转自:http://catkang.github.io/2020/02/27/mysql-redo.html
1.介绍
磁盘数据库为了在保证数据库的原子性(A, Atomic) 和持久性(D, Durability)的同时,还能以灵活的刷盘策略来充分利用磁盘顺序写的性能,会记录REDO(重做/恢复)和UNDO(撤销)日志。
为了取得更好的读写性能,InnoDB会将数据缓存在内存中(InnoDB Buffer Pool),对磁盘数据的修改也会落后于内存,这时如果进程或机器崩溃,会导致内存数据丢失,为了保证数据库本身的一致性和持久性,InnoDB维护了REDO LOG。
修改Page之前需要先将修改的内容记录到REDO log中,并保证REDO LOG早于对应的Page落盘,也就是常说的WAL,Write Ahead Log(提前写日志/预写日志)。
当故障发生导致内存数据丢失后,InnoDB会在重启时,通过重放REDO LOG,将Page恢复到崩溃前的状态。
2.实现
最终REDO会被写入到REDO日志文件中,以ib_logfile0、ib_logfile1…命名,为了避免创建文件及初始化空间带来的开销,InooDB的REDO文件会循环使用,通过参数innodb_log_files_in_group可以指定REDO文件的个数。
REDO日志必须在事务提交前保证落盘,REDO生成到最终落盘的完整过程称为数据库写入的关键路径,其效率也直接决定了数据库的写入性能。
这个过程包括:
- REDO内容的产生,
- REDO写入InnoDB Log Buffer,
- 从InnoDB Log Buffer写入操作系统Page Cache,
- 以及REDO刷盘,
- 之后还需要唤醒等待的用户线程完成Commit。
//原来是这样,好复杂的写入过程。