数据库日志记录了每一条数据更改操作,以便于数据库发生故障时,从某个起点依次执行这些操作以恢复数据
Undo日志
Undo日志用来回滚事务操作,即回退数据的旧版本,因此在每次数据更改时记录旧值
Undo适用场景
事务提交前发生故障,需要撤回数据修改
如何进行Undo恢复
将所有操作全部撤回到事务开始时的状态,即按 时间倒序 逐条恢复Undo Log中记录的旧值
OUTPUT和COMMIT顺序
OUTPUT先于COMMIT:只要数据未落盘,磁盘数据就维持事务开始状态,此时无需回滚。换句话说,回滚撤销的是已落盘的操作
Redo日志
Redo日志用来重做事务,即将数据从旧版本恢复到新版本,因此在每次数据更改时记录新值
Redo适用场景
一般用于上个检查点之后到故障发生之前这段时间内刷盘成功的事务,从上一个一致性状态恢复到最近的一致性状态
如何进行Redo恢复
故障发生时需要从检查点开始,按 时间正序 逐条恢复Redo Log记录,使数据恢复到故障发生前的最新状态
OUTPUT和COMMIT顺序
COMMIT先于OUTPUT:需要重做的是已提交但未落盘的数据操作
MySQL中的BinLog日志
BinLog日志主要用于备份恢复数据库和主从复制同步,记录的是MySQL写操作的SQL语句。恢复数据时按 时间正序 逐条执行SQL语句。在MySQL中BinLog由Server层实现,而Undo/Redo日志由InnoDB存储引擎实现
日志刷盘和数据刷盘策略
日志刷盘先于数据刷盘,即 FLUSH LOG 先于 OUTPUT
正确性考量:无论数据落盘成功与否均有正确的恢复数据参照
性能考量:可以先将日志落盘,而数据所在缓存块被淘汰时再落盘,降低IO频率提高性能
参考资料
GarciaMolina H, Ullman J D, Widom J. Database Systems: The Complete Book[M]. Second Edition. Pearson, 2013.