欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MySQL的Flush-List和脏页的落盘机制

程序员文章站 2022-06-27 18:53:41
一、回顾mysql启动后buffer pool会初始化。buffer pool也会初始化好n多个空白的缓存页,以及它们的描述数据会被组织成lru链表以及freelist 双向链表。这时你从磁盘中读取一...

一、回顾

mysql启动后buffer pool会初始化。buffer pool也会初始化好n多个空白的缓存页,以及它们的描述数据会被组织成lru链表以及freelist 双向链表。

这时你从磁盘中读取一个数据页,会先从free list中找出一个空闲缓存页的描述信息,然后将你读出的数据页中加载进缓存页中。同时将缓存页的描述信息从free list中剔除,此外该描述信息块还会被维护进lru链表中。

数据页被加载进buffer pool后你就可以对其进行变更操作了。

二、flush list

为了加快响应客户端的速度,mysql会在buffer pool中对数据进行修改,可是一旦你对lru链表中的缓存页做了修改,那该页中的数据和磁盘中的数据页信息就不一致了!大家一般管这种数据页叫做脏页。

为了保证数据的最终一致性,mysql是需要将脏页刷新回磁盘的!

但是问题是:需要将哪些数据页刷新回磁盘呢?

这就引出了flush list~

flush list 和 free list很像,都是由buffer pool中数据描述信息组织而成的双向链表。

MySQL的Flush-List和脏页的落盘机制

一旦你对内存中的缓冲页作出了修改,那该缓冲页对应的描述信息块就会添加进 flush list。这样当buffer pool中的数据页不够用时,我们就可以优先将 flush list中的脏数据页刷新进磁盘中。

如果你读了前几篇文章那你肯定知道了 lrulist、freelist、flushlist、buffer pool、脏页、脏数据。

下面乘胜追击!一起看一下脏页的落盘机制

三、什么是脏页?什么是脏数据?

什么是脏页?

我在介绍flush list 的那篇文章有提及,脏页就是lru链表中被修改了的缓存页。他们和磁盘中的数据页不一致,脏页是需要被刷新回磁盘的。

什么是脏数据?

这个问题其实引出了脏读的概念。举个例子:事物a中读取到了事物b中未提交的数据,我们管这些数据叫做脏数据。

四、脏页刷回磁盘的时机

当buffer pool不够用时,根据lru机制,mysql会将old sublist部分的缓存页移出lru链表。如果被移除出去的缓存页的描述信息在flush list中,mysql就得将其刷新回磁盘。

innodb存储引擎将脏页刷回磁盘的时机有蛮多的,你可以把它当作拓展知识大概浏览一下。

1、当mysql数据库关闭时,会将所有的脏数据页刷新回磁盘。这个功能由参数:innodb_fast_shutdown=0控制,默认让innodb在关闭前将脏页刷回磁盘,以及清理掉undo log。

2、有一个后台线程master thread会按照每秒或者每十秒的速度,异步的将buffer pool中一定比例的页面刷新回磁盘中。

3、在mysql5.7中,buffer pool的刷新由page cleaner threads完成。

我们可以通过innodb_page_cleaners参数控制page cleaner threads线程的数量,但是当你将这个数值调整的比buffer pool的数量还大时,mysql会自动将 innodb_page_cleaners数量设置为innodb_buffer_pool_instances的数量。
innodb1.1.x之前需要保证lru列表中有至少100个空闲页可以使用。低于这个阈值就会触发脏页的刷新。
从mysql5.6,也就是innodb1.2.x开始,innodb_lru_scan_depth参数为每个缓冲池实例指定page cleaner threads 扫描buffer pool来查找要刷新的脏页的下行距离。默认为1024,该后台线程每秒都会执行一次。
4、当脏数据页太多时,也会触发将脏数据页刷新回磁盘。该机制可由参数innodb_nax_dirty_pages_pct控制,比如将其设置为75,表示,当buffer pool中的脏数据页达到整体缓存的75%时,触发刷新的动作。现实情况是该参数默认值为0。以此来禁用buffer pool早期的刷新行为。

5、当redo log不可用时,也会强制脏页列表中的脏页刷新回磁盘。这个机制同样由一个后台线程完成。

五、其他关于脏页刷新的知识点

刷新临接数据页:意思是当mysql将某脏页刷新回磁盘时,是否也以相同的态度将该脏页邻接的脏页一并刷新回磁盘。

可以通过参数innodb_flush_neighbors控制该过程。

  • 设置为0时表示,禁用刷新邻接的功能。
  • 设置为1时表示,以相同的态度刷新其邻接的脏页。
  • 设置为2时表示,以相同的程度刷新脏页。

那如何选择将其设置为哪种状态呢?

你可以根据mysql实例所在机器的存储类型来决定。如果为hdd存储建议将其开启,因为hdd的磁盘刷新速率较低,开启该参数后可以有效的减少io操作。相反如果使用ssd存储,其本身就有高磁盘io的特性,建议禁用该参数。

以上就是mysql的flush-list和脏页的落盘机制的详细内容,更多关于mysql flush-list和脏页的落盘机制的资料请关注其它相关文章!