【高并发高性能高可用之海量数据MySQL实战-7】-内存数据落盘

WAL要求数据的变更写入到磁盘前,首先必须将内存中的日志写入到磁盘;当一个事务提交时,所有产生的日志都必须刷新到磁盘上,如果日志刷新成功后,缓冲池中的数据刷新到磁盘前数据库发生了宕机,那么重启时,数据库可以从日志中恢复数据。这种方法提高了数据写入的效率,同时也形成了内存脏页。脏页最终还是需要写入磁盘的,于是InnoDB采用了 checkpoint机制 实现数据最终的持久性。 

1.脏页落盘简介

思考一下这个场景:如果重做日志可以无限地增大,同时缓冲池也足够大,那么是不需要将缓冲池中页的新版本刷新回磁盘。因为当发生宕机时,完全可以通过重做日志来恢复整个数据库系统中的数据到宕机发生的时刻。

但是这需要两个前提条件:

1. 缓冲池可以缓存数据库中所有的数据;

2. 重做日志可以无限增大

因此Checkpoint(检查点)技术就诞生了,用来解决脏页落盘问题。

LSN(log sequence number) 用于记录日志序号,它是一个不断递增的 unsigned long long 类型整数。在 InnoDB 的日志系统中,LSN 无处不在,它既用于表示修改脏页时的日志序号,也用于记录checkpoint。通过LSN可以具体的定位到其在redo log文件中的位置。为了管理脏页,在 Buffer Pool 的 每个instance上都维持了一个flush list,flush list 上的 page 按照修改这些 page 的LSN号进行排序。因此在定期做redo checkpoint时,就可以快速找到flush list 上最老的那个page(拥有最小的LSN)。

由于采用WAL的策略,每次事务提交时需要持久化 redo log 才能保证事务不丢。而延迟刷脏页则起到了合并多次修改的效果,避免频繁写数据文件造成的性能问题。

LSN可以通过命令 SHOW ENGINE INNODB STATUS 来观察: 

mysql> show engine innodb status \G

 Checkpoint发生的时间、条件及脏页的选择等都非常复杂。而Checkpoint所做的事情无外乎是将缓冲池中的脏页刷回到磁盘,不同之处在于每次刷新多少页到磁盘,每次从哪里取脏页,以及什么时间触发Checkpoint。 

2.checkpoint 机制进行落盘

在InnoDB存储引擎内部,有两种Checkpoint,分别为: Sharp Checkpoint 、 Fuzzy Checkpoint

1.sharp checkpoint

1.概述

即同步数据落盘,会阻塞写操作,影响系统的吞吐量。checkpoint范围内的所有的页面落盘的时间都是相同的即所有写操作完成之后此checkpoint才会完成。产生sharp checkpoint的时机:

1. 关闭数据库的时候,将buffer pool中的脏页全部刷新到磁盘中。

2. 日志文件写满,后续操作的日志无法写入,需要将一部分日志文件空间腾出来。

3. buffer pool的使用量超过90%时执行sharp checkpoint。

2.总结

sharp checkpoint:强制落盘。阻塞写操作,需要把所把本次 checkpoint 的所有的脏页写入磁盘才算完成。

①关闭数据库时

②当 redo log 写满时,当 redo log 的使用量超过 90%。

③buffer pool 中的脏页超过 90%时

2.fuzzy checkpoint

异步数据落盘,本次checkpoint范围内的数据页的落盘时机点可能不同。不会影响系统的吞吐量。目的也是为了避免产生sharp checkpoint造成的性能问题。

1.缓冲池定时Checkpoint

当脏页的百分比达到由 innodb_max_dirty_pages_pct_lwm 变量定义的低水位线值时,将启动缓冲池刷新。默认低水位线为缓冲池页的 10%。并防止脏页数达到 innodb_max_dirty_pages_pct 变量(默认值为 90)定义的阈值。 如果缓冲池中脏页的百分比达到 innodb_max_dirty_pages_pct 阈值后,则会执行sharp checkpoint刷新缓冲池页。在MySQL 8.0中,缓冲池刷新由页面清理器线程执行。页面清理程序线程数由 innodb_page_cleaners 变量控制,该变量的默认值为 4。但是,如果页面清理程序线程数超过缓冲池实例数将自动设置为与缓冲池数量相同的值。

清理线程每秒执行一次,扫描的范围为线程池链表末端的一段距离,扫描的范围由参数innodb_lru_scan_depth 参数控制,默认为 1024 ,所以每次扫描的范围为: 

缓冲池的数量(8) * 扫描的长度(1024)

即:

innodb_buffer_pool_instances * innodb_lru_scan_depth 

2.Adaptive Flushing Checkpoint

