1. 问题现象与初步判断
上周五凌晨2点37分,我被一阵急促的报警短信惊醒——生产环境的MySQL连接池突然爆满,所有新请求都被阻塞。打开监控系统一看,活跃连接数曲线像坐了火箭一样直冲上限,而正常情况下这个数值应该平稳维持在50-60之间。
这种典型的连接泄漏问题,就像你家水龙头坏了导致整个小区水压下降。每个挂死的连接都占用着宝贵的服务器资源,最终会导致整个应用瘫痪。我立即通过跳板机连上数据库服务器,执行了SHOW PROCESSLIST命令,果然发现了二十多个状态为"Sleep"却持续了2小时以上的连接。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统化排查流程
2.1 连接状态分析
首先需要确认这些"僵尸连接"的真实状态:
sql复制SELECT * FROM performance_schema.threads
WHERE PROCESSLIST_STATE = 'Sleep'
AND PROCESSLIST_TIME > 60;
重点关注几个关键字段:
PROCESSLIST_TIME:睡眠时长(秒)PROCESSLIST_INFO:最后执行的SQL语句THREAD_OS_ID:对应的操作系统线程ID
2.2 连接来源定位
通过以下语句追溯连接来源:
sql复制SELECT
p.ID,
p.USER,
p.HOST,
p.DB,
p.COMMAND,
p.TIME,
p.STATE,
p.INFO,
t.PROCESSLIST_ATTR
FROM
performance_schema.threads t
JOIN information_schema.PROCESSLIST p ON t.PROCESSLIST_ID = p.ID
WHERE
p.COMMAND = 'Sleep'
AND p.TIME > 300;
PROCESSLIST_ATTR字段在MySQL 8.0+会记录连接池信息,类似:
code复制{"program_name":"myapp","connection_pool":"HikariPool-1"}
2.3 线程堆栈分析
对于Linux系统,可以用gdb获取线程堆栈:
bas复制
