redo日志学习

redo日志是什么?

假设我们在事务提交后发生了某个故障,导致内存中的数据全部失效了,对于刚刚事务在数据库中的操作所做的更改也就跟着丢失了,所以需要这个持久性。一个简单的做法是在事务提交完成之前,把该事务修改的所有页面都刷新到磁盘。不过这个粗暴的做法存在两个问题:

  • 刷新一个完整的数据页太浪费了。对于仅仅修改页面中的一个字节,但是由于innodb是以页为单位来进行磁盘I/O的,也就是说在该事务提交时不得不讲一个完整的页面从内存中刷新到磁盘。一个页面的默认大小是16KB,因为修改了一个字节就要刷新16KB的数据到磁盘上,显然太浪费。
  • 随机I/O刷新起来比较慢。一个事务可能包含很多语句,即使是一条语句也可能修改许多页面,"倒霉催" 的是该事务修改的这些页面可能并不相邻。这就意味着在将来某个事务修改的Buffer Pool中的页面刷新到磁盘时,需要进行很多的随机I/O。随机I/O比顺序I/O要慢,尤其是对于传统的机械硬盘。

再次回到我们的初心:我们只是想让已经提交了的事务对数据库中的数据所做的修改能永久生效,即使后来系统崩溃,在重启之后也能把这种修改恢复过来。所以没必要在每次提交事务时就把该事务在内存中修改过的全部页面刷新到磁盘,只需要把修改的内容记录一下就好。比如,某个事务将系统表空间100号页面中偏移量为1000处的那个字节的值从1改成2,我们只需要进行如下记录:

将系统表空间100号页面中偏移量为1000处的那个字节的值从1更新为2。

这样在事务提交时,就会把上述内容刷新到磁盘中。即使之后系统崩溃了,重启之后只要按照上述内容所记录的步骤重新更新一下数据页,那么该事务对数据库中所做的修改就可以被恢复出来,这样也就意味着满足持久性的要求。
因为在系统因崩溃而重启时需要按照上述内容所记录的步骤重新更新数据页,所以上述内容也称为重做日志(redo log)。我们可以中西结合,将它称为redo 日志。相较于在事务提交时将所有修改过的内存中的页面刷新到磁盘中,只将该事务执行过程中产生的redo日志刷新到磁盘具有下面这些好处。

  • redo日志占用的空间非常小:在存储表空间id、页号、偏移量以及需要更新的值时,需要的存储空间很小。
  • redo日志是顺序写入磁盘的:在执行事务的过程中,每执行一条语句,就可能产生若干条redo日志,这些日志是按照产生的顺序写入磁盘的,也就是顺序io。

redo日志格式

你可能感兴趣的:(mysql事务持久化)