deploy=1是启用主从识别的总开关,rw_separate=true才开启读写分离,二者需同时配置且必须正确定义master和slave连接,否则仍全走主库。

ThinkPHP6 的数据库部署模式(deploy)和读写分离(rw_separate)不是开关式功能,必须配合主从结构、正确配置连接参数才能生效;单纯设为 1 或 true 不会自动拆分 SQL。
什么是 deploy 和 rw_separate?
这两个配置项共同控制 ThinkPHP6 是否启用「集中式」或「分布式」数据库部署逻辑:
-
deploy => 0:集中式,所有操作走同一个连接(默认值) -
deploy => 1:分布式,启用主从识别逻辑,但是否真正分离读写,取决于rw_separate和连接定义方式 -
rw_separate => false:即使deploy => 1,也全部走主库(即master连接) -
rw_separate => true:SELECT 类查询走从库,其余走主库 —— 但前提是必须明确定义master和slave连接
主从连接必须按约定命名,不能自定义键名
ThinkPHP6 的读写分离逻辑硬编码识别 master 和 slave 键,而不是靠你随便起名的连接名。下面这种写法是无效的:
return [
'connections' => [
'my_master' => [/* ... */],
'my_slave' => [/* ... */],
],
];正确写法是:
立即学习“PHP免费学习笔记(深入)”;
return [
'connections' => [
'master' => [
'type' => 'mysql',
'hostname' => '192.168.1.10',
'database' => 'app_db',
'username' => 'root',
'password' => 'xxx',
],
'slave' => [
'type' => 'mysql',
'hostname' => '192.168.1.11',
'database' => 'app_db',
'username' => 'ro_user',
'password' => 'ro_pass',
],
],
'deploy' => 1,
'rw_separate' => true,
];注意:slave 支持数组形式定义多个从库,例如 'slave' => [['hostname'=>'s1'], ['hostname'=>'s2']],框架会随机选一个。
master_num 和 slave_no 怎么影响实际路由?
这两个参数只在 rw_separate => true 且存在多个 slave 时起作用:
-
master_num => 1:表示只有一个主库(目前仅支持 1,设为 2 无意义) -
slave_no => ''(空字符串):默认随机选择从库 -
slave_no => 0:强制固定使用第一个从库(索引 0) -
slave_no => 1:强制固定使用第二个从库(索引 1),超出范围则 fallback 到随机
不建议硬编码 slave_no,除非你有明确的灰度或调试需求;生产环境应保持为空,让框架自动负载。
常见失效原因和验证方式
配置完后仍走主库?大概率是以下某个环节出错:
- 没把
deploy设为1(很多人只改了rw_separate) -
connections里没有名为master和slave的键(比如写成了write/read) -
slave连接配置本身无法连通(框架不会报错,而是静默 fallback 到master) - 用了模型的
db('slave')手动指定连接,覆盖了自动分离逻辑
验证是否生效最直接的方式:开启 SQL 日志(trigger_sql => true),执行一条 Db::table('user')->select(),看日志里打印的 hostname 是主库还是从库 IP。
部署模式不是“配了就自动高可用”,它只是个路由开关;真实主从一致性、延迟、故障转移,得靠数据库层自己保障。TP6 不做哨兵、不自动切主、不检测从库健康 —— 它只认配置,不认状态。



















