两次写特性能加强MySQL的可靠性。在脏页写入到表之前,先将一份副本写入硬盘,成功之后再写入表。
这样做的目的是预防脏页写入表时,发生最坏情况(例如:掉电),导致页损坏。也就是说至少部分数据无法读取。
两次写避免了这个问题。当最坏情况发生,服务重新启动时,系统检测页发生了损坏,那么会读取两次写的副本来恢复损坏的页。这样的系统更加可靠。
redo log是当脏页写入前,先写入到redo日志。当发生掉电时,缓存内的部分脏页会丢失,在系统恢复后,将从redo log中恢复缓存未写入磁盘的数据。
这看起来两者有点相似,再掉电后都有恢复数据的功能。不过两者的功能还是有较大区别。
两次写所存储的数据较小,它的重点是预防马上要写入的数据页,在故障中损坏后的恢复。也就是说重点是修复物理存储介质上损坏的数据页。
redo log重点是故障中,缓存脏页未能写入磁盘的数据,能通过redo log得以完整写入到磁盘。
两者相结合形成了一个完整的可靠的机制。
如果没有二次写,页损坏了,redo log中可能已经不包含这部分内容,数据就不完整了。
如果没有redo log,损坏的页虽然恢复正常,但是缓存脏页未能及时写入的数据则无法找回,数据也不完整。
两者相结合,完整的流程如下:
发生掉电故障后,系统重启恢复。如果检查页受损,那么调用两次写的副本恢复损坏的页。之后读入redo log将未写入的脏页写入到磁盘。