报错是这么冒出来的。业务侧大面积报连接失败,数据库日志写连接数超限,重启数据库能缓解几分钟,很快又被打满。
排查方向其实有限,先把可能性排一排。应用连接池配置过大,多台实例叠加超过上限。也可能是慢查询把连接长期占住,释放不回来。
另外,最大连接数本身设置偏小,没有留出管理连接余量。
上来先看当前连接数和上限
mysql -e 'show status like \"Threads_connected\"; show variables like \"max_connections\"'
再往下按来源地址统计连接
mysql -e 'select host,count(*) from information_schema.processlist group by host order by 2 desc'
接着找出长时间处于空闲或执行的连接
mysql -e 'show full processlist' | head -20
临时提高上限并排查慢查询
mysql -e 'set global max_connections=800'
排查用的命令都是临时敲的,没有写成脚本,事后才整理。
恢复的判定其实很直接。连接数回落到上限的六成以下,业务不再报连接失败,慢查询数量同步下降。
调大连接数只是给慢查询争取时间,每个连接都要占内存;根治要改连接池配置并清掉执行过久的语句。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。