1. 问题现象与初步判断
上周五凌晨三点,我被一阵急促的告警短信惊醒——生产环境的MySQL连接池突然耗尽,所有新请求都被阻塞。登录服务器后发现,有近百个连接处于Sleep状态超过8小时,CPU和内存却异常平静。这种"安静如鸡"的挂死状态,往往比疯狂报错更让人头皮发麻。
连接挂死通常表现为三种典型症状:
- 应用日志出现"Connection timeout"或"Too many connections"错误
show processlist显示大量Sleep状态的连接- 监控图表中Active Connections曲线形成平台期
遇到这种情况,先别急着重启——那只会掩盖问题。我通常会按"先观测后动手"的原则,用以下命令快速抓取现场快照:
sql复制/* 查看所有连接状态 */
SHOW FULL PROCESSLIST;
/* 查看连接超时设置 */
SHOW VARIABLES LIKE '%timeout%';
/* 查看最大连接数 */
SHOW VARIABLES LIKE 'max_connections';
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 连接生命周期与常见死因
要理解连接挂死,得先看看MySQL连接的正常生命周期:
- 应用从连接池获取连接
- 执行SQL语句
- 返回结果集
- 释放连接回池
这个链条中任意环节卡住都会导致连接泄漏。根据我处理过的案例,90%的挂死集中在四个场景:
2.1 事务未提交
开发同学忘记commit/rollback,连接会一直持有锁。曾有个UPDATE语句漏写commit,导致200个连接被阻塞。
2.2 网络闪断
应用服务器与MySQL之间的网络抖动后,TCP连接未正常关闭。云环境尤其常见。
2.3 客户端崩溃
应用进程异常退出,没来得及释放连接。Docker容器被强杀时经常出现。
2.4 查询阻塞
慢查询或死锁导致后续请求排队。有次全表扫描堵住了支付接口的所有连接。
3. 分层排查实战指南
3.1 数据库层诊断
首先锁定问题连接的特征:
sql复制/* 查看运行时间最长的10个连接 */
SELECT * FROM information_schema.processlist
WHERE COMMAND != 'Slee
