codeigniter不内置主从自动路由,需手动配置主库(master)和从库(slave)连接,并在model中显式调用:写操作用$this->master,读操作用$this->slave;支持多从库轮询负载均衡,但需注意复制延迟、结构一致性和事务隔离。

CodeIgniter 本身不内置主从自动路由功能,但可以通过手动配置多个数据库连接 + 在 Model 中按需调用,实现读写分离。关键不是“自动识别SQL类型”,而是由开发者明确指定读操作走从库、写操作走主库。
在 database.php 中定义主库和从库
打开 application/config/database.php,在 $db 数组中声明至少两个连接组:
-
主库(写库):用于 INSERT / UPDATE / DELETE,通常只配一台,比如命名为
'master' -
从库(读库):用于 SELECT,可配一台或多台,比如命名为
'slave'或'read'
示例配置:
$db['master'] = array( 'hostname' => '192.168.1.100', 'username' => 'db_user', 'password' => 'db_pass', 'database' => 'myapp', 'dbdriver' => 'mysqli', 'db_debug' => TRUE, 'cache_on' => FALSE, 'pconnect' => FALSE, 'char_set' => 'utf8', 'dbcollat' => 'utf8_general_ci', 'swap_pre' => '', 'encrypt' => FALSE, 'compress' => FALSE, 'stricton' => FALSE, 'failover' => array(), 'save_queries' => TRUE ); $db['slave'] = array( 'hostname' => '192.168.1.101', 'username' => 'db_reader', 'password' => 'read_pass', 'database' => 'myapp', 'dbdriver' => 'mysqli', 'db_debug' => TRUE, // 其他参数同上,注意从库一般设为只读权限 );
在 Model 中分别加载主从连接
不要依赖默认连接,每个 Model 应主动加载所需的数据库实例:
- 用
$this->master处理写操作 - 用
$this->slave处理读操作
示例 Model(application/models/User_model.php):
class User_model extends CI_Model {
public function __construct() {
parent::__construct();
$this->master = $this->load->database('master', TRUE);
$this->slave = $this->load->database('slave', TRUE);
}
public function create($data) {
return $this->master->insert('users', $data);
}
public function get_by_id($id) {
return $this->slave->where('id', $id)->get('users')->row();
}
public function get_list($limit = 10, $offset = 0) {
return $this->slave->get('users', $limit, $offset)->result();
}
}
进阶:支持多从库负载均衡(手动轮询)
若配置了多个从库(如 slave1、slave2),可在 Model 构造函数中随机选择一个加载:
- 定义数组包含所有从库键名,如
['slave1', 'slave2', 'slave3'] - 用
array_rand()随机取一个键,再调用$this->load->database() - 避免每次都连同一台,减轻单节点压力
注意:这种轮询是简易方案,不带故障检测;如需自动剔除失效从库,需自行封装连接健康检查逻辑。
注意事项与常见陷阱
配置完成后务必验证以下几点:
- 确保从库已开启 MySQL 复制,并且
SHOW SLAVE STATUS\G中Seconds_Behind_Master值稳定(非持续增长) - 主库和从库的表结构、字符集、时区必须严格一致,否则可能因隐式转换或 NOW() 行为导致数据不一致
- 写操作后立刻执行读操作(如插入后马上查自己刚插的记录),可能因复制延迟读不到最新数据,此时应强制走主库查询
- 事务内所有操作必须使用同一连接(即全走 master),不能混用 slave 连接











