Carry の Blog Carry の Blog
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • Python
  • Shell
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carry の Blog

好记性不如烂键盘
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • Python
  • Shell
  • MySQL8-SOP手册
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • MySQL8-SOP

  • MySQL实战45讲学习笔记

    • MySQL45讲学习笔记
    • MySQL基础架构
    • MySQL日志系统 (Redo Log 与 Binlog)
    • MySQL字符串字段索引优化
    • MySQL索引原理与优化
    • MySQL锁机制详解
    • MySQL事务与MVCC机制
    • MySQL普通索引与唯一索引的选择
    • MySQL优化器如何选择索引
    • MySQL抖动刷脏页
      • 1. 什么是刷脏页
      • 2. 刷脏页的工作机制
        • 2.1 内存结构
        • 2.2 刷脏页触发条件
      • 3. 抖动现象分析
        • 3.1 什么是抖动
        • 3.2 抖动产生的原因
        • 3.3 抖动的表现
      • 4. 监控抖动现象
        • 4.1 关键监控指标
        • 4.2 常见的抖动指标
      • 5. 抖动问题诊断
        • 5.1 使用Performance Schema
        • 5.2 检查系统资源
      • 6. 解决方案
        • 6.1 调整缓冲池配置
        • 6.2 调整刷脏页相关参数
        • 6.3 优化应用程序
        • 6.4 硬件升级
      • 7. 预防措施
        • 7.1 合理规划配置
        • 7.2 监控告警设置
        • 7.3 定期维护
      • 8. 实际案例分析
        • 8.1 案例背景
        • 8.2 问题诊断
        • 8.3 解决方案
      • 9. 最佳实践建议
        • 9.1 参数调优
        • 9.2 性能监控
        • 9.3 应用优化
      • 10. 总结
    • 表空间管理与回收
    • count函数详解
    • 日志索引
    • orderby工作原理
    • 随机排序实现
    • SQL性能差异函数与转换
    • 慢查询分析锁与版本
    • 幻读与间隙锁
    • 加锁规则分析
    • 应急性能优化方法
    • 数据持久化保证
    • 主备一致性原理
    • 高可用架构与切换
    • 备库延迟分析与优化
    • 主备切换GTID
    • 读写分离实践与问题
    • 数据库健康检查
    • 锁与死锁
    • 数据误删恢复
    • Kill命令详解
    • 查询与内存使用分析
    • Join原理与选择
    • 临时表原理与应用
    • 内部临时表详解
    • Memory引擎详解
    • 自增ID详解
    • Insert加锁分析
    • 表复制方法比较
    • Grant与权限管理
    • 分区表详解
    • SQL语句中的Join问题
    • 自增ID用尽问题
  • 专题系列
  • MySQL实战45讲学习笔记
Carry の Blog
2026-03-04
目录

MySQL抖动刷脏页

# MySQL抖动刷脏页

# 1. 什么是刷脏页

刷脏页(Dirty Page Flushing)是InnoDB存储引擎中一个重要的概念。当数据在内存缓冲池(Buffer Pool)中被修改后,这些修改被称为"脏页"(Dirty Pages)。为了保证数据的持久性,InnoDB需要将这些脏页写回到磁盘上的数据文件中。

# 2. 刷脏页的工作机制

# 2.1 内存结构

InnoDB Buffer Pool
├── 数据页(Data Pages)
├── 索引页(Index Pages)
├── 脏页(Dirty Pages) ← 需要刷回磁盘
└── 清洁页(Clean Pages) ← 已经写回磁盘
1
2
3
4
5

# 2.2 刷脏页触发条件

  1. 缓冲池脏页比例过高:当脏页占缓冲池的比例超过阈值时
  2. 后台线程定期刷新:后台线程定期执行刷脏页操作
  3. 日志文件写满:当redo log写满时需要刷脏页
  4. 数据库关闭:关闭数据库时需要刷完所有脏页
  5. 手动刷脏页:通过命令手动触发

# 3. 抖动现象分析

# 3.1 什么是抖动

抖动(Thrashing)是指在高并发写入场景下,系统频繁地进行刷脏页操作,导致性能急剧下降的现象。

# 3.2 抖动产生的原因

  1. 写入压力过大:大量并发写入导致缓冲池中脏页快速增长
  2. 刷脏页速度跟不上写入速度:系统无法及时将脏页写回磁盘
  3. 缓冲池配置不合理:缓冲池太小无法容纳足够数据
  4. 磁盘I/O性能瓶颈:磁盘写入速度跟不上内存写入速度

# 3.3 抖动的表现

性能指标异常:
- QPS下降严重
- 响应时间大幅增加
- 系统CPU使用率升高
- I/O等待时间增加
- InnoDB状态显示脏页比例过高
1
2
3
4
5
6

# 4. 监控抖动现象

# 4.1 关键监控指标

-- 查看InnoDB状态信息
SHOW ENGINE INNODB STATUS\G

-- 查看脏页相关信息
SELECT 
    VARIABLE_NAME,
    VARIABLE_VALUE 
FROM INFORMATION_SCHEMA.GLOBAL_STATUS 
WHERE VARIABLE_NAME LIKE '%dirty%';

-- 查看缓冲池使用情况
SELECT 
    pool_size,
    pages_free,
    pages_data,
    pages_dirty,
    pages_flushed
FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 4.2 常见的抖动指标

