Innodb为啥要刷脏页?

1.名词解释

脏页:当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为“脏页”。

干净页:内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页”。

LSN:称为日志的逻辑序列号(log sequence number),在innodb存储引擎中,lsn占用8个字节。LSN的值会随着日志的写入而逐渐增大。事务中更新操作会产生一个新的LSN。LSN不仅存在于redo log中,还存在于数据页中。

2.产生原因

MySQL有两个重要组成部分,内存和磁盘。

磁盘是永久存储,内存中的数据则有可能丢失。但内存上修改的数据都会记录到redo log,所以即使丢失,也能从redo log中找回。

MySQL的IO特别耗费性能,所以很多操作在内存中进行的,并不立即刷到磁盘。

例如,更新一行数据时

  • 如果内存中不存在该行数据,则从磁盘中找到该行所在的数据页

  • 将整页的数据读入内存(如果change buffer中记录了该页的更改信息,会在内存中进行更新)

  • 在内存中对该行进行更新,整个更新操作完成

这个场景下,内存中的数据和磁盘中的数据已经不一致了,便产生了脏页。

当读取该行数据时,因为内存中的数据是最新的,直接读取内存数据返回,省去读磁盘的时间,提升性能。

3.内存数据和redo log的关系

要明白刷脏页的流程,首先要理解内存中的数据和redo log中数据的关系。

  1. 内存中的数据和redo log中的数据是一致的

  2. 如何判断是否为脏页:

  • redo log中记录了LSN

  • redo log中的checkpoint位于某个LSN,意味着该LSN之前的数据都已写入磁盘

  • 内存中干净页如有修改,修改后该页的LSN大于 checkpoint 的LSN,则在写redo log的同时该页也会被标记为脏页记录到脏页列表

脏页本质是内存数据页跟磁盘数据页内容不一致**。所以内存数据页刷盘或者redo log的checkpoint向后移动,都会将脏页变为干净页。**

图片

4.刷脏页时机


刷脏页(flush)的时机如下:

  1. InnoDB 的 redo log 已满
  • 这时候系统会停止所有更新操作,把 checkpoint 往前推进,以便 redo log 留出空间可以继续写。对checkpoint 移动范围内的日志,对应的所有脏页都 flush到磁盘上
  1. 当需要新的内存页,而内存不够用的时候
  • 淘汰一些内存数据页,空出内存给别的数据页使用。如果淘汰的是“脏页”,就要先将脏页写到磁盘
  1. MySQL 认为系统“空闲”时,见缝插针地找时间,只要有机会就刷一点“脏页”

  2. MySQL 正常关闭时,会把内存的脏页都 flush 到磁盘上

刷盘的脏页的LSN可能比redo log中checkpoint的LSN高,但没有影响,当redo log在“重放”的时候,如果一个数据页已经是刷过的,会识别出来并跳过。

5.刷脏页影响

需要根据不同的时机来看对性能的影响。

空闲和正常关闭情况下,不会太关注性能。所以主要看第一种和第二种情况。

  1. 尽量不要出现redo log写满的情况,一旦发生,所有更新操作都会停止
  • redo log大小需要合理设置
  1. 内存页有三种状态:未使用的、干净页、脏页。当要读入的数据页没有在内存的时候,就必须到缓冲池中申请一个数据页。这时候只能把最久不使用的数据页从内存中淘汰掉:如果要淘汰的是一个干净页,就直接释放出来复用;但如果是脏页呢,就必须将脏页先刷到磁盘,变成干净页后才能复用。如果一个查询要淘汰的脏页个数太多,会导致查询的响应时间明显变长。
  • 合理控制脏页比例

6.控制刷脏页

  1. innodb_io_capacity:合理设置 innodb_io_capacity,这个值告诉innodb可以以多快速度写磁盘。如果系统要刷脏页了,innodb会参考这个值,计算出一个刷脏页的速度。之所以不按照这个值来刷脏页,是因为不能将所有能力全用于刷脏页,耽误处理正常请求。

  2. Innodb会根据现在脏页的比例(可通过 innodb_max_dirty_pages_pct控制)和redo log剩余空间,计算出刷盘速度百分比R,从而计算出刷脏页速度=innodb_io_capacity*R%

所以为防止刷脏页影响性能,要合理设置redo log大小、innodb_io_capacity、innodb_max_dirty_pages_pct。

资料

  1. MySQL45讲

最后

大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)

我的个人博客为:https://shidawuhen.github.io/

图片

往期文章回顾:

  1. 设计模式

  2. 招聘

  3. 思考

  4. 存储

  5. 算法系列

  6. 读书笔记

  7. 小工具

  8. 架构

  9. 网络

  10. Go语言

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序员麻辣烫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值