ThinkPHP 连 TDSQL-C 必须关闭 break_reconnect、启用 deploy => 1 和 rw_separate => true,所有 hostmaster/hostslave 均填代理地址而非真实节点,并设 persistent => true、params => [PDO::ATTR_TIMEOUT => 5],ID 获取与事务操作须强制走主库。

ThinkPHP 能直接连 TDSQL-C,但默认配置会踩存储计算分离的坑——连接池、读写分离、故障切换这三处不调,性能和可用性会断崖式下跌。
为什么 mysql 驱动连不上 TDSQL-C 代理地址?
不是驱动不兼容,而是 TDSQL-C 的数据库代理(DBProxy)默认只接受长连接 + 连接复用,而 ThinkPHP 5.1+ 默认开启 break_reconnect 且未显式设置 deploy 和 rw_separate,导致每次查询都新建连接,触发代理限流或连接拒绝。
- 必须关闭自动重连:
'break_reconnect' => false - 必须启用部署模式:
'deploy' => 1,否则rw_separate不生效 - 代理地址不能填在
hostname,要填在hostmaster(主库)和hostslave(从库)中,否则读写分离逻辑跳过代理 - 务必设置
'charset' => 'utf8mb4',TDSQL-C MySQL 8.0 版本对字符集校验更严格
read_master 和 rw_separate 怎么配才不绕过代理?
TDSQL-C 的自动读写分离依赖数据库代理统一入口转发,如果 ThinkPHP 把读请求直连从库 IP,就等于绕过代理,失去负载均衡、故障自动摘除、延迟感知等能力。
-
'rw_separate' => true必须开启,否则所有请求走主库 -
'read_master' => false(默认值),设为true会强制读也走主库,废掉只读节点 -
'slave_no' => ''留空,让框架随机选从库;若指定数字,需确保hostslave是数组且下标匹配 - 关键:所有
hostslave值必须和hostmaster一样,都填数据库代理提供的读写分离地址(如xxxx-proxy.tencentcloud.com),不是后端真实节点 IP
连接池和超时参数不调,秒级扩缩容就成“秒级中断”
TDSQL-C 支持秒级升降配,但前提是客户端能容忍短时闪断并自动重连。ThinkPHP 默认的 timeout(3600 秒)和无连接池机制,会让闪断变成连接卡死或报 MySQL server has gone away。
把一个已有 git 仓库装配成"TAPD 故事 → feature 分支 → PR → CNB AI 代码评审 → 合入 main → TAPD 故事自动回写 commit"的闭环工程挽具(harness)。适用于腾讯云 CNB(cnb.cool)+ TAPD 组合的团队。触发场景:(1) 用户要求把 git 仓库接入 CNB 和/或 TAPD;(2) 要求 commit/PR 自动关联 TAPD 故事;(3) 要求启用 CNB AI 代码评审(cnbcool/ai-review);(
立即学习“PHP免费学习笔记(深入)”;
- 显式设置
'params' => [\PDO::ATTR_TIMEOUT => 5],避免长事务阻塞连接回收 - 启用持久连接:
'persistent' => true,配合数据库代理的连接复用能力 - 设置
'wait_timeout' => 28800(8 小时)不如设'connect_timeout' => 3更实用——闪断恢复快,靠重试比靠保活更可靠 - 业务层必须实现重连兜底:在
Db::execute()外包一层 try/catch,捕获PDOException后 sleep 100ms 再重试 1 次
日志即数据架构下,lastInsertId 和事务一致性怎么保障?
TDSQL-C 的物理日志同步(Redo Log)让主从延迟压到毫秒级,但 ThinkPHP 的 lastInsertId() 默认走 SELECT LAST_INSERT_ID(),若该语句被路由到从库,可能取到旧值。
- 所有涉及自增 ID 的操作,必须显式使用
Db::master()->insertGetId()强制走主库 - 事务内禁止跨库查询:不要在事务中调用
Db::name('user')->where(...)->find(),改用Db::master()->name('user')->... - 避免使用
INSERT ... ON DUPLICATE KEY UPDATE后立刻查,这类语句在代理层可能被拆解为多阶段,建议用INSERT IGNORE+ 主库查兜底 - 慢查询日志里若频繁出现
SELECT LAST_INSERT_ID(),说明读写分离规则没生效,要检查hostslave是否误填了真实从库地址
存算分离不是透明的——它把扩展性换给了基础设施,但把连接生命周期、路由语义、事务边界这些责任,明确交还给了应用层。ThinkPHP 配置里漏掉任意一个 hostmaster、rw_separate 或 persistent,TDSQL-C 的秒级弹性就只是控制台上的数字。


















