双写缓冲区(Doublewrite Buffer)是一个存储区,是InnoDB在tablespace上的128个页(2个区),大小是2MB[1]。
版本区别:在MySQL 8.0.20之前,doublewrite缓冲区存储区位于
InnoDB
系统表空间中。从MySQL 8.0.20开始,doublewrite缓冲区存储区位于doublewrite文件中。本文基于MySQL 5.7编写。
操作系统写文件是以4KB为单位的,那么每写一个InnoDB的page到磁盘上,操作系统需要写4个块。如果写入4个块的过程中出现系统崩溃,那么会导致16K的数据只有一部分写是成功的,这种情况下就是partial page write
(部分页写入)问题。
InnoDB这个时候是没法通过redo log来恢复的,因为这个时候页面的Fil Trailer
(Fil Trailer 主要存放FIL_PAGE_END_LSN
,主要包含页面校验和以及最后的事务)中的数据是有问题的。
为此,每当InnoDB将页面写入到数据文件中的适当位置之前,都会首先将其写入双写缓冲区。只有将缓冲区安全地刷新到磁盘后,InnoDB才会将页面写入最终的数据文件。
如果在页面写入过程中发生操作系统或者mysqld进程崩溃,则InnoDB可以在崩溃恢复期间从双写缓冲区中找到页面的完好副本用于恢复。恢复时,InnoDB扫描双写缓冲区,并为缓冲区中的每个有效页面检查数据文件中的页面是否完整。
如果系统表空间文件(“ ibdata文件 ”)位于支持原子写的Fusion-io设备上,则自动禁用双写缓冲,并且将Fusion-io原子写用于所有数据文件。