thinkphp 6.1 仅在搭配 think-orm v3.0+ 时真正支持连接池,低版本配置无效;必须显式设置 max_active、get_timeout、max_wait 三项核心参数,min_idle 和 idle_timeout 等在 tp6.1 中实际未生效。

ThinkPHP 6.1 真正支持数据库连接池,但仅限配合 think-orm v3.0+ 使用;低版本(如 TP6.0 或 TP5.x)写的 pool 配置完全被忽略,不会生效。
确认你用的是 TP6.1 + think-orm v3.0+
运行 composer show topthink/think-orm,输出版本必须是 3.0.0 或更高。若看到 2.x,说明你还在用旧 ORM,pool 配置压根不解析——删掉配置项比留着误导强。
常见错误现象:show processlist 里大量 Sleep 连接、并发稍高就报 Too many connections、监控显示连接数随请求线性增长,基本可断定连接池没启用。
- TP6.1 默认安装的 ORM 是 v3.0+,但升级项目可能残留 v2.x
-
config/database.php中写'pool' => [...]前,先确认Db::class实际指向think\orm\Db而非think\db\Db - 执行
Db::connect()->getPdo()后打印对象哈希,对比多次调用是否返回同一实例——复用才说明池生效
正确配置 pool 参数并理解各字段作用
pool 不是“开了就变快”的开关,它是一组有明确语义的控制参数,设错反而加剧问题。关键三项必须显式配置:
-
'max_active' => 20:池中最多允许 20 个「正在执行 SQL」的连接。超了会排队或抛异常,这是防打爆 MySQL 的硬闸门 -
'get_timeout' => 1000:从池中获取连接的等待上限,单位毫秒。设为1000表示等 1 秒没拿到就抛think\db\exception\PDOException -
'max_wait' => 3000:当池满时,新请求在队列里最多等待 3 秒——注意,这不是连接建立超时,是排队超时
'min_idle' 和 'time_between_eviction_runs_millis' 在 TP6.1 中实际未生效,别依赖它们自动清理空闲连接;'idle_timeout' 同样无效。空闲连接靠 MySQL 自身的 wait_timeout 回收。
为什么设置了 get_timeout 却不抛异常?
最常见原因是:你根本没触发「池满等待」场景,或者异常被框架静默吞掉了。
-
Db::table()->select()等方法默认会重试一次失败连接,首次get_timeout失败后直接换新连接重试,掩盖了原始异常 - 没配
'break_reconnect' => true,连接异常后不归还池子,导致后续请求更难获取连接,但错误日志里只看到慢查询或超时,看不到PDOException - 事务开启后未提交/回滚,连接一直被占用,
get_timeout永远等不到可用连接,但报错可能是SQLSTATE[HY000]: General error而非明确的获取超时
验证方式:临时把 max_active 设为 1,开两个并发请求,第二个必然卡住并最终触发 get_timeout 异常——这是最干净的测试路径。
连接池生效但连接数还是飙升?检查 deploy 和连接复用边界
deploy => 1 是连接复用的前提,但很多人忽略了它的作用范围:
- 只有「同名连接配置 + 同数据库名 + 同账号密码」的请求才会复用同一池子。换一个库名(比如从
db_a切到db_b),哪怕其他参数全一样,也会新建池子 - 模型类里写
protected $connection = 'mysql_slave',和Db::connect('mysql_slave')是两个独立连接池,不共享 - CLI 命令或 Swoole Worker 常驻进程下,连接不会随请求结束自动销毁,必须确保每次用完不泄漏——事务务必
try/catch + rollback,避免START TRANSACTION卡住连接
真正决定连接数上限的,从来不是 PHP 层的配置,而是 max_active × 并发 Worker 数 × 连接配置变体数。线上压测前,先用 SHOW PROCESSLIST 对照 DbPool::stats()(如有自定义统计)看实际复用率。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











