学习redo 重做日志

90 阅读3分钟

访问数据之前所需要做的事情

需要把页面的数据 缓存 到 buffer bool 内存中 在真正访问页面之前,需要把在磁盘上的页缓存到内存中的 Buffer Pool 之后才可以访问

事务的持久性 意思是 机器重启或者崩溃,数据还是在磁盘中。 那么就需要把内存 Buffer Pool 的数据 更新到 磁盘上。

问题出现了

  • 刷新一个完整的数据页太浪费了 有时候我们仅仅修改一个页面的1个字节,我们知道一个页面只有 16K。 如果只修改一个字节,就要刷新 16k 的页面到磁盘,那么就会显得很浪费了。

  • 随机IO刷新页面比较慢

一个事务可能涉及到多个语句,那么就会涉及到多个页面,这些页面可能不并不相邻。需要把这些页面更新到磁盘,就需要进行随机IO,那么随机IO 会比 顺序IO 慢很多,尤其是 机械硬盘。 回到我们的初心: 我们只想把修改的记录下来,在系统崩溃的时候,能够还原数据。 所以我们其实没有必要在每次事务提交时就把该事务在内存中修改过的全部页面刷新到磁盘,只需要把修改了哪些东西记录一下就好,比方说某个事务将系统表空间中的第100号页面中偏移量为1000处的那个字节的值 1 改成 2 我们只需要记录一下:

将第0号表空间的100号页面的偏移量为1000处的值更新为 2

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

redo 日志占用的空间非常小

存储表空间ID、页号、偏移量以及需要更新的值所需的存储空间是很小的,关于 redo 日志的格式我们稍后会详细唠叨,现在只要知道一条 redo 日志占用的空间不是很大就好了。

redo 日志是顺序写入磁盘的

在执行事务的过程中,每执行一条语句,就可能产生若干条 redo 日志,这些日志是按照产生的顺序写入磁盘的,也就是使用顺序IO。

redo日志格式

image.png

各个部分的详细释义如下:

  • type :该条 redo 日志的类型。

    在 MySQL 5.7.21 这个版本中,设计 InnoDB 的大叔一共为 redo 日志设计了53种不同的类型,稍后会详细介绍不同类型的 redo 日志。

  • space ID :表空间ID。

  • page number :页号。

  • data :该条 redo 日志的具体内容。