而今天要讲解的Doublewrite Buffer被MySQL放在官档目录“磁盘结构”中了,但真实情况是Doublewrite Buffer是内存+磁盘的结构。
今天就学习了解一下Doublewrite Buffer是什么?工作原理是怎样的?(PS:英文名:Doublewrite Buffer,翻译成中文:双写缓冲区,缩写:DWB。)
预备知识必知
不同程序的Page大小
操作系统可以看成是一个程序,作为程序而言,都有最小处理单位的说法,我们常见的服务器一般都是Linux操作系统,对应文件系统的页(OS Page)就可以看成是Linux操作系统与文件系统交互的最小单位。可以通过下面的命令来查看:
getconf PAGESIZE
通过结果可以看出,Linux文件系统页(OS Page)的大小是4KB。同样地,MySQL作为一个程序也是有最小交互单位的,即InnoDB Buffer Pool能处理的最小单位,可以通过以下SQL命令查看:
SHOW VARIABLES LIKE 'innodb_page_size';
如图所示,MySQL的页(Page)大小默认是16KB。
不同大小Page的程序在交互过程中会出现什么问题
一般情况下,除了操作系统的页(OS Page)为4KB之外,其余程序的页(Page)都会大于等于操作系统的页大小,比如,Oracle的Page大小为8KB。MySQL的Page大小也可以通过上面innodb_page_size参数指定(<5.6版本时,不可调整;5.6版本时,可自定义为8KB、4KB,但不能调大【调小是为了调高数据对齐概率】;5.7以上,才可以改成32KB、64KB【且最好设置成默认值16KB的整数倍,这是全局选项,无法在MySQL运行过程中动态修改】。说了这么多,其实不用修改,使用默认值即可)。
有点扯远了。我们知道操作系统的页大小和MySQL的页大小了,而且MySQL程序是跑在Linux操作系统上的,所以可以得出一个结论:MySQL将Buffer Pool中一页数据刷入磁盘,要写4个文件系统里的页(也可以说成一个MySQL数据页映射4个系统页)。
Doublewrite Buffer工作原理
Doublewrite Buffer概念
针对上面出现的情况,如何解决这类“页数据损坏”的问题呢?很容易想到的方法是,能有一个“副本”,对原来的页进行还原,这个存储“副本”的地方,就是Doublewrite Buffer。Doublewrite Buffer,它与传统的“Buffer”又不同,它分为内存和磁盘的两层架构。(传统的“Buffer”,大部分是内存存储;而DWB里的数据,是需要落地的)
Doublewrite Buffer工作流程
(Doublewrite Buffer工作流程图)
如上图所示,当有页数据要刷盘时:
第1步:页数据先memcopy到DWB的内存里;
第2步:DWB的内存里的数据页,会先刷到DWB的磁盘上;
第3步:DWB的内存里的数据页,再刷到数据磁盘存储.ibd文件上;
备注:DWB内存结构由128个页(Page)构成,所以容量只有:16KB × 128 = 2MB。
Doublewrite Buffer Q&A环节
Q-1:DWB为什么能解决“页数据损坏”问题呢?
A-1:假设步骤2掉电,磁盘里依然是Page 1、Page 2、Page 3、Page 4的完整数据。只要有页数据完整,就能通过Redo Log还原数据;假如步骤3掉电,DWB磁盘结构里存储着完整的数据。所以,一定不会出现“页数据损坏”问题。同时写了DWB磁盘和Data File,总有一个地方的数据是OK的。
Q-2:为什么叫Doublewrite?
A-2:步骤2和步骤3要写2次磁盘,这就是“Doublewrite”的由来。
Q-3:能够通过DWB保证页数据的完整性,但毕竟DWB要写两次磁盘,会不会导致数据库性能急剧降低呢?
A-3:分析DWB执行的三个步骤:
第1步:页数据memcopy到DWB的内存,速度很快;
第2步:DWB的内存fsync刷到DWB的磁盘,属于顺序追加写,速度也很快;
第3步,刷磁盘,随机写,本来就需要进行,不属于额外操作;
另外,128页(每页16K)2M的DWB,会分两次刷入磁盘,每次最多64页,即1M的数据(所以图中我们的DWB磁盘结构分为了两部分),执行也是非常之快的。综上,性能会有所影响,但影响并不大。
Doublewrite Buffer相关参数和变量
SHOW VARIABLES LIKE 'innodb_doublewrite';SHOW GLOBAL STATUS LIKE '%dblwr%';
参数:innodb_doublewrite
介绍:Doublewrite Buffer是否启用开关,默认是开启状态,InnoDB将所有数据存储两次,首先到双写缓冲区,然后到实际数据文件。
变量:Innodb_dblwr_pages_written
介绍:记录写入到DWB中的页数量。
变量:Innodb_dblwr_writes
介绍:记录DWB写操作的次数。
知识补充
MySQL不同版本间Doublewrite Buffer的差异
上面讲解的内容是基于MySQL 5.7。MySQL 5.6和MySQL 5.7的Doublewrite Buffer结构和参数类似,看下官档中给出的InnoDB体系结构图。
MySQL 5.6:
MySQL 5.7:
从上面的图片对比,可以看出,MySQL 5.6 → MySQL 5.7的InnoDB体系结构变化还是很大的。但是Doublewrite Buffer的结构没有发生变化,DWB磁盘结构的数据都存放在共享系统表空间(System Tablespace-ibdata1)中:
MySQL 8.0中Doublewrite Buffer的变化
MySQL 8.0:
(https://dev.mysql.com/doc/refman/8.0/en/innodb-architecture.html)
同时你会发现涉及Doublewrite Buffer的参数也多了:
SHOW VARIABLES LIKE '%double%';
参数:innodb_doublewrite_batch_size
参数:innodb_doublewrite_dir
参数:innodb_doublewrite_files
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210927_9e4a9c5c-1f25-11ec-ae4b-38f9d3cd240d.png)
#ib_16384_0.dblwr#ib_16384_1.dblwr
参数:innodb_doublewrite_pages
小结
今天理论的知识不是很多,下面简单做一下总结:
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210927_9e5d3ff6-1f25-11ec-ae4b-38f9d3cd240d.png)
![](https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20210927_9e669f38-1f25-11ec-ae4b-38f9d3cd240d.png)
end