设为首页 加入收藏

TOP

数据库原理 - 序列4 - 事务是如何实现的? - Redo Log解析(续)(一)
2019-09-17 18:52:06 】 浏览:87
Tags:数据库 原理 序列 事务 如何 实现 Redo Log 解析

> 本文节选自《软件架构设计:大型网站技术架构与业务架构融合之道》第6.4章节。 作者微信公众号:
> 架构之道与术。进入后,可以加入书友群,与作者和其他读者进行深入讨论。也可以在京东、天猫上购买纸质书。

## 6.5.5 Redo Log Block结构

Log Block还需要有Check sum的字段,另外还有一些头部字段。事务可大可小,可能一个Block存不下产生的日志数据,也可能一个Block能存下多个事务的数据。所以在Block里面,得有字段记录这种偏移量。
图6-9展示了一个Redo Log Block的详细结构,头部有12字节,尾部Check sum有4个字节,所以实际一个Block能存的日志数据只有496字节。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190412103606585.?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NodW5sb25neXU=,size_16,color_FFFFFF,t_70)
图6-9 Redo Log Block详细结构
头部4个字段的含义分别如下:
Block No:每个Block的唯一编号,可以由LSN换算得到。
Date Len:该Block中实际日志数据的大小,可能496字节没有存满。
First Rec Group:该Block中第一条日志的起始位置,可能因为上一条日志很大,上一个Block没有存下,日志的部分数据到了当前的Block。如果First Rec Group = Data Len,则说明上一条日志太大,大到横跨了上一个Block、当前Block、下一个Block,当前Block中没有新日志。
Checkpoint No:当前Block进行Check point时对应的LSN(下文会专门讲Checkpoint)。

## 6.5.6 事务、LSN与Log Block的关系

知道了Redo Log的结构,下面从一个事务的提交开始分析,看事务和对应的Redo Log之间的关联关系。假设有一个事务,伪代码如下:

start transaction
update 表1某行记录
delete 表1某行记录
insert 表2某行记录
commit

其产生的日志,如图6-10所示。应用层所说的事务都是“逻辑事务”,具体到底层实现,是“物理事务”,也叫作Mini Transaction(Mtr)。在逻辑层面,事务是三条SQL语句,涉及两张表;在物理层面,可能是修改了两个Page(当然也可能是四个Page,五个Page……),每个Page的修改对应一个Mtr。每个Mtr产生一部分日志,生成一个LSN。
这个“逻辑事务”产生了两段日志和两个LSN。分别存储到Redo Log的Block里,这两段日志可能是连续的,也可能是不连续的(中间插入的有其他事务的日志)。所以,在实际磁盘上面,一个逻辑事务对应的日志不是连续的,但一个物理事务(Mtr)对应的日志一定是连续的(即使横跨多个Block)。
图6-11展示了两个逻辑事务,其对应的Redo Log在磁盘上的排列示意图。可以看到,LSN是单调递增的,但是两个事务对应的日志是交叉排列的。
![在这里插入图片描述](https://img-blog.csdnimg.cn/2019041210372321.?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NodW5sb25neXU=,size_16,color_FFFFFF,t_70)
图6-10 事务与产生的Redo Log对应关系
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190412103753967.?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NodW5sb25neXU=,size_16,color_FFFFFF,t_70)
图6-11 两个逻辑事务的Redo Log在磁盘上排列示意图

同一个事务的多条LSN日志也会通过链表串联,最终数据结构类似表6-9。其中,TxID是InnoDB为每个事务分配的一个唯一的ID,是一个单调递增的整数。

表6-9 Redo Log与LSN和事务的关系
![在这里插入图片描述](https://img-blog.csdnimg.cn/2019041210384922.)

## 6.5.7 事务Rollback与崩溃恢复(ARIES算法)

**1.未提交事务的日志也在Redo Log中**
通过上面的分析,可以看到不同事务的日志在Redo Log中是交叉存在的,这意味着未提交的事务也在Redo Log中!因为日志是交叉存在的,没有办法把已提交事务的日志和未提交事务的日志分开,或者说前者刷到磁盘的Redo Log上面,后者不刷。比如图6-11的场景,逻辑事务1提交了,要把逻辑事务1的Redo Log刷到磁盘上,但中间夹杂的有逻辑事务2的部分Redo Log,逻辑事务2此时还没有提交,但其日志会被“连带”地刷到磁盘上。
所以这是ARIES算法的一个关键点,不管事务有没有提交,其日志都会被记录到Redo Log上。当崩溃后再恢复的时候,会把Redo Log全部重放一遍,提交的事务和未提交的事务,都被重放了,从而让数据库“原封不动”地回到宕机之前的状态,这叫Repeating History。
重放完成后,再把宕机之前未完成的事务找出来。这就有个问题,怎么把宕机之前未完成的事务全部找出来?这点讲Checkpoint时会详细介绍。
把未完成的事务找出来后,逐一利用Undo Log回滚。

**2.Rollback转化为Commit**
回滚是把未提交事务的Redo Log删了吗?显然不是。在这里用了一个巧妙的转化方法,把回滚转化成为提交。
如图6-12所示,客户端提交了Rollback,数据库并没有更改之前的数据,而是以相反的方向生成了三个新的SQL语句,然后Commit,所以是逻辑层面上的回滚,而不是物理层面的回滚。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190412103920589.)
图6-12 一个Rollback事务被转换为Commit事务示意图
同样,如果宕机时一个事务执行了一半,在重启、回滚的时候,也并不是删除之前的部分,而是以相反的操作把这个事务“补齐”,然后Commit,如图6-13所示。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190412103941287.)
图6-13 宕机未完成的事务被转换成Commit事务
这样一来,事务的回滚就变得简单了,不需要改之前的数据,也不需要改Redo Log。相当于没有了回滚,全部都是Commit。对于Redo Log来说,就是不断地append。这种逆向操作的SQL语句对应到Redo Log里

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇MySQL系列--4.使用Python3访问数.. 下一篇Oracle截取JSON字符串内容

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目