Innodb Double Write原理

基本原理就是将数据写两份
将Dirty Page刷到磁盘时,先将Page刷到磁盘上的一个区域tablespace,然后择机将Page拷贝到数据文件对应位置。
tablespace是innodb在磁盘上分配的一块区域,包含100个Page。
而每个Page都有自己的checksum,来校验本身数据的正确性。

为什么使用DoubleWrite

是为了处理partial page write。
因为Innodb的page大小是16K,而文件系统写磁盘的单位是一般是4K,所以会出现这个Page的前4K刷到磁盘,而由于机器宕机或是程序退出,而导致Page中的其它数据没有刷到磁盘的情况。即使有raid卡,有电池可以保证机器宕机,也可以有电量支持将数据刷成功,但是当电池电量不足时,会导致出现partial page。

异常情况下的恢复:

恢复时,tablespace中的数据Page校验出错,则直接丢弃。
如果tablespace中的数据Page是正确的,则会将tablespace中的数据Page,刷到实际数据所在的位置

对性能的影响:

在tablespace中写刷Page是顺序写,对性能影响不大。

OceanBase中的应用:

OceanBase每个磁盘都用一个sstable data file用来存储数据,而sstable data file的基本信息记录在SuperBlock中,SuperBlock是整个sstable data file最重要的数据块(2M)。

sstable data file中只有写SuperBlock是replace,其它都是找一个新的空闲数据块来写。
所以在更新SuperBlock时要保证正确性(SuperBlock数据块中的数据是正确的,完整的),可用性(几个备份中,一个备份挂了,可以恢复)
SuperBlock总共有三个备份,放到sstable data file不同的位置。

最初的设计:

方法

写SuperBlock,必须三个super block都写成功才返回成功。启动加载super block时,当三个副本不一致时,直接报错退出。SuperBlock没有块checksum

问题

2M的块刷磁盘并不是原子的,可能出现刷一部分,然后程序或硬件挂掉的情况.
SuperBlock数据块中没有checksum,无法判断这个数据块是否是完整的。当出现三个副本不一致时,无法确定使用哪一个SuperBlock块的数据,只能根据server日志,人工来处理。

改进的设计

方法:每个SuperBlock加上checksum来保证数据的正确性,写入顺序是3,2,1,启动时首先校验checksum,找到checksum正确,并且号码最大的一个SuperBlock,然后将数据同步到其它SuperBlock,如果出现数据块不可读(磁盘出问题)或是三个SuperBlock checksum都不正确,则报错退出,使用工具处理。原理和DoubleWrite是一样的

参考资料:

1)http://www.mysqlperformanceblog.com/2006/08/04/innodb-double-write/
2)http://www.orczhou.com/index.php/2010/02/innodb-double-write/

Comments

2014-08-21