MySql的Checkpoint技术
前言
对数据库中数据进行增删改时,都是先在buffer pool中完成,为了提高事务的操作效率,buffer pool中数据并不会立即写入磁盘,所以可能出现内存中数据和磁盘数据不一致的情况。
如果buffer pool发生故障导致数据无法持久化,造成磁盘和buffer pool数据不一致。
为了防止内存中修改的数据尚未写入磁盘,发生故障而不能持久化的问题。可以通过redo log先行的方式进行保障。 redo log可以在故障重启之后做“重做”,保障了事务的持久化特性,但是redo log空间不可能无限扩大,对于内存中已修改未提交到磁盘的数据,也就是“脏页”,也需要写入磁盘。
对于内存中“脏页”的处理就是checkpoint的工作,在一定情况下将脏页放入磁盘。
checkpoint主要解决以下问题:
- 缩短数据库恢复的时间。
- 缓冲池不够用时,将脏页刷入磁盘。
- 重做日志不可用时,刷新脏页。
- 故障恢复时只需要对checkpoint后的重做日志进行恢复,缩短了恢复时间。 缓冲区不够用时,采用lru算法,使部分脏页刷入磁盘。
checkpoint分类
checkpoint分为两种:
- sharp checkpoint:在关闭数据库时,将buffer pool中的脏页全部刷入磁盘。
- fuzzy checkpoint:在数据库正常运行时,找到不同时机将脏页写入磁盘,一部分一部分的刷入磁盘,不会因为一次性刷入磁盘造成性能问题。
master thread checkpoint master thread中,每秒或每10秒一次的频率将脏页从内存刷入磁盘,这个过程是异步的。
flush_lru_list checkpoint
flush_lru_list checkpoint是在单独的page cleaner线程中执行的。lru列表是buffer pool的lru列表,lru空闲列表中保留一定数量的空闲页面,来保证buffer pool中有足够的空间应对新的数据库请求。
在空闲列表不足时,发生flush_lru_list checkpoint,空闲数量阈值是可以配置的。
async/sync flush checkpoint
async/sync flush checkpoint是在单独的page cleaner线程中执行的。在重做日志不可用时,将buffer pool中的一部分脏数据刷新到磁盘。 通过配置阈值,在redo log空间不足指定阈值时进行刷新。
dirty page too much checkpoint
dirty page too much checkpoint是在master thread线程中每秒一次的频率实现的。 dirty page too much 意味着buffer pool中脏页过多,执行checkpoint脏页刷入磁盘,保证buffer pool中有足够的可用页面。
总结
mysql为提高事务执行效率,并不会每次都和磁盘交互进行持久化,通过日志先行策略保证事务的持久化。 对于事务修改过程中的脏页,通过异步方式刷盘,通过checkpoint达到内存和redo log可用空间的目的。
转载自:https://juejin.cn/post/6869318169685819406