Skip to main content
Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

MySQL 故障排查

覆盖 MySQL 所有常见故障场景,包含 定位流程、必查命令、根因分析、修复方法。

结构按 从现象 -> 分析 -> 诊断 -> 解决 排列,可直接拿来当运维手册使用。

1. 故障排查总原则(核心法则)

MySQL 的所有故障,基本都可以归为五大类:

  1. 性能瓶颈(CPU / IO / 内存 / 连接数)
  2. 锁问题(死锁、长事务、等待行锁 / 元数据锁)
  3. 资源耗尽(磁盘满 / redo 满 / undo 膨胀)
  4. 复制异常(主从延迟、复制中断、GTID 冲突)
  5. 配置错误 / 参数不当

排查总顺序(必须遵守):

线程 -> 锁 -> 慢 SQL -> 资源 -> 系统 -> 配置 -> 日志

2. 高 CPU 使用率 故障排查

2.1 现象

  • CPU 接近 100%
  • Threads_running 持续高
  • 查询响应时间暴涨

2.2 快速定位(最常用路径)

① 查看当前是否被 SQL 打爆

SHOW PROCESSLIST;

高概率看到:

  • “Sending data”
  • “Copying to tmp table”
  • “Waiting for table metadata lock”

② 查看当前正在运行的 SQL

SELECT * FROM performance_schema.events_statements_current LIMIT 10;

③ 查看是否锁等待导致 CPU 被拖爆

SELECT * FROM information_schema.innodb_locks;

④ 查看最耗 CPU 的 SQL

SELECT * FROM sys.statement_analysis
ORDER BY total_cpu_time DESC LIMIT 10;

2.3 根因

  • 缺索引引发全表扫描
  • 大量复杂 JOIN
  • 全表排序、临时表
  • 大事务导致行锁阻塞
  • 元数据锁 MDL 被长事务占用

2.4 解决方法

  • 添加索引(最常见解决方案)

  • 拆 SQL(避免大查询)

  • Kill 明显卡住的长查询:

    KILL <id>;
    
  • 在线回收元数据锁:

    KILL CONNECTION <trx_holding_MDL>;
    

3. 高 IO 使用率(Read/Write IO)故障排查

3.1 现象

  • 磁盘写吞吐暴涨
  • fsync 延迟高
  • 存储抖动导致 TPS 降低

3.2 检查 MySQL 内部 IO

SHOW GLOBAL STATUS LIKE 'innodb_data_%';
SHOW GLOBAL STATUS LIKE 'innodb_os_log_fsyncs';

3.3 检查是否是 check point 导致

SHOW ENGINE INNODB STATUS\G;

关注:

Log sequence number
Checkpoint age

Checkpoint age 接近 redo log 大小 ⇒ MySQL 强制落盘 -> IO 爆炸

3.4 根因

  • redo log 太小
  • buffer pool 太小
  • 性能不足的存储(非 SSD / SATA)
  • 大量随机写

3.5 解决

  • 调大 redo log:
innodb_log_file_size = 2G
  • 升级 SSD
  • 增加 buffer pool
  • 优化写热点表结构

4. 锁等待 & 死锁 故障排查

4.1 查看所有锁

SELECT * FROM information_schema.innodb_trx;
SELECT * FROM information_schema.innodb_locks;
SELECT * FROM information_schema.innodb_lock_waits;

4.2 查看死锁(最有用)

SHOW ENGINE INNODB STATUS\G;

4.3 根因

  • 多事务抢同一行
  • 更新顺序不一致
  • 索引缺失导致锁范围扩大
  • 大事务长时间不提交

4.4 解决

  • 拆小事务
  • 增加索引
  • 将频繁写热点表分片
  • 改成乐观锁(version 字段)

5. 长事务(最危险问题之一)

5.1 现象

  • undo 表空间暴涨
  • 磁盘变满
  • 复制延迟加剧
  • Checkpoint age 长期不回收

5.2 定位

SELECT * FROM information_schema.innodb_trx
ORDER BY trx_started LIMIT 5;

5.3 常见原因

  • 应用层忘记 commit
  • Hibernate / JPA 开启自动事务
  • MySQL 客户端 idle in transaction

