连接不是越多越好
MySQL 每个连接对应一个线程,PostgreSQL 每个连接对应一个进程,连接数往上走,内存与上下文切换开销都跟着涨。连接池的作用是把连接复用起来并限制并发上限,池大小要跟应用并发量和数据库承载能力匹配,不是越大越好。
基本信息
| MySQL 连接模型 | 每连接一个线程,连接多则线程与内存开销大 |
|---|---|
| PostgreSQL 连接模型 | 每连接一个进程,常配合外部连接池 |
| MySQL 常用指标 | Threads_connected、Threads_running、max_connections |
| 关键状态 | idle in transaction:空闲事务持锁并阻碍清理 |
| 池大小估算 | 参考并发量与单查询响应时间,而非拍脑袋取上限 |
典型使用场景
- 排查连接数打满导致的报错
- 数据库内存被大量空闲连接吃掉
- 调整池大小前先量化真实并发
- 发现长事务阻碍系统清理
- 容器化部署后连接数暴涨
MySQL 观察
MySQL 观察
-- 当前连接数与正在执行的连接数
SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Threads_running';
-- 上限与空闲回收时间
SHOW VARIABLES LIKE 'max_connections';
SHOW VARIABLES LIKE 'wait_timeout';PostgreSQL 观察
PostgreSQL 观察
-- 按状态统计连接
SELECT state, count(*)
FROM pg_stat_activity
GROUP BY state;
-- 重点关注长时间空闲的事务
SELECT pid, state, xact_start, query
FROM pg_stat_activity
WHERE state = 'idle in transaction'
ORDER BY xact_start;指标怎么读
| 指标 | 含义 | 怎么用 |
|---|---|---|
| Threads_connected | 当前连接数 | 接近上限就要扩容或排查泄漏 |
| Threads_running | 正在执行的连接数 | 远低于连接总数说明多数连接在空闲 |
| max_connections | 连接数上限 | 调高上限也要同步评估内存 |
| idle in transaction | 开了事务却不干活的连接 | 持锁并阻碍清理,需要回收 |
| wait_timeout | 空闲连接回收时间 | 与连接池的空闲回收配合设置 |
连接池不是缓冲池:池里的连接在数据库侧始终占用资源,池开得太大只是把压力从应用挪到数据库,问题会在高峰期集中爆发。
idle in transaction 最值得警惕:它持有锁、阻碍清理,通常还意味着应用忘了提交事务。连接池要配空闲回收与事务超时做兜底。