自适应刷新算法根据redo log生成的速度和当前的刷新频率动态调整。其目的是通过确保刷新活动与当前工作负载保持同步来平滑整体性能。自动调整刷新速率有助于避免在缓冲池刷新导致的 I/O 活动突发影响可用于普通读写活动的 I/O 容量时,吞吐量突然下降。自适应刷新算法通过跟踪缓冲池中的脏页数和生成重做日志记录的速率来帮助避免这种情况。根据此信息,它决定每秒从缓冲池中刷新多少脏页,从而适应工作负载的突然变化。从而确保重做日志利用率不会达到 75%(达到75%后会启动异步刷新,此处为硬编码无参数控制)

innodb_adaptive_flushing_lwm 变量为重做日志容量定义低水位线。超过该阈值时,将启用自适应刷新。

3.Async/Sync Flush Checkpoint

Async/Sync Flush checkpoint是在单独的page cleaner线程中执行的。

Async/Sync Flush checkpoint 发生在重做日志不可用的时候,将buffer pool中的一部分脏页刷新到磁盘中,在脏页写入磁盘之后,事务对应的重做日志也就可以释放了。

关于redo_log文件的的大小,可以通过 innodb_log_file_size 来配置。

对于是执行Async Flush checkpoint还是Sync Flush checkpoint,由 checkpoint_age 以及async_water_mark 和 sync_water_mark 来决定。

##即checkpoint_age等于最新的lsn减去已经刷新到磁盘的lsn的值 

checkpoint_age = redo_lsn-checkpoint_lsn 

async_water_mark = 75%*innodb_log_file_size 

sync_water_mark = 90%*innodb_log_file_size

1. 当 checkpoint_age<async_water_mark 的时候,无需执行Flush checkpoint。也就说,redo log剩余空间超过25%的时候,无需执行Async/Sync Flush checkpoint。

2. 当 async_water_mark<checkpoint_age<sync_water_mark 的时候,执行Async Flush checkpoint,也就说,redo log剩余空间不足25%,但是大于10%的时候,执行Async Flush checkpoint,刷新到满足条件1

3. 当 checkpoint_age>sync_water_mark 的时候,执行sync Flush checkpoint。也就说,redo log剩余空间不足10%的时候,执行Sync Flush checkpoint,刷新到满足条件1。 在mysql 5.6之后,不管是Async Flush checkpoint还是Sync Flush checkpoint,都不会阻塞用户的查询进程。 

由于磁盘是一种相对较慢的存储设备,内存与磁盘的交互是一个相对较慢的过程

由于innodb_log_file_size定义的是一个相对较大的值,正常情况下,由前面两种checkpoint刷新脏页到磁盘,在前面两种checkpoint刷新脏页到磁盘之后,脏页对应的redo log空间随即释放,一般不会发生Async/Sync Flush checkpoint。同时也要意识到,为了避免频繁低发生Async/Sync Flush checkpoint,也应该将innodb_log_file_size配置的相对较大一些。

4.Dirty Page too much

Dirty Page too much 意味着buffer pool中的脏页过多,执行checkpoint将脏页刷入磁盘,保证buffer pool中有足够的可用页面。Dirty Page 由 innodb_max_dirty_pages_pct 配置,innodb_max_dirty_pages_pct 的默认值是90,以前是75增加的默认值允许缓冲池中脏页的百分比更大。InnoDB尝试从缓冲池中刷新数据,以便脏页的百分比不超过此值。

5.总结

fuzzy checkpoint:模糊落盘,不会阻塞写操作,本次 checkpoint 的脏页不要求同一时刻写入磁盘。

①buffer pool 中的脏页超过 10%时,启动定时落盘机制,每秒执行一次检查。检查的范围是每个缓冲池中 lru 列表后 1024 个页面。

②自适应 checkpoint:检查 redo log 文件,根据落盘的频率和 redo log 的使用量,动态调整落盘的数据页。保证 redo log 的使用量不大于 75%。

③当 redo log 的使用量超过 75%时,会触发一个 fuzzy checkpoint。

脏页落盘后,对应的 redo log 需要删除的。

3、Double Write脏页双写落盘

双写过程

①先把要落盘的脏页向双写缓冲区写一份

②然后再将脏页写入对应的数据文件中。

保证数据写入过程中的安全性。

如果说Insert Buffer给InnoDB存储引擎带来了性能上的提升,那么Double Write带给InnoDB存储引擎的是数据页的可靠性。

 双写缓冲区是一个存储区域,在该区域中,先从缓冲池中刷新页,然后再将页写入数据文件中的正确位置。如果操作系统在将页写入磁盘的过程中发生了崩溃,在恢复过程中,InnoDB存储引擎可以从共享表空间中的double write中找到该页的一个副本,将其复制到表空间文件中,再应用重做日志。 

如果您觉得文章好看,欢迎点赞收藏加关注,一连三击呀,您的肯定是我持续输出的动力,感谢!!☺☻ 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不要迷恋发哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值