(1)前序:
    在更新Buffer Pool的缓存页之后,必须写一条redo log,这样才能记录下来我们对数据库做的修改,redo log可以保证我们事务提交之后,如果事务中的增删改SQL语句更新的缓存页还没刷到磁盘上去,此时MySQL宕机,那么MySQL重启之后,就可以把redo log重做一遍,恢复出来事务当前更新的缓存页,然后再把缓存页刷到磁盘。redo log的本质是保证事务提交之后,修改的数据绝对不能丢失。

    (2)执行过程:
    执行增删改SQL语句的时候,都是针对一个表中的某些数据执行的,此时的话,首先必须找到这个表对应的表空间,然后找到表空间对应的磁盘文件,接着从磁盘文件里把你要更新的那批数据所在的数据页从磁盘读取出来,加载到Buffer Pool缓存页里。
    接着增删改SQL语句都是针对Buffer Pool中的缓存页去执行更新逻辑,或者插入,删除一条语句。其实更新缓存页的时候,会更新free表,flush表,lru表,然后后台有专门的IO线程,不定时的根据flush链表,lru链表,会把你更新过的缓存页刷新回磁盘文件的数据页里。
    然而如果一个事务里有增删改SQL更新了缓存页,然后事务提交了,结果还没来得及让IO线程把缓存页刷新到磁盘文件,此时MySQL宕机然后内存数据丢失,事务更新的数据丢失了。?也不能每次提交一个事务,就把事务更新的缓存页都刷新回磁盘文件,缓存页刷新到磁盘文件是随机磁盘读写,性能很差。
    46947400_1583895039.jpg

    (3)解决:
    引入redo log机制,你提交事务的时候,绝对是保证缓存页做的修改以日志的形式写入redo log日志文件里去。此时哪怕宕机也没关系,因为重启MySQL后,之前事务更新做过的修改根据redo log在Buffer Pool里重做一遍就可以了,就可以恢复出来当时你事务对缓存页做的修改,然后找时机再把缓存页刷入磁盘文件里。
    这样和直接写入磁盘的区别?
    如果把修改过的缓存页都刷入磁盘,首先缓存页是16KB,数据比较大,而且可能修改了好几个缓存页里的几个字节的数据,不可能把完整的缓存页刷入磁盘,而且缓存页刷入磁盘是随机写磁盘,性能很差,他可能一个缓存页的位置在磁盘文件的一个随机位置,但是如果是写redo log,第一个redo log可能只占据几十字节,就包含表空间号,数据页号,磁盘文件偏移量,更新值,这个写入磁盘速度很快,此外,redo log写日志,是顺序写入磁盘文件,每次都是追加到磁盘文件末尾,速度也很快。
    所以提交事务的时候,用redo log的形式记录做出的修改,性能远远超过刷缓存页的方式,这也可以让你的数据库并发能力更强。

    首先是使用redo log机制避免数据库宕机数据丢失的问题,其次使用redo log日志记录修改的记录,避免直接写磁盘,提升了性能,因为直接写磁盘文件是随机写,而写redo log日志文件是从末尾追加是顺序写。
    41780500_1583895067.jpg