先确认mysqld进程是否真在吃CPU:用top/htop看%CPU占比,若非第一则问题不在MySQL;常见干扰项包括备份脚本、日志轮转等;即使排第二,也需对比与第一名差距再定优先级。

确认是不是 mysqld 进程真正在吃 CPU
别一看到监控告警就跳进 MySQL 里查 SQL。先用 top 或 htop 看清进程级占用:如果 mysqld 的 %CPU 列不是第一,那问题根本不在数据库。常见干扰项包括备份脚本、日志轮转、其他容器里的批处理进程。哪怕 mysqld 排第二,也要看它和第一名的差距——差 5% 和差 50% 的排查优先级完全不同。
SHOW PROCESSLIST 显示全是 Sleep,但 CPU 还是 100%
这是最让人困惑的典型现象:连接列表里没活跃查询,Command 全是 Sleep,Time 却有几百上千秒。这往往指向两个隐藏消耗源:
-
innodb_log_file_size太小(比如默认 48MB × 2),redo log 频繁写满,触发强制刷脏页,CPU 被后台线程持续拉高 -
innodb_buffer_pool_size过小(比如仅 128MB),buffer pool 命中率掉到 95% 以下,大量物理读 + 频繁页置换,CPU 在做无意义搬运 - 检查方式:
SHOW VARIABLES LIKE 'innodb_log_file_size';和SHOW ENGINE INNODB STATUS\G里找log capacity used和buffer pool hit rate
long_query_time 设为 2 秒,但实际慢 SQL 可能只跑 0.8 秒
很多团队按经验设 long_query_time = 2,结果漏掉高频轻量级杀伤——比如每秒执行 200 次、每次 0.8 秒的简单查询。它们单次不进慢日志,但合起来能把 CPU 吃干抹净。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 真正该看的是
Rows_examined和执行频次,不是绝对耗时 - 临时启用全量采样:
SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 0;(注意:仅调试用,开太久会影响性能) - 配合
SELECT * FROM performance_schema.events_statements_summary_by_digest ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;找“单位时间总耗时最高”的语句
wait_timeout 和 interactive_timeout 不匹配导致连接堆积
应用端用长连接池,但 MySQL 侧 wait_timeout 设得过大(比如 28800 秒),Sleep 连接长期不释放,线程数虚高。每个 Sleep 线程虽不干活,但维持连接状态、心跳检测、权限校验仍占调度资源,尤其在连接数逼近 max_connections 时,线程上下文切换开销会明显推高 CPU。
- 建议值:
wait_timeout = 60(应用空闲连接 60 秒断开),interactive_timeout = 600(DBA 手动连接可稍长) - 改完必须
SET GLOBAL wait_timeout = 60;生效,重启不解决已存在的旧连接 - 观察
SHOW STATUS LIKE 'Threads_connected';是否在 1–2 分钟内回落
配置调优容易忽略 buffer pool 和 redo log 的联动关系:buffer pool 太小 → 脏页多 → redo log 写得快 → 更快写满 → 更频繁刷盘 → CPU 更高。这两个参数必须一起看,不能只调一个。

















