thinkphp 6 读写分离必须同时启用 deploy => 1 和 rw_separate => true,且 deploy 必须配置在具体连接块内;read 必须为二维数组、write 为单维关联数组,缺一不可,否则静默失效。

ThinkPHP 6 的 deploy 和 rw_separate 必须同时启用
不设 deploy => 1,哪怕你写了 read 和 write,框架也完全无视——所有查询都 fallback 到主库连接。这不是配置没生效,是整个读写分离机制压根没启动。
rw_separate => true 只在 deploy === 1 时才起作用;设成 false 或干脆不写,等价于关闭自动路由,后续必须手动调用 ->master() 或 ->slave()。
-
deploy => 1必须写在具体连接配置块内(比如connections['mysql']),不能只放在顶层或default键下 - 两个开关缺一不可,漏掉任一,
read/write数组都会被静默忽略 - 常见错误现象:
Db::table('user')->select()仍走主库、从库轮询完全不触发
TP6 的 read 和 write 必须严格按结构写
TP6 已废弃 TP5 的逗号分隔字符串方式,也不接受旧版的 read/write 键以外的字段(如 master_num、slave_no)。配置结构错一点,就会报错或静默失效。
-
read必须是二维数组:哪怕只有一个从库,也得写成[['hostname' => '192.168.1.11']];写成一维['192.168.1.11']会静默失败 -
write必须是单维关联数组:['hostname' => '192.168.1.10', 'username' => 'root'];写成数组套数组会直接报Invalid write database config - 每个
read子数组必须包含完整连接参数:hostname、database、username、password缺一不可,少一个就抛Database config read_config is invalid
哪些操作会强制走主库?不是所有“SELECT”都进从库
TP6 不解析 SQL 语义,而是靠方法调用和上下文做路由决策。所谓“读操作走从库”只是默认策略,很多看似只读的场景其实被框架识别为强一致性需求,必须走主库。
- 事务内所有查询(包括
count()、value()、find())全部走主库,不管是否加锁 - 显式加锁:调用
->lock(true)或原生 SQL 含FOR UPDATE、LOCK IN SHARE MODE,强制主库 - 手动指定:
->master(true)或Db::connect('mysql')(若该连接未启用rw_separate) - 写操作后紧接的读:比如
save()后立刻find(),TP6 不清写标记,仍走主库(这点和 TP5 类似)
Db::connect() 和 Db::name() 的行为差异
Db::connect('mysql') 是显式切换连接配置名,它独立于读写分离机制;而 Db::name('user') 永远基于当前默认连接(即 default 指向的配置),是否走从库,完全取决于那个配置里 rw_separate 是否开启。
- 如果你定义了名为
mysql_slave的只读连接,想临时查从库又不想改全局配置,就该用Db::connect('mysql_slave') -
Db::name('user')->select()不能绕过主从规则——它受connections['mysql']里的rw_separate控制 - 不要在代码里传数组给
Db::connect(),比如Db::connect(['hostname' => '...']),这会新建连接、不复用,高并发下容易触发Too many connections
->master(true),或者用缓存层对冲。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











