ThinkPHP 连接 TiDB Cloud Serverless 必须显式配置 TLS(sslmode=VERIFY_IDENTITY)、带前缀的用户名(如abc123def456.root)及足够超时(time_out=15),否则会连接超时或权限拒绝。

ThinkPHP 连接 TiDB Cloud Serverless 不能直接套用 MySQL 配置,因为默认不启用 TLS、用户名带前缀、且密码必须显式传入——不填或填错会卡在连接超时或 Access denied,不是配置写得“差不多就行”的问题。
ThinkPHP 6/7 的 database.php 中必须显式启用 SSL
TiDB Cloud Serverless 强制要求 TLS 连接,但 ThinkPHP 默认的 mysql 或 pdo_mysql 驱动不会自动加 sslmode=VERIFY_IDENTITY。不配就会报错:SSL connection is required 或直接断连。
- 在
database.php的'hostname'后追加'dsn'字段,绕过驱动默认行为 -
dsn必须包含?sslmode=VERIFY_IDENTITY&sslca=/etc/ssl/cert.pem(Linux/macOS)或对应系统证书路径 - Windows 用户需下载并指定
sslca路径,例如c:/xampp/php/extras/ssl/cacert.pem - 不要用
ssl=true这类模糊参数,TiDB Cloud 只认VERIFY_IDENTITY
示例片段:
'dsn' => 'mysql:host={host};port=4000;dbname=test;charset=utf8mb4;sslmode=VERIFY_IDENTITY;sslca=/etc/ssl/cert.pem',
'username' => '<prefix>.root',
'password' => '<your-password>',
用户名必须带前缀且不能被自动截断
TiDB Cloud Serverless 的用户名格式是 <cluster-prefix>.root,比如 abc123def456.root。ThinkPHP 如果开启 'parse_params' => true(某些模板项目默认开),会把点号 . 当作分隔符做解析,导致用户名变成 abc123def456,登录失败。
- 关闭
parse_params,确认配置中无该选项,或显式设为false - 检查
username值是否被日志或调试器自动脱敏(如显示为***.root),实际值必须完整、无空格、无换行 - 若用环境变量注入,确保
$_ENV['DB_USERNAME']读取后未被 trim 或正则替换
连接超时和重试要调得比本地 MySQL 更保守
TiDB Cloud Serverless 是按需启动计算资源的,首次连接可能有 1–3 秒冷启动延迟。ThinkPHP 默认 'break_reconnect' => false 但 'time_out' => 3 太激进,容易触发 SQLSTATE[HY000] [2002] Connection timed out。
- 把
'time_out'改成15 - 加上
'params' => [\PDO::ATTR_TIMEOUT => 15](PDO 层级) - 禁用自动重连:
'break_reconnect' => true,避免在冷启动期间反复无效重试 - 不要依赖
'deploy' => 1(分布式部署配置),Serverless 集群不支持主从切换逻辑
测试连接时别只跑 Db::query('SELECT 1')
这个语句太轻,可能成功但掩盖真实问题。真正暴露 TLS 或权限问题的是带字符集、事务或预处理的查询。
- 用
Db::execute("SET NAMES utf8mb4")测试字符集协商 - 执行
Db::transaction(function () { Db::insert(...); return true; })验证事务支持 - 查看日志里是否有
SSL connection established类提示(需开启 PDO 的PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
Serverless 的“无感”只存在于连接建立之后;前期配置漏掉 TLS、前缀、超时三项中的任意一项,都会让整个应用卡在初始化阶段,且错误信息极其模糊。



















