MySQLtoomanyconnections报错

发布时间:2026-06-30 00:48

线上MySQL突然报too many connections,导致业务无法连接数据库。整理了临时恢复、排查连接来源以及永久调整最大连接数的操作过程,包括查看当前连接、杀掉空闲会话、修改max_connections参数的注意事项。

大半夜被报警吵醒,一看日志全是“too many connections”,MySQL直接不让连了。第一反应是先把业务恢复,不然等天亮挨骂。这种报错说白了就是连接数被撑满,新来的请求排队都排不上,要么是并发突然上来,要么是有程序没关连接,一堆sleep在那占着坑。

临时救急:先腾出连接

登不上数据库的时候不能用常规工具,有些机器可能留了给root的保留连接,可以尝试用mysql -u root -p连过去,登录时多加个--connect-timeout=5免得卡死。进去之后用show processlist看一眼,果然满屏的sleep和某些慢查询挂着的连接。来不及分析了,直接批量杀掉空闲连接,语句类似select concat('kill ',id,';') from information_schema.processlist where command='sleep' and time>60,把结果跑一遍,瞬间释放了大半。这时候应用再重连就能上了。

查根因:谁消耗了连接

临时解决之后别急着睡,得翻账。用show full processlist看user和host分布,发现某个从应用服务器发起的连接占了将近两百个,状态全是sleep但time很短,说明那边线程池没复用,每次请求都直接新建连接。另外有个开发库的查询跑了快半小时没结束,蹲在连接上不释放。几个原因凑一块,max_connections的默认151根本扛不住。也可以查performance_schema下的几个host相关表,把历史最大连接数拉出来看看峰值是不是经常触顶。

有些同志喜欢set global max_connections=500急救,确实够快,但这是临时药,重启就丢,而且你得想想机器内存撑不撑得住。一个连接大概占用几兆,盲目加太高把内存跑崩了更麻烦。

长久改法:调参和代码都要动

永久修改得在my.cnf的[mysqld]下面加上max_connections=800(按实际调试),然后重启。但我习惯先在线set global验证几天,确认无副作用再刷进配置文件。如果用的云数据库,控制台就有参数修改入口,改完会提示需要不需要重启,有些版本支持动态生效。代码层面,叫开发把短连接改成长连接或者连接池,php的话注意修改进程模式下连接不能持久化的问题,java那边查查hikari的maximumPoolSize是不是配得比数据库上限还大。

顺便把wait_timeout调低一点,比如300秒,让空闲连接自动踢掉,别在那白白占号。有些框架默认8小时,纯属浪费。这套组合拳打下来,以后应该不会再半夜被too many connections搞起来了。