persistent => true在tp6/8中无效,因框架析构时强制销毁pdo、mysql驱动不识别该参数,且tp未维护mysqli驱动;真正有效的连接复用机制是deploy => 1,需配合pool_size、break_reconnect等配置,并严格保证host/database/username/password三元组一致。

在 ThinkPHP 6/8 中,persistent 参数对数据库性能基本没有正向影响,反而容易引发连接泄漏、状态污染和超时错误;它不是“长连接开关”,而是一个被框架连接管理逻辑绕过的无效配置。
为什么 persistent => true 在 TP6/8 里几乎没用
TP6 的 Connection 类在析构时强制执行 $this->pdo = null,PDO 对象一销毁,底层 socket 就断开,PDO::ATTR_PERSISTENT 根本没机会生效。更关键的是:mysql(非 mysqlnd)的 PDO DSN 压根不识别 persistent 参数;即使你用的是 mysqlnd,TP 官方也未维护 mysqli 驱动,写在 database.php 里的 'persistent' => true 会被直接忽略。
常见错误现象包括:
-
show processlist看不到复用连接,连接数随请求线性增长 - QPS 上去后仍报
Too many connections - CLI 脚本或队列任务运行超时后,复用连接直接失败,报
MySQL server has gone away - Apache prefork 模式下完全失效(进程不复用);FPM 下仅对同一 worker 内有效,但 TP 不保证复用路径
deploy => 1 才是 TP6/8 真正有效的连接复用机制
TP6 提供的务实方案不是“长连接”,而是基于配置驱动的连接复用池,核心开关是 deploy => 1。它不依赖 PDO 持久化,而是由框架自己缓存已建立的 PDO 实例,并按 host + database + username/password 三元组做键值隔离。
必须配合以下配置才实际生效:
-
'deploy' => 1:必须写在config/database.php的具体数据库配置块内,不是全局配置 -
'pool_size' => 20:限制最大空闲连接数,防 MySQLmax_connections耗尽 -
'break_reconnect' => true:连接异常时自动重建,避免阻塞等待 -
'pool_time' => 3600:空闲连接存活时间(秒),否则连接堆积不释放
注意:该池只对「同 hostname、同 database、同 username/password」的请求复用;换库名、改账号、甚至 host 写成 localhost vs 127.0.0.1,都会新建池,无法共享。
Connection timed out 错误的真实来源不是网络,而是连接池卡住了
报 SQLSTATE[HY000] [2002] Connection timed out,90% 不是 PHP 连不上 MySQL,而是 TP 的连接池在等一个可用连接超时了。根源可能包括:
-
'host'写成域名而非 IP,DNS 解析慢拖垮首次连接 - MySQL 的
wait_timeout设为 60 秒,而队列任务运行超时,连接被服务端主动 kill,下次复用就断 - 事务闭包中发生未捕获异常或提前
return,导致连接未归还池,池逐渐枯竭 - 连接池默认不自动清理空闲连接,长期运行后堆积大量 idle 连接,占满 MySQL 上限
验证方法:直接连 MySQL 执行 SHOW PROCESSLIST,看连接数是否随请求增长却不回收。
FPM 下真正的连接复用,只发生在单请求内
TP6/8 官方没有跨请求的连接池实现。所谓“复用”,本质是减少新建连接次数,不是维持长连接。FPM 每次请求都是全新生命周期,连接对象默认只在单请求内复用——这是框架默认行为,无需额外配置。
但开发者常误写:
- 在循环里反复调用
Db::connect('log_db')->table('log')->insert($item)—— 每次都重建连接对象(虽底层 PDO 可能复用,但框架层开销白费) - 自定义模型中重写
initialize()并调用Db::connect()却没保存实例 - 开启调试模式(
debug => true),TP6 会在每次查询后调用SHOW FULL PROCESSLIST,额外占用连接
正确做法是提前获取一次连接对象:$logDb = Db::connect('log_db');,后续所有操作都基于它。
复杂点在于:连接复用逻辑高度依赖配置一致性、运行环境(FPM/Swoole)、以及业务代码是否规范释放资源。最容易被忽略的是事务闭包里的连接泄漏和 pool_time 缺失导致的连接堆积——这两者往往在压测后期才集中爆发。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