5.4 解决

  • Kill:

    KILL <trx_mysql_thread_id>;
    
  • 改应用(根因永远在应用)

6. 磁盘写满 / 表空间暴涨

6.1 现象

  • MySQL 崩溃
  • 无法写入数据
  • undo / redo 巨大

6.2 检查

df -h

检查 undo 表空间

SELECT tablespace_name, file_size
FROM information_schema.innodb_tablespaces;

6.3 原因

  • 长事务
  • 大量临时表
  • 未清理 binlog
  • InnoDB undo 不可回收

6.4 处理

  • 删除旧 binlog

    PURGE BINARY LOGS BEFORE NOW() - INTERVAL 7 DAY;
    
  • 终止长事务

  • 优化大查询

注意:磁盘满必须立即停 MySQL,否则表空间会损坏。

7. 复制故障(主从 / MGR)排查

7.1 主从复制中断

检查:

SHOW SLAVE STATUS\G;

关注字段:

  • Last_IO_Error
  • Last_SQL_Error
  • Seconds_Behind_Master

常见错误

  • 主键冲突
  • 行找不到(ROW 模式下)
  • relay log 损坏
  • GTID 冲突

7.2 常见修复

  • 重置复制:

    RESET SLAVE ALL;
    CHANGE MASTER TO ;
    START SLAVE;
    
  • 跳过事务(不推荐):

    SET GLOBAL sql_slave_skip_counter=1;
    
  • MGR 修复:

    SELECT * FROM performance_schema.replication_group_member_stats;
    

8. 内存问题(OOM / Buffer Pool 不够)

8.1 排查

SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_reads';

命中率 < 99% ⇒ buffer pool 太小

8.2 OOM 原因

  • join_buffer / sort_buffer 过大
  • 连接数导致内存飙升
  • 查询创建巨大临时表

8.3 最佳配置

join_buffer_size = 1M
sort_buffer_size = 2M
max_connections = 500

9. 启动失败(无法启动 mysqld)

9.1 检查数据目录权限

chown -R mysql:mysql /var/lib/mysql

9.2 查看错误日志

/var/log/mysql/error.log

常见报错:

  • 表空间损坏
  • redo log 读取失败
  • 端口被占用
  • 配置文件拼写错误

9.3 InnoDB 表损坏恢复

innodb_force_recovery = 1~6

6 最危险,只用于导出数据。

10. 网络连接问题排查

检查连接数

SHOW GLOBAL STATUS LIKE 'Threads_connected';

查看是否连接泄漏

SHOW PROCESSLIST;

连不上排查三步骤

  1. MySQL bind-address 是否限制
  2. 防火墙(iptables / firewalld)
  3. 密码插件 caching_sha2 vs mysql_native_password

11. Binlog / Redo / Undo 故障排查

11.1 redo log 100% 满

查看:

SHOW ENGINE INNODB STATUS\G;

现象:

  • Checkpoint age 接近 redo 大小
  • MySQL 卡住、不响应写入

解决:

  • 增加 redo 大小:innodb_log_file_size
  • 优化热点写表
  • 停掉大事务

12. 故障排查流程图(文字版)

Step 1:数据库是否卡住?

查看:

Threads_running

Step 2:如果 >20 -> 查锁

innodb_trx / innodb_locks / innodb_lock_waits

Step 3:无锁 -> 查慢 SQL

sys.statement_analysis

Step 4:慢 SQL 不明显 -> 查 IO

SHOW ENGINE INNODB STATUS

Step 5:IO 正常 -> 查系统

top, vmstat, iostat

Step 6:系统正常 -> 查复制

SHOW SLAVE STATUS\G;

Step 7:仍找不到 -> 看 MySQL 错误日志

13. 最终总结(最重要的 10 条)

  1. 任何问题第一看 Threads_running
  2. 慢 SQL 永远比配置更重要
  3. 长事务是 MySQL 最大敌人
  4. redo / undo 膨胀通常是事务不提交
  5. MDL 锁经常是 alter table 引起的
  6. 复制中断大多由主键冲突或 GTID 冲突
  7. checkpoint age 接近 redo 大小 = IO 爆炸
  8. 大表不要轻易做全表操作
  9. 磁盘满 = 必须停 MySQL
  10. 所有故障排查都离不开 error.log