问题背景
当数据库发生宕机时,Innodb可能正在把内缓冲区中的脏页写到表中,此时假如一个页只写了一部分,则出现部分写失效问题。Innodb使用双写机制(double write)解决部分写失效导致的数据丢失问题。
解决方案
有人会想到可以通过重做日志恢复,但是,重做日志中记录的是对页的物理操作,但如果页本身已经损坏,则重做日志不再起作用。这时,在应用重做日志之前,可以copy一个页的副本,先用副本重放日志,进行重做,这就是双写机制。
内部实现
double write 由两部分组成——内存中的double write buffer(2MB)和物理磁盘上共享表空间中连续128个页(2MB)。
在对缓冲区中的脏页刷盘时,不直接写磁盘,先将脏页复制到内存的double write buffer,然后分两次,每次1MB顺序的写入共享表空间的物理磁盘中,然后马上调用fsync,同步磁盘。此时double write页是连续的,开销不大。
在完成double write页的写入后,再将double write buffer真正写入各个表空间。
如果在某个页真正写盘的时候发生宕机,可以进入恢复过程,从共享表空间中的double write中找到该页的一个副本,将其复制到表空间文件,就可以应用重做日志进行重做了。
参数说明
Innodb_dblwr_pages_written: 共享表空间中double write页的数据量,用户若需要统计数据库在生产环境中写入的数据量,可以根据此参数进行统计。
skip_innodb_doublewrite: 双写功能是否开启
nnodb_doublewrite: 双写功能是否开启
|