thinkphp 6 读写分离必须同时满足四个条件:deploy => 1、rw_separate => true、read为二维数组、write为单维数组,缺一不可;否则全部回退主库。

ThinkPHP 6 的读写分离不是“配完就自动分流”,它必须同时满足 deploy => 1、rw_separate => true、read 是二维数组、write 是单维数组这四个硬性条件,缺一就会全部回退到主库。
database.php 中 connections.mysql 必须显式启用 deploy 和 rw_separate
TP6 不会从全局或默认连接自动推导读写分离逻辑,所有开关都得写在具体连接配置里。很多人把 deploy 和 rw_separate 放在顶层或写错位置,结果配置白写了。
-
deploy => 1是总闸门,没它整个读写分离模块压根不初始化 -
rw_separate => true只有在deploy === 1时才生效,单独设它没用 - 这两项必须嵌套在
connections.mysql(或你实际用的连接名)内部,不能放在default或顶层 - 如果
default指向的是'mysql',但connections.mysql里没写deploy,那就等于没开
read 必须是二维数组,write 只能是单维数组
TP6 对配置结构极其敏感:一维 read(比如 'read' => ['192.168.1.11'])会被静默忽略;把 write 写成数组套数组(比如 'write' => [[...]])则直接报错 Invalid write database config。
- 正确写法:
'read' => [['hostname' => '192.168.1.11'], ['hostname' => '192.168.1.12']](哪怕只有一个从库也要套一层) -
write只允许一个主库,写成:'write' => ['hostname' => '192.168.1.10', 'username' => 'app_rw'] - 所有从库配置项(
hostname、database、username等)必须完整,不能只填 IP - 从库的
type必须显式写为'mysql',漏掉可能被当成 PostgreSQL 驱动
哪些查询走从库?哪些强制走主库?
TP6 不解析 SQL,而是靠方法名和上下文做路由判断。它不会因为你写了 SELECT 就放行——一旦带锁、进事务、或上一条是写操作,立刻切回主库。
- 走从库(默认):
find()、select()、count()、value()、Db::query('SELECT ...') - 强制走主库:
save()、insert()、update()、delete()、execute()、任何带->lock(true)或FOR UPDATE的查询 - 事务中所有操作(包括纯
SELECT)全部走主库,这是硬规则,无法绕过 -
Db::connect('xxx')会跳过读写分离逻辑,直连指定配置 —— 它和rw_separate无关
主从延迟问题必须由业务层兜底
TP6 不提供“强一致性读”开关,也不检测从库延迟。刚 insert() 完立刻 find(),大概率读不到最新数据。
- 需要强一致的场景(如支付结果页、用户注册后跳转),必须手动加
->master(true)强制走主库 -
Db::name('user')->master(true)->find(1)这样写才能确保读到刚写入的数据 - 不要依赖框架自动识别“这个读应该等主从同步”,它根本不管同步状态
- 监控从库延迟、设置告警、甚至在关键路径上主动 sleep(100ms) 等同步,都是常见兜底手段
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











