doublewrite 是MySQL保证数据完整性的一种机制,doublewrite在磁盘上有一块专门的存储区域,InnoDB 刷脏页到磁盘时,先将页面写到这块专门的存储区,然后再将页面写入到InnoDB数据文件中,因为同一个页面,写了两次,所以称之为double write。
doublewrite虽然加重了磁盘IO的负载,但是能够保证异常场景下的数据完整性。MySQL InnoDB 页面默认大小16KB,操作系统一次写入的块大小默认为4KB,传统的磁盘块大小为512字节,因此MySQL的一个页面要写入到磁盘,需要分批进行写入,分批写入不是原子操作,在写入的过程中,如果发生异常,那么一个16KB的页面,就有可能只有部分数据成功写入到了磁盘,导致页面数据被写乱,也就是出现所谓的页损坏。InnoDB崩溃恢复时,发现页损坏,如果有doublewrite机制,就能从doublewrite存储区拿到完整的页面,顺利执行崩溃恢复过程,从而保证数据完整,避免数据丢失。
MySQL 8.0 doublewrite 改进
在MySQL 8.0.20 版本之前,doublewrite 存储区位于系统表空间,从 8.0.20 版本开始,doublewrite 有自己独立的表空间文件,这种变更,能够降低doublewrite的写入延迟,增加吞吐量,为设置doublewrite文件的存放位置提供了更高的灵活性。
新增的参数:
- innodb_doublewrite_dir,指定doublewrite文件存放的目录,如果没有指定该参数,那么与innodb数据目录一致(innodb_data_home_dir),如果这个参数也没有指定,那么默认放在数据目录下面(datadir)。
- innodb_doublewrite_files, 指定doublewrite文件数量,默认情况下,每个buffer pool实例,对应2个doublewrite文件。
- innodb_doublewrite_pages,一次批量写入的doublewrite页数量的最大值,默认值、最小值与innodb_write_io_threads参数值相同,最大值512。
- innodb_doublewrite_batch_size,一次批量写入的页数量。默认值为0,取值范围0到256。
已有的参数:
- innodb_doublewrite,控制是否启用doublewrite功能。