thinkphp本身不内置连接池,tp6.0及更早版本完全不支持,tp6.1+仅在swoole协程环境下实验性支持;fpm模式下应删除所有pool和persistent配置,启用deploy=1实现单请求内pdo复用,并配置break_reconnect与正确params以应对断连。

ThinkPHP本身不内置连接池,所谓“连接池配置错误”多数是误配了本不存在的功能,或在不支持的运行环境(如FPM)下强行启用 pool 参数,导致连接堆积、复用失效甚至报错。修复关键不是调参数,而是认清运行模式、关闭无效配置、补全真正起作用的连接控制项。
先确认是否真在用连接池
TP6.0 及更早版本完全不支持连接池,任何 pool 相关配置(如 'pool' => true 或 'pool_size')都会被忽略;TP6.1+ 且搭配 think-orm ≥3.0 才开始实验性支持,但仍仅限于 Swoole 协程环境(php think swoole 启动)。FPM 模式下 Db::connect() 每次都是全新 PDO 实例,所谓“池”根本不存在。
- 执行 php think run 查看启动方式:显示 FPM 则 pool 配置一律删除
- 执行 php think swoole 且 TP 版本 ≥8.0.12(或 TP6.1+ + think-ormv3.0+)才可启用 pool
- 运行中执行 SHOW PROCESSLIST,若大量 Command = Sleep 且持续不释放,说明连接没走池,只是卡住了
关闭所有无效的 pool 和 persistent 配置
FPM 下开启 'persistent' => true 或 'pool' => [...] 不但无效,反而会干扰连接生命周期管理,加剧 Sleep 连接堆积。PDO 的持久化需通过 params 显式传参,且 PHP 8+ 中风险更高。
- 删掉 config/database.php 中所有 'pool' 键及其子项(如 pool_size、get_timeout)
- 将 'persistent' => true 改为 false,或直接移除;如需底层复用,改用 'params' => [PDO::ATTR_PERSISTENT => false]
- 确保 'type' => 'pdo_mysql',mysqli 驱动下 break_reconnect、deploy 等均不生效
启用 deploy=1 实现连接复用(非池,但最实用)
TP 的 deploy 模式不是连接池,而是单请求内多次 Db::table() 复用同一个 PDO 实例的轻量机制。它不跨请求,但能避免一次请求里反复 new PDO。
- 在 MySQL 配置块中明确写:'deploy' => 1(必须是整数 1,不能是 true 或 '1')
- 配合 'hostname' 填对数据库服务名(Docker 下填 mysql,非 localhost)
- 补全 'params':[PDO::ATTR_TIMEOUT => 5, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4", PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
补全断连兜底:break_reconnect + 异常捕获
MySQL 主动断开空闲连接(wait_timeout)后,TP 默认抛异常终止请求。启用 break_reconnect 可让下一条查询自动重连,但必须满足前提条件。
- 显式开启:'break_reconnect' => true
- 确保 PDO 错误模式为异常:params 中必须含 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
- 事务中不生效——Db::startTrans() 后断连仍会直接报错,这是设计使然,避免数据错乱
- CLI 脚本建议手动保活:在 execute() 开头加 Db::close(); Db::connect(); 或封装 safeQuery 函数捕获 2006 错误并重试
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











