MySQL CPU过高排查:连接超时与慢查询优化
当MySQL服务器的CPU占用率持续升高时,通常是由大量的空闲TCP连接未正常关闭,或是存在资源消耗巨大的慢查询导致的。通过合理设置连接超时时间(wait_timeout)来快速清理无效连接,并利用SHOW PROCESSLIST监控数据库会话状态以定位阻塞源,可以有效缓解系统压力并提升数据库响应速度。
一、检查并优化连接超时设置
MySQL在处理连接时,如果空闲时间超过设定值会自动断开连接,若该时间过长,高峰期会积累大量处于“Sleep”状态的连接,导致线程调度负担加重,进而引发CPU飙升。因此,根据应用类型调整连接超时时间至关重要。
第1步:理解关键超时参数
在修改配置前,需了解两个核心变量的区别:
wait_timeout:针对非交互式连接(如JDBC、ODBC等程序连接),指MySQL关闭空闲连接前等待的秒数。Linux下取值范围最大为31536000秒,默认值通常为28800秒(8小时),这个数值对Web应用来说往往过长。interactive_timeout:针对交互式连接(如mysql命令行客户端),指MySQL关闭交互连接前等待的秒数。默认值同样为28800秒。
建议将这两个值设置为较小的数值(如90-120秒),以便在访问低谷期快速回收连接资源。
第2步:修改配置文件(永久生效)
要持久化修改这些参数,需要编辑MySQL的配置文件 /etc/my.cnf(具体路径可能因系统而异)。
在 [mysqld] 段落中添加或修改以下行:
[mysqld] wait_timeout = 90 interactive_timeout = 90
官方文档要求同时修改这两个参数。修改完成后,必须重启MySQL服务才能生效:
service mysqld restart
或者使用:/etc/init.d/mysql restart。
第3步:在线临时修改(无需重启)
如果需要立即见效且不打算重启服务,可以直接在数据库中执行SET命令。注意,这种修改在MySQL重启后会失效。
-- 查看当前超时设置 SHOW VARIABLES LIKE '%timeout%'; -- 同时修改全局的交互和非交互超时时间 SET GLOBAL interactive_timeout = 100; SET GLOBAL wait_timeout = 100;
修改后退出并重新登录MySQL客户端,新设置即可在当前会话中查看生效。需注意,修改 interactive_timeout 会联动影响相关逻辑,而单独修改 wait_timeout 在某些场景下可能表现不一致,建议两者保持一致。
二、排查高负载SQL语句与异常连接
除了连接池管理不当导致的线程堆积外,具体的慢查询或未关闭的连接也是导致CPU过载的直接原因。我们需要进入数据库内部进行实时诊断。
第4步:查看当前活跃进程列表
登录MySQL后,切换到具体业务库(可选),然后执行以下命令查看所有正在运行或等待中的线程信息:
USE database_name; -- 切换到目标数据库 SHOW FULL PROCESSLIST;
也可以通过查询信息架构表获取更详细的数据:
SELECT * FROM information_schema.PROCESSLIST WHERE INFO IS NOT NULL;
第5步:分析PROCESSLIST输出字段
SHOW FULL PROCESSLIST 返回的列表中,各列含义如下:
- Id:连接标识符,用于后续Kill操作。
- User/Host:发起连接的账户和IP端口,有助于追踪问题来源的应用或服务。
- db:当前连接的数据库。
- Command:当前执行的动作。常见值为 Sleep(空闲)、Query(执行中)、Connect(新建)。
- Time:当前状态持续的秒数。如果大量连接的Time值很大且状态为Sleep,说明连接长时间未被释放。
- State:SQL语句执行的当前阶段(见下方详解)。
- Info:正在执行的SQL语句文本。这是定位具体慢查询的最直接依据。
第6步:识别危险的State状态
状态(State)反映了SQL执行的生命周期。某些状态持续过久是性能隐患的信号:
- Sleeping:连接空闲。如果数量异常多,通常是前端代码未在输出结束后调用Close方法,导致连接被网络层保持而DB端仍处于休眠。
- Sending data / Copying to tmp table:表示正在处理数据或建立临时表。如果在内存临时表过大时需要写磁盘(Copying to tmp table on disk),会导致严重的I/O和CPU竞争。
- Locked / Waiting for tables:表明发生了锁冲突,可能是其他事务未提交导致当前查询被阻塞。
- Sorting for group/order:正在进行排序操作,缺少索引或数据量大时会显著增加CPU消耗。
实战中,常遇到前端程序只查询不关闭连接的情况。由于网络输出耗时远大于SQL执行耗时,连接长时间维持在Sleep状态,一旦并发量激增,就会耗尽连接池并拖垮数据库CPU。
总结
解决MySQL CPU过高的问题,核心在于切断无效连接并优化执行计划。一方面,将 wait_timeout 控制在分钟级,确保闲置连接快速释放;另一方面,定期审查长耗时和低效状态的进程,修复代码层面的资源泄漏。以上就是MySQL占用CPU过高排查原因及解决方案的详细内容,更多关于MySQL性能优化的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













