聊聊 mysql 事务?(三:从redo log恢复数据)

        上篇文章提到,MySQL为了数据持久性,引入了redo log。那么在系统奔溃后,到底如何做数据恢复的呢?我们现在已经知道MySQL会定期做checkpoint,也就是更新checkpoint_lsn的值,可以理解为redo日志中,当前最大可以被覆盖的lsn值。

        某一时刻下,各重要lsn值对应如下,lsn代表当前已经写入的redo日志量(buffer),flushed_to_disk_lsn代表已经刷盘的日志量,checkpoint_lsn代表当前允许被覆盖的日志量。即得到如下关系:

checkpoint\_lsn \leqslant flushed\_to\_disk\_lsn \leqslant lsn

        现在回到系统奔溃后如何恢复。

        首先就是要找到恢复的起点,checkpoint_lsn之前的redo日志对应的数据页都已经被刷到磁盘上了,那么自然这部分的数据不需要重新恢复了,所以起点是checkpoint_lsn。

        然后就是要找到恢复的终点,我们知道,redo log是以块为单位的,一个block512字节,而且是顺序写入,每个block中的log block header记录了该块的管理信息,其中一个字段LOG_BLOCL_HDR_DATA_LEN属性记录了当前block中使用了多少字节空间,如果这个属性小于512,那么说明后面没有日志了,这个block就是终点。

        最后,redo日志如何恢复数据的呢?redo日志有大大小小几十种类型,需要从物理、逻辑层面上展开来说。

        物理上,绝大多数日志类型都有种通用结构:

  • type:日志类型
  • spaceID:表空间ID
  • page number:页号
  • data:这条redo日志具体内容 

         通过物理结构,我们能够定位到数据发生变化的具体位置了。但是实际上数据恢复没有这么简单,除了修改具体内容以外,可能还要修改 PAGE HEADER , PAGE DIRECTORY等等地方的信息,反正就是:一次数据修改,需要更改的地方非常多。

        因此,从逻辑层面上说,MySQL并不是简单找到数据位置,然后修改;而是针对每种不同的log类型,调用不同的函数。函数里面封装了一系列操作,通过调用这些函数,才可以将页面恢复成系统奔溃前的样子(不仅包括恢复具体数据,还要恢复管理信息,以及其他关联信息等)。

最后总结(持久性)

        MySQL的事务有四大特性,其中之一是持久性,这要求系统奔溃后数据可以被正常恢复。为了保证持久性,引入了redo日志。从性能方面考虑,redo日志先写到buffer区,在适当时机再刷盘到file。从存储方面考虑,为了防止log日志越来越大,MySQL采用了循环写入。为了保证循环写入时,不丢失未持久化的数据,又引入了checkponit的概念,通过checkpoint_lsn可以知道那些日志可以被覆盖。系统奔溃后,又可以通过checkpoint_lsn找到需要被重做的日志起点,以及根据页管理信息找到终点,最后根据每条日志类型不同,调用相关函数恢复数据到系统奔溃前的状态。

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值