zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

了解MySQL的Flush-List吗?顺便说一下脏页的落盘机制!

mysqlList 机制 了解 一下 Flush
2023-09-27 14:25:58 时间
今天我要跟你分享的MySQL话题是:“了解Flush-List吗?顺便说一下脏页的落盘机制!(文末送书)” 本文是MySQL专题的第 8 篇,共110篇。

Hi 大家好 我是白日梦

今天我要跟你分享的MySQL话题是 “了解Flush-List吗 顺便说一下脏页的落盘机制 文末送书 ”

本文是MySQL专题的第 8 篇 共110篇。


一、回顾#

现在稍微回顾一下 前面几篇文章介绍了LRU List、Free List。

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中数据描述信息组织而成的双向链表。

image


一旦你对内存中的缓冲页作出了修改 那该缓冲页对应的描述信息块就会添加进 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的特性 建议禁用该参数。


六、推荐阅读#

1、谈谈MySQL中基数是什么

2、聊聊什么是慢查 如何监控 如何排查

3、对Not Null字段插入Null值有啥现象

4、能谈谈year、date、datetime、time、timestamp的区别吗

5、你有没有搞混查询缓存和Buffer Pool 谈谈看

6、你知道数据库缓冲池中的LRU-List吗

7、了解InnoDB的FreeList吗 谈谈看


参考

https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html

https://dev.mysql.com/doc/refman/5.7/en/innodb-buffer-pool-flushing.html

https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_lru_scan_depth

《MySQL技术内幕》



推荐阅读#大家常说的基数是什么 已发布 讲讲什么是慢查 如何监控 如何排查 已发布 对NotNull字段插入Null值有啥现象 已发布 能谈谈 date、datetime、time、timestamp、year的区别吗 已发布 了解数据库的查询缓存和BufferPool吗 谈谈看 已发布 你知道数据库缓冲池中的LRU-List吗 已发布 谈谈数据库缓冲池中的Free-List 已发布 谈谈数据库缓冲池中的Flush-List 已发布 了解脏页刷回磁盘的时机吗 已发布 用十一张图讲清楚 当你CRUD时BufferPool中发生了什么 以及BufferPool的优化 已发布 听说过表空间没 什么是表空间 什么是数据表 (已发布)谈谈MySQL的 数据区、数据段、数据页、数据页究竟长什么样 了解数据页分裂吗 谈谈看 (已发布)谈谈MySQL的行记录是什么 长啥样 (已发布)了解MySQL的行溢出机制吗 (已发布)说说fsync这个系统调用吧! (已发布)简述undo log、truncate、以及undo log如何帮你回滚事物! (已发布)我劝 这位年轻人不讲MVCC 耗子尾汁 (已发布)MySQL的崩溃恢复到底是怎么回事 (已发布)MySQL的binlog有啥用 谁写的 在哪里 怎么配置 (已发布)MySQL的bin log的写入机制 (已发布)



MySQL 深潜 - MDL 锁的实现与获取机制 # 背景 为了满足数据库在并发请求下的事务隔离性和一致性要求,同时针对 MySQL 插件式多种存储引擎都能发挥作用,MySQL 在 Server 层实现了 Metadata Locking(MDL)机制。达到的效果比如可以在事务访问数据库的某种资源时,限制其他并发事务删除该资源。这是一种逻辑意义上的锁,与操作系统内核提供的有限种类 mutex 不同,MDL 可以灵活自定义锁的对象、锁的类型以及不同