关键指标:
1. Innodb_buffer_pool_pages_dirty:脏页数量
2. Innodb_buffer_pool_pages_total:缓冲池总页数
3. Innodb_buffer_pool_dirty_pages_pct:脏页百分比
4. Innodb_buffer_pool_pages_flushed:已刷页数
5. Innodb_os_log_written:已写入日志字节数
1
2
3
4
5
6

# 5. 抖动问题诊断

# 5.1 使用Performance Schema

-- 查看缓冲池相关事件
SELECT 
    EVENT_NAME,
    COUNT_STAR,
    SUM_TIMER_WAIT/1000000000000 AS total_wait_ms
FROM performance_schema.events_waits_summary_global_by_event_name 
WHERE EVENT_NAME LIKE '%buffer_pool%'
ORDER BY total_wait_ms DESC;
1
2
3
4
5
6
7
8

# 5.2 检查系统资源

# 检查磁盘I/O
iostat -x 1 5

# 检查内存使用
free -h

# 检查进程状态
top -p $(pgrep mysqld)
1
2
3
4
5
6
7
8

# 6. 解决方案

# 6.1 调整缓冲池配置

-- 查看当前缓冲池配置
SHOW VARIABLES LIKE 'innodb_buffer_pool%';

-- 增加缓冲池大小(需要重启生效)
SET GLOBAL innodb_buffer_pool_size = 2G;
1
2
3
4
5

# 6.2 调整刷脏页相关参数

-- 调整脏页刷新比例
SET GLOBAL innodb_max_dirty_pages_pct = 75;

-- 调整刷新线程数量
SET GLOBAL innodb_write_io_threads = 8;
SET GLOBAL innodb_read_io_threads = 8;
1
2
3
4
5
6

# 6.3 优化应用程序

-- 减少单次写入的数据量
-- 使用批量插入代替单条插入
INSERT INTO table VALUES 
(1, 'data1'),
(2, 'data2'),
(3, 'data3');

-- 控制事务大小,避免长时间持有锁
BEGIN;
-- 执行少量操作
COMMIT;
1
2
3
4
5
6
7
8
9
10
11

# 6.4 硬件升级

  1. SSD硬盘:提高磁盘I/O性能
  2. 增加内存:提供更多缓冲池空间
  3. 多核CPU:提高并发处理能力

# 7. 预防措施

# 7.1 合理规划配置

-- 推荐配置
innodb_buffer_pool_size = 70% of total RAM
innodb_max_dirty_pages_pct = 75
innodb_flush_log_at_trx_commit = 2  -- 平衡性能和安全性
1
2
3
4

# 7.2 监控告警设置

-- 创建监控脚本
CREATE EVENT check_dirty_pages
ON SCHEDULE EVERY 5 MINUTE
DO
BEGIN
    DECLARE dirty_pct FLOAT;
    SELECT (pages_dirty * 100.0 / pages_total) INTO dirty_pct
    FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS;
    
    IF dirty_pct > 70 THEN
        -- 发送告警
        INSERT INTO alert_log (message, timestamp) 
        VALUES ('High dirty page percentage: ' + dirty_pct, NOW());
    END IF;
END;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 7.3 定期维护

-- 定期执行OPTIMIZE TABLE
-- 减少碎片,提高写入效率
OPTIMIZE TABLE table_name;

-- 分析表统计信息
ANALYZE TABLE table_name;
1
2
3
4
5
6

# 8. 实际案例分析

# 8.1 案例背景

某电商平台在促销活动期间出现严重的性能问题,表现为:

  • 系统响应时间从正常100ms上升到5000ms以上
  • 数据库CPU使用率达到90%以上
  • 用户下单成功率下降

# 8.2 问题诊断

通过监控发现:

  • InnoDB缓冲池脏页比例达到90%以上
  • 磁盘I/O等待时间显著增加
  • 刷脏页频率异常增高

# 8.3 解决方案

  1. 临时措施:

    SET GLOBAL innodb_max_dirty_pages_pct = 90;
    SET GLOBAL innodb_flush_log_at_trx_commit = 2;
    
    1
    2
  2. 长期优化:

    • 增加缓冲池大小到4GB
    • 升级到SSD存储
    • 优化应用层批量写入逻辑

# 9. 最佳实践建议

# 9.1 参数调优

-- 生产环境推荐参数
innodb_buffer_pool_size = 70% of total RAM
innodb_max_dirty_pages_pct = 75
innodb_flush_log_at_trx_commit = 2
innodb_write_io_threads = 8
innodb_read_io_threads = 8
1
2
3
4
5
6

# 9.2 性能监控

  • 持续监控脏页比例
  • 监控I/O等待时间
  • 定期分析InnoDB状态
  • 建立性能基线

# 9.3 应用优化

  • 合理使用事务
  • 批量处理数据
  • 避免长时间运行的查询
  • 优化索引设计

# 10. 总结

MySQL抖动刷脏页问题是高并发写入场景下的典型性能瓶颈。通过合理的配置优化、监控告警和应用层面的改进,可以有效避免和解决这个问题:

  1. 理解机制:深入理解InnoDB的缓冲池和刷脏页工作机制
  2. 预防为主:通过合理的参数配置预防抖动发生
  3. 及时监控:建立完善的监控体系及时发现问题
  4. 快速响应:制定应急预案快速处理突发状况
  5. 持续优化:根据业务特点不断优化配置和架构

通过以上措施,可以确保数据库在高并发场景下稳定运行,避免因刷脏页抖动导致的性能问题。

上次更新: 3/4/2026

← MySQL优化器如何选择索引 表空间管理与回收→

最近更新
01
表空间管理与回收
03-04
02
count函数详解
03-04
03
读写分离实践与问题
03-04
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式