什么是double write
Double write 由2部分组成,一部分是内存中的double write buffer ,大小为2MB;另一部分是INNODB在 tablespace上的128个页(2个区),大小也是2MB;
使用Double write 的目的:
为了实现数据库的可靠性,详细描述如下:
当INNODB更改数据时,会在buffer_pool中修改数据的page,并将此次更新记录到log file中,这时这个page就会被表示为胀页,等到系统空闲或者buffer_pool不够时,这些胀页会刷新到磁盘上。 但如果某个胀页在刷新时发生了异常情况,如断电。只有一部分被刷新到了磁盘上,这时候被称之为partial page writes发生,这时候INNODB就无法丢失掉没有刷新的数据。
造成该问题的根本原因是因为mysql的page size 和系统的page size不一致。系统在写数据的时候,并不是一次把buffer_pool中的数据写到disk上。当写到一半时掉电,就发生partial page writes.而mysql在恢复的过程中是检查page的checksum,checksum就是pgae的最后事务号,如果找不到这个事务号,就无法恢复。
Double write 就是为了避免partial page的发生
Double write的工作原理
当缓冲池刷新胀页时,并不直接写磁盘,而是会通过memcopy先将胀页拷贝到内存中的double write buffer,之后通过double write buffer再分2次,每次写入1MB到共享表空间,然后马上调用fsync函数,同步到磁盘上,避免缓冲带来的问题,在这个过程中,doublewrite是顺序写,开销并不大,在完成doublewrite写入后,在将double write buffer写入各表空间文件,这时是离散写入。
查看double write 的情况
点击(此处)折叠或打开
mysql> show status like 'innodb_dblw%';
+----------------------------+-----------+
| Variable_name | Value |
+----------------------------+-----------+
| Innodb_dblwr_pages_written | 162553707 |
| Innodb_dblwr_writes | 2334129 |
+----------------------------+-----------+
2 rows in set (0.00 sec)
可以看到2次写入的页面162553707 ,次数是2334129 ,比例是69:1
如果你在系统高峰期观察到这个比例小于64:1,那么你的系统压力就很小
崩溃后的恢复
如果在系统运行中发生崩溃,恢复过程中INNODB将在tablespace中找到修改页的副本,将其 拷贝到表空间文件,再应用重做日志。
如果写doublewrite本身失败,那么这些数据将不会写入到磁盘,INNODB将会从磁盘载入原始的数据,然后通过INNODB的事务日志来计算出正确的数据,再重新写入doublewrite。
如果写doublewrite本身成功,但是写磁盘失败,INNODB直接用buffer写一遍磁盘
恢复的时候,INNODB比较一边checksum,如果不对,执行A。
性能损失
开启double write大概损失5-10%的性能。
禁用double write
有多台从服务器,为了提供更快的数据服务,或者有些文件系统本身就提供了防止写失效的功 能,比如(ZFS文件系统)那么我们可以关闭double write
Skip_double_write=1