Ⅰ、Double Write介绍
为了保证数据写入的可靠性,InnoDB引入了double write特性
1.1 partial write
InnoDB默认一个页的大小是16k,如果一个页没有写完整出现故障,这种页叫做corrupt page,这种情况叫partial page write。
InnoDB崩溃恢复,redo恢复数据的前提是页是完整干净的,corrupt page不恢复又会造成写入丢失,怎么办?
1.2 double write原理Double_Write
Double Write由两部分组成,一部分在磁盘上,存在于ibdata1中的一个段对象,这个段由两个区(每个1M)组成,另一部分在内存中,叫double write buffer,也是2M,大小固定,不支持调整。
缓冲池中的页落盘时,不直接写入对应的ibd文件中,第一步是先拷贝到double write buffer中,再先从double write buffer中写入double write段对象(2M循环,顺序io一次),成功写满2M也就是128个页后,再根据(space,page_no)写入对应ibd(随机io)。
如果写double write时发生crash,此时ibd是干净的,服务启动后通过redo进行恢复,如果写ibd时发生crash,此时double write中存在副本,可以直接覆盖到ibd中对应的页中,然后再继续redo恢复。
总之,double write和ibd中总有一份干净的内容,类似于raid1的机制。
Ⅱ、Double Write性能开销
假设每个页16k,2M的double write中存放128个页,开启double write后,io从原来的128次io变成了128 + 1次,而不是128 + 128次
原因是,double write的2M数据是顺序写入的,是一次io,只是这个io大小是2M。
一般来说,开启double write的性能会降低5%~25%的样子,io bound场景下降最严重。
但还是建议使用double write来保证数据写入的可靠性,不管主库还是从库。
Ⅲ、什么情况下可以关闭Double Write
innodb_doublewrite参数控制是否打开double write,默认开启状态。
支持原子写的设备可以关闭double write
1、磁盘
Fusion-IO
宝存
2、文件系统
zfs
btrfs 使用copy on write机制,不进行原地更新,而是开辟新位置,写成功后释放原来的页,本质上也是副本思路
linux中上面两种文件系统基本是用不下去的,所以还是建议使用double write特性。