一、什么叫double wirte
double wirte是为了保证脏页写入硬盘数据一致性设计的,因为mysql最小IO操作单位是页(16KB),而操作系统的块一般是4KB,当我们16KB写入时,当写入了8K的时候,突然断电了,这个页的数据就不完整了,通过redo log恢复也不行,因为redo log恢复必须是针对干净的页。所以就需要double wirte的特性,在硬盘更新数据前,先把页写入double wirte共享表空间进行备份,如果上面的情况发生了,数据就可以从double wirte共享表空间进行恢复。
mysql怎么判断页是否干净,页里面有page header和page Trailer.两个里面的LSN不一样的话就会成不干净页。
下图就是大概的流程,脏页更新数据文件前,先到共享表空间进行存储。
如何利用double write进行恢复
数据恢复有三种情况:
① 脏数据写磁盘成功
这种情况是最常见的,脏页刷磁盘99.9%都会成功,但是即使有0.1失败可能也要做处理,不然数据丢了,数据库就不安全了,没有公司愿意天天提心吊胆的抱着个定时炸弹。刷盘成功,找检查点,redo log前滚、回滚就行了。
② 共享表空间写失败
如果是写共享表空间失败,那么这些数据不会被写到数据文件,数据库会认为这次刷盘从没发生过,MySQL此时会从磁盘载入原始的数据,然后找检查点,redo log前滚、回滚就行了。
③ 脏数据刷数据文件失败
写共享表空间成功,但是写数据文件失败,在恢复的时候,MySQL直接比较页面的checksum,如果不对的话,直接从共享表空间的double write中找到该页的一个最近的副本,将其复制到表空间文件,再应用redo log,就完成了恢复过程。因为有副本所以也不担心表空间中数据页是否损坏。