ThinkPHP 6 读写分离需在 database.php 的 connections 下同时定义主从库,通过 read_master 和 read_config 显式配置;读操作必须调用 ->useReadConnection() 才走从库,否则默认连主库;多个从库按 read_config 数组顺序轮询,不支持权重与自动故障恢复。

ThinkPHP 6 的 database.php 怎么配读写分离
ThinkPHP 6 原生支持读写分离,但不是靠“自动识别 SELECT/INSERT”来实现的,而是靠显式指定连接池和读库路由规则。配置错一个键名,read 就不会生效。
关键点:必须把主库(write)和从库(read)都定义在 connections 下,并通过 read_master 和 read_config 控制行为:
-
read_master设为true表示「读操作也允许走主库」,默认是false;设成true容易误以为读写分离生效了,其实没切过去 -
read_config必须是数组,哪怕只配一个从库也要写成['host' => '192.168.1.10'],不能直接写对象或字符串 - 如果用了 Redis 缓存,记得关掉
schema_cache_type或清空runtime/cache,否则旧连接配置不生效
为什么 Db::table('user')->select() 还是连主库
TP6 的查询构造器默认不主动触发读库切换,除非你明确告诉它“这是读操作”。最常见漏掉的是没调用 ->useReadConnection(),或者用了 ->master() 强制走主库却忘了删。
典型错误场景:
立即学习“PHP免费学习笔记(深入)”;
- 在事务里执行
select()—— TP6 会自动降级到主库,这是安全策略,不是 bug - 用了
Db::connect('mysql_read')手动连从库,但后续模型操作仍走默认连接,因为模型不继承手动连接上下文 - 数据库中间件里做了
Db::setConnectConfig(),但没配合Db::close(),连接复用导致配置残留
正确做法:对纯查询加 ->useReadConnection(),例如 Db::table('user')->useReadConnection()->select()。
多个从库怎么负载均衡?read_config 支持哪些参数
TP6 的读库列表是轮询(round-robin)策略,不支持权重、延迟探测或自动下线。你写的顺序就是轮询顺序,第一个挂了会跳到下一个,但不会自动恢复——除非重启服务或手动触发连接重建。
read_config 可以包含的字段和主库一致,但注意这些差异:
-
host、port、username、password、database必填,少一个就报InvalidArgumentException: Database config read_config is invalid -
charset和主库不一致时,可能触发字符集转换失败,尤其含 emoji 的字段 - 不要在
read_config里配deploy或prefix,它们只作用于主连接
示例片段:
'read_config' => [
['host' => '192.168.1.11', 'port' => 3306, 'username' => 'r1', 'password' => 'xxx', 'database' => 'myapp'],
['host' => '192.168.1.12', 'port' => 3307, 'username' => 'r2', 'password' => 'xxx', 'database' => 'myapp'],
],
模型类里怎么确保走读库?BaseModel 重写有坑吗
模型默认走全局连接,不感知读写分离配置。想让某个模型固定走读库,不能只改 protected $connection 指向一个从库名,因为那样会丢失轮询能力,变成单点依赖。
更稳妥的做法是在模型基类里统一拦截查询方法:
- 重写
scopeSelect或scopeGet,内部加useReadConnection() - 避免重写
__call去劫持所有方法,TP6 的链式调用里有些方法(如chunk)不走标准查询流程,容易漏 - 如果用了软删除,
withTrashed()会绕过读库路由,因为它底层调用的是whereRaw+ 主连接
真正需要读写分离的业务,建议把查操作收口到 Service 层,而不是靠模型自动判断——模型太“聪明”反而难调试。
读写分离不是开个开关就完事的事,连接池、事务边界、缓存一致性、从库延迟,每个点都能让你在凌晨三点盯着监控看慢查询。配完别急着上线,先用 Db::getLastSql() 确认实际连的是哪个 host。


















