发布于2026-07-11 阅读(0)
扫一扫,手机访问
先说个很多开发者踩过的坑吧:ThinkPHP 6 的读写分离,真不是配个 read 就自动走从库了。关键在于,必须在 config/database.php 里严格按层级、键名、数组结构写对,缺一不可,否则所有查询会被静默回退到主库,而且不报错——这其实是最棘手的地方。

框架只认 default 指向的那个连接名,比如 'mysql',而该连接的所有实际配置,必须完整写在 connections['mysql'] 里。不能把数据库参数直接塞在 default 下,也不能用临时数组调用 Db::connect([]) 绕过。
default 只能是字符串,比如 'mysql' 或 'main_db'。connections 下的每个键名必须是合法的 PHP 变量名:小写字母开头,只能包含字母、数字、下划线,绝对不能出现 .、- 或大写字母。type、hostname、database、username、password、charset 这六项一个都不能少。漏掉 type 会导致驱动误判,这个坑尤其隐蔽。只有同时满足以下四个条件,Db::name('user')->select() 才可能真正走从库:
'deploy' => 1:这是总开关,没有它整个机制不会初始化。'rw_separate' => true:注意,这个配置仅在 deploy === 1 时才会生效。'write' 必须是一维关联数组,里面完整包含主库的所有参数。例如:['hostname' => '192.168.1.5', 'username' => 'rw_user', 'database' => 'app_db']。'read' 必须是二维数组,哪怕只有一个从库,也要在外面套一层大括号。例如:[ ['hostname' => '192.168.1.10', 'username' => 'ro_user', 'database' => 'app_db'] ]。主库和所有从库的 charset(比如 'utf8mb4')和 database 名必须完全一致,不能有半点差异。如果从库用的是 utf8,主库却是 utf8mb4,那 emoji 字段要么乱码,要么写入直接失败。而 database 名不同的话,跨库 JOIN 或事务操作就会出问题。
'charset' => 'utf8mb4',不要依赖默认值,主动写清楚更稳妥。当需要绕过自动路由,比如报表查专用从库,或者调试时想确认某条 SQL 是否真的走了从库,有两种方法比较可靠:
connections 中单独定义一个只读连接,比如 'report_sla ve',这个连接里不需要写 deploy 或 rw_separate,它完全独立,不参与读写分离逻辑。Db::connect('report_sla ve')->table('log')->select() 直接调用,这个连接与读写分离机制无关,定位问题特别方便。->useReadConnection(),例如:Db::table('user')->useReadConnection()->where('id', 1)->find(),这种方式更灵活,适合临时指定。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8