MySQL 连接数爆了怎么办
看到 Too many connections,第一反应往往是调大 max_connections。这能救急,但多半治不了本。
先止血
SHOW VARIABLES LIKE 'max_connections';
SET GLOBAL max_connections = 500;
SET GLOBAL 立即生效且不用重启,但重启后失效。永久生效要写进配置文件:
# my.cnf
[mysqld]
max_connections = 500
再找真因
连接数爆掉,通常是因为连接释放不掉。看看当前都在干什么:
SHOW FULL PROCESSLIST;
重点看 Time 列,几十秒以上的就是问题所在。
-- 只看跑得久的
SELECT id, user, host, db, command, time, state, info
FROM information_schema.processlist
WHERE time > 10 AND command != 'Sleep'
ORDER BY time DESC;
常见元凶
一、没加索引的查询
订单表、日志表数据量上来之后,一个全表扫描就能拖垮整台机器。
EXPLAIN SELECT * FROM acg_order WHERE trade_no = 'xxx';
看 type 列,出现 ALL 就是全表扫描,该加索引了:
ALTER TABLE acg_order ADD INDEX idx_trade_no (trade_no);
:::tip 加索引选低峰期 大表加索引会锁表。几十万行以内一般几秒,上百万行就要谨慎了。 :::
二、日志表没清理
访问日志、操作日志这类表会无限增长。定期清理:
DELETE FROM acg_manage_log WHERE create_time < DATE_SUB(NOW(), INTERVAL 90 DAY);
:::warning 大批量删除要分批
一次删几十万行会产生巨大的事务,可能把从库拖垮。用 LIMIT 5000 循环删。
:::
三、Sleep 连接堆积
大量 Sleep 状态的连接说明连接没被正确关闭。降低超时时间让它们自己断:
wait_timeout = 120
interactive_timeout = 120
预防
- 给高频查询字段加索引
- 日志表配置定期清理
wait_timeout调到合理值- 监控连接数,超过 80% 就告警
- 读写分离(单机撑不住时再考虑)
评论 0