当前位置: 代码迷 >> 综合 >> 【MySQL 进阶】重做日志 与 Checkpoint 技术
  详细解决方案

【MySQL 进阶】重做日志 与 Checkpoint 技术

热度:73   发布时间:2024-02-27 20:50:36.0

1、Redo Log 重做日志


前面已经提到,使用 缓冲池技术的原因是为了协调 CPU 以及磁盘速度。页数据的改变通常在缓冲池中执行。如果一条 DML 语句修改了数据造成缓冲池和磁盘中数据不一致的问题。那么此时的页称之为脏页(dirty page)。数据库需要将脏页刷新到磁盘中。但是倘若每一个页变成脏页就要执行一次刷新操作,那么其开销是非常大的。当刷新到磁盘的时候发生宕机,可能就会造成数据丢失,所以事务系统通常采用 Write Ahead Log 的方式,先写重做日志,然后在修改页,如果发生数据丢失通过重做日志完成数据恢复,这也是事务中 ACID 中的 D 的体现。


如果缓冲池空间大小足够大,并且重做日志空间大小也足够大,能够缓冲数据库所有的数据的时候,那么当服务宕机的时候,完全可以通过重做日志恢复数据。这种方式理论上是可以的,但是必须满足缓冲池以及重做日志空间足够大的前提条件。但是当数据库运行几个月甚至几年之后这时候发生宕机,通过重做日志恢复数据的时间将非常长,此时恢复数据的代价很大。


2、Checkpoint


因此Checkpoint技术就是解决这些问题,缩短数据库恢复的时间,将脏页刷新到数据库中以及重做日志不可用时,刷新脏页。

  • 缩短数据库恢复时间

当数据库服务不可用的时候,数据库并不需要重做所有的日志,仅仅需要重做 Checkpoint 之后的日志记录,因为在 Checkpoint 之前的日志已经刷新到磁盘中。所以这种方式就可以大大缩短数据库恢复的时间。

  • 缓冲池不够的时候,刷新脏页数据到磁盘中

当缓冲池空间不够的时候,根据LRU 算法,此时会溢出不常用的页数据,那么存储引擎会强制执行 Checkpoint ,将溢出的脏页数据刷新到磁盘中。

  • 重做日志不可用时候,刷新脏页数据到磁盘中

重做日志出现不可用的时候,是因为当前数据库事务系统对重做日志设计都是循环使用的,并不是让其无限增大。所以重做日志可以被覆盖的部分是已经不需要的部分。但是倘若重做日志还是需要的额,此时就需要必要强制Checkpoint,刷新数据。




3、Checkpoint 的分类


Checkpoint 大致可以划分为 两类: Sharp Checkpoint & Fuzzy Checkpoint。 前者是在数据库关闭的时候将所有的脏页刷新到磁盘中,这是默认的工作方式,即参数 innodb_fast_shutdown = 1 。但是对于 Fuzzy Checkpoint 而言,其可能会发生于以下场景。

  • Master Thread Checkpoint

MasterThread 每个1s或者10s就会执行一次 Checkpoint,刷新一定比例的脏页到磁盘中,此操作是异步的。

  • Flush LRU List Checkpoint

InnoDB 存储引擎需要保证有100个空闲页可用,当没有100个空闲页可用时候,会将 LRU 列表尾部数据移除,此时就会需要 Checkpoint。

  • Async/Sync Flush Checkpoint

  • Dirty Page too much Checkpoint

当缓冲池中脏页太多的时候,超过一定的比例的时候会强制执行Checkpoint,这个比例在参数 innodb_max_dirty_pages_pct 定义,比如下面的数据显示,当脏页数据超过整个 LRU 列表的 90% 的时候回强制 Checkpoint。

mysql> show variables like 'innodb_max_dirty_pages_pct';
+----------------------------+-----------+
| Variable_name              | Value     |
+----------------------------+-----------+
| innodb_max_dirty_pages_pct | 90.000000 |
+----------------------------+-----------+
1 row in set (0.01 sec)


  相关解决方案