ThinkPHP 8 在 FPM 环境下不支持连接池,'pool' => true 或 pool_size 配置完全无效;Db::connect() 每次新建 PDO 连接,异常或阻塞易致 Sleep 连接堆积,应删除 pool 配置、显式关闭持久化、优化查询并调低 MySQL wait_timeout。

ThinkPHP 8 在非协程环境下(如标准 PHP-FPM)根本**不支持连接池**,所谓 pool_size 或 'pool' => true 的配置完全被忽略。你设得再大,也不会起作用;但更危险的是——它会误导你,让你误以为“连接复用”已开启,从而掩盖真实问题:连接没释放、重复创建、持久化滥用。
TP8 的 pool_size 是个“假开关”
在 FPM 模式下:
-
Db::connect()每次都 new 一个全新 PDO 实例,请求结束才靠 PHP 自动析构关闭——中间若抛异常、阻塞(如file_get_contents)、或脚本提前退出(fatal error),连接就卡在 MySQL 的 Sleep 状态不释放 -
'pool' => ['enable' => true]或pool_size配置项在 TP8 + FPM 中无任何实现逻辑,源码里压根不读取、不处理,纯属无效字段 - 你以为设了
pool_size => 100是限制连接数,实际是放任每次请求新建连接,100 个并发进来可能瞬间建出 500+ 连接(尤其循环查库时)
为什么看起来像“pool_size 太大”导致报错
本质不是 pool_size 起了作用,而是它强化了错误认知,引发连锁反应:
- 开发者误信“有池子兜底”,不再检查连接是否 close,也不合并查询,导致单请求建多个连接
- 配合 PDO 默认未禁用持久化(
PDO::ATTR_PERSISTENT => false未显式设置),在 Apache/mod_php 或旧版 FPM 下,连接会被进程长期持有,MySQL 看到大量同 IP:port 的 Sleep 连接 - 这些堆积的 Sleep 连接持续占用
max_connections槽位,最终触发 Too many connections
真正该检查和调整的点
别调 pool_size,它在 FPM 下等于没写。重点做这几件事:
立即学习“PHP免费学习笔记(深入)”;
- 删掉 database.php 中所有
'pool'相关配置,清空干扰项 - 显式关闭持久化:
'params' => [PDO::ATTR_PERSISTENT => false](PDO 驱动下必须这么写才生效) - 用
SHOW PROCESSLIST查Command = 'Sleep'且Time > 60的连接,按HOST和USER分组确认泄漏源头 - 检查代码中是否在循环里反复调
Db::table()->find(),改用whereIn批量查 - 确认 MySQL 的
wait_timeout已调低(建议 300~600 秒),避免 Sleep 连接挂太久
只有跑在 Swoole 协程服务器(php think swoole)且 TP ≥ 8.0.12 时,pool 配置才真正生效——此时连接由协程 MySQL 客户端管理,可复用。FPM 下谈 pool_size,就像给自行车装涡轮增压,徒增误解。



















