MySQL InnoDB存储引擎缓存刷盘CheckPoint技术底层实现原理详细介绍
文章目录
- 一、CheckPoint技术背景
- 二、CheckPoint技术引入
- 三、CheckPoint技术实现原理
- 1. LSN标记机制
- 2. CheckPoint触发条件
- 3. CheckPoint执行流程
- 4. LSN状态查询
- 四、CheckPoint与Redo log的关系
- 1. Redo log的作用
- 2. CheckPoint与Redo log的协同工作
- 3. 数据库恢复过程
- 五、CheckPoint关键参数
- 六、CheckPoint对性能的影响
- 1. 正面影响
- 2. 负面影响
- 总结
一、CheckPoint技术背景
我们知道,InnoDB存储引擎为了解决CPU和磁盘之间的性能问题引入了缓冲池,所有数据页的操作都是先在缓冲池执行,然后再更新到磁盘持久化数据。
当数据库接收到一条更新语句时,InnoDB存储引擎会首先记录Redo Log并更新缓存脏页,此时磁盘的数据还未同步更新,为了保证数据持久化,我们就需要将缓存的脏页数据同步到磁盘。
这时候问题就来了,如果每次的脏页更新操作都进行磁盘同步,这个开销会非常的大。假如数据热点集中在某几个页中,那么数据库的性能就会很差。为了避免数据丢失,InnoDB存储引擎采用了 Write Ahead Log 策略,即当事务提交时,先写重做日志(Redo Log),再修改页。当由于发生宕机而导致数据丢失时,通过重做日志来完成数据的恢复,从而满足事务的持久性要求。
在这些技术前提下,为了更好的解决脏页刷盘和数据库恢复的性能问题,因此设计了CheckPoint。
二、CheckPoint技术引入
前面提到的技术背景下,如果说重做日志可以无限的增大,同时缓冲池也足够大,能够缓冲所有数据库的数据,那么是不需要将缓冲池中页的新版本刷回磁盘。因为发生宕机时完全可以通过重做日志来恢复数据库系统的数据到宕机发生的情况。然而现实是这两个条件是很难满足的,即使满足了,如果数据库运行了很久后发生宕机,那么使用重做日志进行恢复的时间也会非常的久。
在实际生产中,缓冲池的容量和重做日志容量都是有限的,且为了避免数据库恢复时间过长,需要定期将脏页刷回磁盘。因此才引入了 Checkpoint(检查点)技术,解决这几个痛点问题:
- 缩短数据库恢复时间:
- 数据库宕机后,只需重做CheckPoint之后的日志,而非全部日志,显著减少恢复时间。
- 通过日志序列号(LSN)标记版本,CheckPoint的LSN表示已持久化到磁盘的数据边界。恢复时,仅需处理
Redo Log LSN - CheckPoint LSN
的日志。
- 管理缓冲池空间:缓冲池内存有限,需通过CheckPoint释放空间。当脏页占用过高时,触发刷新以避免内存溢出。
- 保障重做日志循环使用:重做日志文件是循环使用的,当日志空间不足时,需确保相关脏页已持久化,否则无法覆盖旧日志。
三、CheckPoint技术实现原理
1. LSN标记机制
LSN称为日志序列号(Log Sequence Number),是日志空间中每条日志的结束点,用字节偏移量来表示。在 InnoDB 存储引擎中,LSN 占8个字节,LSN 的值会随着日志的写入而逐渐变大。每个页有LSN,重做日志中也有LSN,CheckPoint也有LSN。
关键LSN类型:
- 页LSN:页头部的
FIL_PAGE_LSN
字段,记录该页最后一次修改的LSN。 - 重做日志LSN:表示日志的写入位置,通过
Log Sequence Number
跟踪。 - CheckPoint LSN:记录已持久化到磁盘的数据页的最大LSN,存储在重做日志文件头部。
2. CheckPoint触发条件
CheckPoint所做的事情都是将缓冲池中的脏页刷回到磁盘,不同之处在于每次刷新多少页到磁盘,每次从哪里获取脏页,以及什么时间触发 CheckPoint。在 InnoDB 内部主要有以下两种 CheckPoint类型:
-
Sharp CheckPoint:
- 触发时机:数据库正常关闭(默认行为,
innodb_fast_shutdown=1
)或执行FLUSH TABLES WITH READ LOCK
命令强制刷新时触发。 - 行为:将内存中所有脏页一次性刷新到磁盘,确保数据完全持久化。
- 缺点:运行时频繁触发会导致性能骤降,因此InnoDB主要使用Fuzzy CheckPoint。
- 触发时机:数据库正常关闭(默认行为,
-
Fuzzy CheckPoint(运行时默认机制):
- Master Thread CheckPoint:
- 触发时机:Master线程每秒或每10秒执行,异步刷新部分脏页。
- 行为:从脏页列表中按比例刷新,避免阻塞用户查询。
- FLUSH_LRU_LIST CheckPoint:
- 触发时机:LRU列表空闲页不足100个时。
- 行为:移除LRU尾端页,若为脏页则触发刷新。
- Async/Sync Flush CheckPoint:
- 触发条件:重做日志空间不足(接近循环使用的阈值)。
- 行为:
- Async Flush:当
checkpoint_age
(重做日志LSN与CheckPoint LSN的差值)超过async_water_mark
(75%日志空间)时,异步刷新足够脏页以降低差值。 - Sync Flush:当
checkpoint_age
超过sync_water_mark
(90%日志空间)时,同步刷新脏页,确保日志可重用。
- Async Flush:当
- Dirty Page too much CheckPoint:
- 触发条件:脏页比例超过阈值(如
innodb_max_dirty_pages_pct=75%
)。 - 行为:强制刷新脏页,防止内存溢出。
- 触发条件:脏页比例超过阈值(如
- Master Thread CheckPoint:
3. CheckPoint执行流程
-
脏页选择:
- 从FLUSH链表(按脏页第一次修改LSN排序)中选择最老的脏页。
- 优先刷新对恢复影响最大的页(LSN较小的页)。
-
脏页刷新:
- 通过Page Cleaner线程(MySQL 5.6+)或后台线程异步执行,避免阻塞用户查询。
- 每次刷新的页数量由系统参数决定,通常不是一次性刷新所有脏页。
- 在刷新过程中,InnoDB会使用Double Write Buffer(双写缓冲区)确保数据完整性。
- 刷新后更新页LSN和CheckPoint LSN。
-
CheckPoint记录:
- 记录当前LSN(Log Sequence Number)。
- 将CheckPoint LSN写入重做日志文件头部(交替写入两个CheckPoint块,避免介质故障)。
4. LSN状态查询
LSN的大小状态可以通过命令SHOW ENGINE INNODB STATUS
来查询:
mysql> SHOW ENGINE INNODB STATUS;
......
---
LOG
---
Log sequence number 2867040
Log flushed up to 2867040
Pages flushed up to 2867040
Last checkpoint at 2867031
0 pending log flushes, 0 pending chkp writes
10 log i/o's done, 0.10 log i/o's/second
......
Log sequence number: 表示当前的 Redo log (in buffer pool) 中的 LSN。
Log flushed up to: 表示刷到 Redo log file 磁盘数据中的 LSN。
Pages flushed up to: 表示下一次即将做 CheckPoint LSN 的位置,如果没有新数据写入则取 LSN 的值。
Last checkpoint at: 表示上一次检查点所在位置的 LSN。
四、CheckPoint与Redo log的关系
1. Redo log的作用
- 重做日志(Redo log)记录了所有对数据的修改操作
- 用于保证事务的持久性(Durability)
- 是InnoDB实现ACID特性中"持久性"的关键
2. CheckPoint与Redo log的协同工作
- 问题:如果Redo log被覆盖,而脏页还未刷新到磁盘,数据库崩溃后将无法恢复
- 解决方案:通过CheckPoint确保在Redo log被重写前,所有相关的脏页已刷新到磁盘
关键关系:InnoDB使用循环写入的方式管理Redo log,当Redo log空间不足时,会触发CheckPoint,确保所有与当前Redo log相关的脏数据已刷新到磁盘。
3. 数据库恢复过程
当数据库崩溃后恢复时:
- 从Checkpoint位置开始
- 重放Checkpoint之后的Redo log
- 恢复到崩溃前的状态
优势:相比从头开始重放所有Redo log,仅重放Checkpoint之后的记录,大大减少了恢复时间。
五、CheckPoint关键参数
innodb_buffer_pool_size
:增大缓冲池可减少脏页刷新频率,但需确保内存足够(通常为系统内存的50-70%)。innodb_io_capacity
:控制脏页刷新速度,值越大刷新越快(建议根据磁盘IOPS设置)。innodb_max_dirty_pages_pct
:脏页比例上限(默认75%),超过后触发紧急刷新。innodb_lru_scan_depth
:控制每秒扫描LRU列表的深度(默认1024),影响脏页发现效率。innodb_adaptive_flushing
:启用自适应刷新(默认ON),根据负载动态调整刷新速度。
六、CheckPoint对性能的影响
1. 正面影响
- 减少恢复时间:确保崩溃后恢复时间可控
- 平衡I/O负载:将大块的I/O操作分散到多个小操作中,避免突发I/O
- 避免redo log过度增长:保证日志文件大小在合理范围内
2. 负面影响
- CPU开销:脏页刷新需要CPU计算
- I/O开销:将数据写入磁盘需要I/O操作
- 可能影响写性能:在CheckPoint期间,写操作可能需要等待
权衡:InnoDB通过参数配置(如
innodb_max_dirty_pages_pct
)在数据安全性和性能之间找到平衡点。
总结
InnoDB的CheckPoint技术是保证数据库高可用性和数据一致性的核心机制:
- 核心目的:减少数据库崩溃恢复时间,确保数据一致性
- 主要类型:Sharp Checkpoint 和 Fuzzy Checkpoint
- 触发时机:定时、脏页比例、日志空间、缓冲池不足等
- 实现机制:通过Buffer Pool的Flush List管理脏页,定期刷新到磁盘
- 与Redo log协同:确保Redo log被覆盖前,相关脏页已刷新到磁盘
- 性能权衡:在数据安全性和系统性能间找到平衡