一、InnoDB 刷脏页(最常见原因)
现象:
- 监控可见磁盘 I/O 突增,TPS 短暂下降。
SHOW ENGINE INNODB STATUS
中BUFFER POOL AND MEMORY
的Modified db pages
值较高。
原因:
- 脏页积累:内存中的脏页(修改后未刷盘的数据页)积累到阈值(默认 75%),触发后台刷盘。
- Redo Log 切换:Redo Log 写满切换时强制刷脏页(Checkpoint 机制)。
解决方案:
-
调整刷盘速度 :
iniinnodb_io_capacity = 2000 # 根据磁盘性能设置(SSD 建议 2000~20000) innodb_max_dirty_pages_pct = 60 # 降低脏页比例阈值
-
优化 Redo Log :
iniinnodb_log_file_size = 4G # 增大 Redo Log 文件(减少切换频率) innodb_log_files_in_group = 3 # 增加日志文件数量
-
监控脏页状态 :
sqlSHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
二、日志系统(Redo Log/Binlog)压力
现象:
- 事务提交延迟,
SHOW PROCESSLIST
显示大量事务处于query end
状态。 - 监控显示磁盘写入延迟高。
原因:
- Redo Log 刷盘策略 :
innodb_flush_log_at_trx_commit=1
时每次提交同步刷盘,I/O 压力大。 - Binlog 刷盘策略 :
sync_binlog=1
导致每次提交同步刷 Binlog。
解决方案:
-
平衡一致性与性能 :
iniinnodb_flush_log_at_trx_commit = 2 # 提交时写 OS 缓存,每秒刷盘(牺牲少量持久性) sync_binlog = 1000 # 每 1000 次提交刷一次 Binlog
-
使用高性能磁盘:SSD 提升日志写入速度。
三、查询性能突增
现象:
- CPU 使用率或锁等待时间突增。
- 慢查询日志中突然出现复杂查询。
原因:
- 低效 SQL 突然执行:全表扫描、未命中索引的查询。
- 锁竞争加剧:热点行更新导致锁等待。
解决方案:
-
捕获慢查询 :
inislow_query_log = ON long_query_time = 0.5
-
优化 SQL :
- 添加缺失索引。
- 重写复杂查询,避免全表扫描。
-
减少锁冲突 :
- 使用
innodb_autoinc_lock_mode=2
(交错自增锁)。 - 缩短事务长度,尽快提交。
- 使用
四、内存不足或 Swap 触发
现象:
- 内存使用率接近 100%,
vmstat
显示si/so
(Swap 换入换出)值高。 SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_wait%'
显示等待次数。
原因:
- Buffer Pool 不足:频繁从磁盘加载数据页。
- 系统内存竞争:其他进程占用内存,触发 Swap。
解决方案:
-
扩大 Buffer Pool :
iniinnodb_buffer_pool_size = 系统内存的 70%~80%
-
禁用 Swap :
bashsysctl vm.swappiness=0
-
优化内存分配 :
iniinnodb_buffer_pool_instances = 8 # 减少锁争用
五、后台维护任务
现象:
- 定期出现性能波动(如每天凌晨)。
SHOW PROCESSLIST
显示OPTIMIZE TABLE
或ANALYZE TABLE
。
原因:
- 统计信息更新 :
ANALYZE TABLE
导致临时资源消耗。 - 表优化操作 :
OPTIMIZE TABLE
重建表文件。
解决方案:
-
调整维护计划 :
- 在业务低峰期执行
OPTIMIZE
或ANALYZE
。
- 在业务低峰期执行
-
启用持久化统计信息 :
iniinnodb_stats_persistent = ON innodb_stats_auto_recalc = ON
六、硬件或系统层问题
现象:
- 磁盘延迟高(
iostat -x
显示await
值突增)。 - 网络波动(如云服务器网络带宽突增)。
解决方案:
- 监控硬件指标 :
- 磁盘健康度(SMART 状态)。
- 网络带宽使用情况。
- 升级硬件 :
- 更换 SSD 提升 I/O 能力。
- 增加内存避免 Swap。
七、诊断工具与命令
-
实时状态分析 :
bash# 查看系统资源 top iostat -x 1 vmstat 1 # 查看 InnoDB 状态 SHOW ENGINE INNODB STATUS\G
-
历史趋势分析 :
- 使用 Prometheus + Grafana 监控 MySQL 和系统指标。
- 开启 Performance Schema 记录历史查询。
总结:按优先级排查
- 检查刷脏页 → 调整
innodb_io_capacity
和 Redo Log 配置。 - 优化日志刷盘策略 → 平衡
innodb_flush_log_at_trx_commit
和sync_binlog
。 - 捕获慢查询 → 优化 SQL 和索引。
- 检查内存压力 → 扩大 Buffer Pool,禁用 Swap。
- 排查硬件问题 → 监控磁盘和网络。