| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> Log、Mini Transaction与ARIES Recovery -> 正文阅读 |
|
[大数据]Log、Mini Transaction与ARIES Recovery |
文章目录逻辑日志与物理日志
redo log为什么使用物理日志?Logical log 只能作用于 Operation Consistency 的数据上。如果磁盘上的数据只反映了一些操作的部分更新,它就不是 Operation Consistency 的。例如 Insert 一个 Tuple 导致一个 Index Page 发生了 Split,这个 Index Page 上的一半数据会被挪到另一个新的 Index Page 上。Logical Log 只会记录我们 Insert 了一个 Tuple,不会记录这两个 Page 上的细节变化。如果数据库挂掉时这两个 Index Page 只有一个刷盘了,我们仍然按照 Logical Log 来 Redo,最终的数据是什么样的,就不知道了。 那Physical log怎么处理上述问题呢?mini-transaction!mtr + redolog可以保证Operation Consistency。 undo log为什么使用逻辑日志?Logical Undo是可以正常使用的,因为redo log +mini-transaction保证了数据库的数据始终是Operation Consistency的。 Undo 应该采用 Logical 的方式(Logical Undo) 而不是 Page-Oriented 的方式(Page-Oriented Undo)。原因有两点:
Mini TransactionMini transaction(简称mtr)是InnoDB对物理数据文件操作的最小事务单元,用于管理对Page加锁、修改、释放、以及日志提交到公共buffer等工作。一个mtr操作必须是原子的,一个事务可以包含多个mtr。每个mtr完成后需要将本地产生的日志拷贝到公共缓冲区,将修改的脏页放到flush list上。 mini-transaction遵循以下三个协议:
Mysql中所有的事务在innodb存储引擎内部都是通过mini transaction完成的,将一个事务划分成多个mini transaction的依据是 : 每条语句都作为一个mini transaction来执行(不确定)。 虽然,innodb将事务划分成了多个mini transaction,但是mini transaction和mysql中的事务并不一样。根据事务应该具有的ACID特性,事务是用来保证整个数据库中数据的ACID而存在的;但是mini transaction是mysql内部的对底层page的一个原子操作,保证并发事务操作下以及数据库异常时page中数据的一致性,主要用于innodb redo log 和 undo log写入,保证两种日志的ACID特性。事务对于数据一致性和持久性的保证在Innodb存储引擎内部是通过mini transaction来实现的。 所有对页的操作都要在mini_transaction中执行。在一个mini-transaction操作中,需要对对应的page加锁。锁中代码逻辑主要就是操作页,然后生成redo和undolog,完成之后释放锁。 mini transaction虽然是用来保证单个page中数据的一致性,但是mini transaction可能需要修改多个page,那么该mini transaction必须持有多个page的latch,并在操作完成之后,按照获取latch相反的顺序释放latch。 Innodb的重做日志是物理逻辑日志,分为MLOG_SINGLE_REC和MLOG_MULTI_REC两种类型。通过在每条日志头部的type字段设置MLOG_SINGLE_REC_FLAG来标志该mini transaction操作是否只涉及一个page的修改。如果一个mini transaction需要同时维护多个page中数据的一致性,那么其在mini-transaction结束时会额外写入1个字节大小的MLOG_MULTI_REC_END信息,表示该mini-transaction产生了修改多个page的日志。当一个mini-transaction涉及到多个page的修改时,只有读到最后一个0x1F的日志,才应用前面所有的操作,否则丢弃前面所有的操作。 总而言之,mtr就是对多个page进行加锁操作,并在mtr局部缓冲区上生成对应的redo log和undo log。当mtr提交时,才将redo log和undo log拷贝到公共缓冲区(真正的redo、undo log缓冲区),以及对page解锁。其有三个作用:
ARIES Recovery术语● LSN:全称是 Log Sequence Number。它是 Log 的编号,始终单调递增。 ● Log Header:每一条 Log Record 都是由 Log Header 和具体的 Log 数据组成。Log Header 中一般有 Log Size,LSN,Transaction ID,Prev LSN(见下面介绍),LogType(见下面介绍) 等字段。 ● Prev LSN:同一个事务中后一条 Log 会把前一条 Log 的 LSN 记录在 Log Header 的 Prev LSN 字段中,形成一个反向链表,便于 Undo 时逆序回溯事务的 Log。 ● Log Type:一般有事务相关的 Type:Begin,Commit,Abort,End(End 有点特殊,下文会详细介绍);普通 Log(包含 Redo Log,Undo Log 和 CLR(见下面介绍))的 Type:Insert,Update,MarkDelete,ApplyDelete,RollbackDelete 等;Checkpoint Log 的 Type:Checkpoint;为一个文件分配新 Page 的 Type:NewPage。 ● CLR:全称是 Compensation Log Record,中文一般翻译为补偿日志。由于 ARIES 采用 Logical Undo,Undo 操作不是幂等的,不可以重复执行。我们通过为 Undo 操作记录 Redo Log 来物化 Undo 操作,同时记录 Undo 的进展(通过 UndoNextLSN 的实现,见下面介绍),保证已经 Undo 了的操作不会再被 Undo。Undo 产生的这些 Redo Log 就叫做 CLR。此外,CLR 是 Redo-Only 的,不支持 Undo,这一特点保证了 Undo 是有界的,Recovery 期间 Undo 过程中挂掉并不会增加 Undo 的工作量。这就是为什么 ARIES 要「Logging changes during undo」。 ● UndoNext LSN:每条 CLR 中都会记录 UndoNext LSN,用来指示下一条需要 Undo 的 Log 的 LSN。如果 Undo 到一半数据库挂掉后重启,我们在重新执行 Undo 时,只需先取出最后一条 CLR Log 的 UndoNext LSN,就能继续之前的 Undo 工作。 ● Log Buffer:内存中分配的用来临时存放 Log 的一段空间。事务执行期间写 Log 只写到 Log Buffer 中,直到事务提交的时候统一刷盘。这种做法有利于减少磁盘 IO,提升性能。(很方便我们实现 Group Commit 特性,本文不展开。) ● Master Record:磁盘上的一个文件,记录最近一次 Checkpoint Log 的 LSN。它能够帮助我们在 Recovery 期间快速找到最近一次 Checkpoint 的 Log。 ● Flushed LSN:已经刷到磁盘上的 Log 中最大的 LSN。它是一个内存中的变量。 ● Page LSN:对于一个 Page,最近一次更新操作对应的 Log 的 LSN。记录在 Page Header 中。 ● Rec LSN:对于一个 Page,自从上一次刷盘以来,第一次更新操作对应的 Log 的 LSN。 ● Last LSN:每个事务最近一次更新操作对应的 Log 的 LSN。 ● DPT:全称是 Dirty Page Table。记录了所有的 Dirty Page 以及它们的 Rec LSN。它是一个内存中的数据结构。 ● ATT:全称是 Active Transaction Table。记录了所有活跃事务(事务在执行中,还没有提交或回滚)以及它们的状态(Undo Candidate,Committed,下文会介绍)和 Last LSN。它也是内存中的一个数据结构。 ARIES主要思想● WAL with STEAL/NO-FORCE Consistent Checkpoint 的RecoveryConsistent Checkpoint 在执行checkpoint时:
所以checkpoint时,ATT和DPT都为空,即没有活跃事务和脏页。
Fuzzy Checkpoint的RecoveryFuzzy Checkpoint 是一个在线 Checkpoint 方案。Checkpoint 时可能会有并发的活跃事务(ATT 不为空),并且并发事务可能更新了一些 Page(DPT 不为空)。如果此时做 Checkpoint,记录一条 Checkpoint Log,实际上 Redo 的起始位置应该在 Checkpoint Log 之前(DPT 中最小的 Rec LSN),要 Undo 的一些事务的部分 Log 也在 Checkpoint Log 之前(ATT 中所有事务最小的 LSN)。换句话说,我们不能像 Consistent Checkpoint 那样,Recovery 直接从 Checkpoint Log 的位置开始了。如何保证 Recovery 的时候把 Checkpoint Log 之前的 Log 对应的更新操作该 Redo 的 Redo,该 Undo 的 Undo ? ARIES 说,我们做 Checkpoint 的时候把 Checkpoint 时刻的 ATT 和 DPT 一同记录下来不就行了。Checkpoint Log 中记录的 ATT 和 DPT 将作为 Recovery 启动时 ATT 和 DPT 的初始状态,依据初始状态我们可以知道 Checkpoint Log 之前有哪些 Log 需要处理。然后我们从 Checkpoint Log 位置开始执行 Analysis 阶段,重做 ATT 和 DPT 后续的增量改动,恢复出完整的 ATT 和 DPT,接下来不就和 Consistent Checkpoint 一样了么。 如何记录 ATT 和 DPT 呢?方案有一点 Trick。我们可以先对 Log Buffer(新事务和更新操作的 Log 会被延后)加 Latch,接着对 ATT 和 DPT 加 Latch,然后拷贝 ATT 和 DPT 并记录 Checkpoint Log。Checkpoint Log 中记录的是 Checkpint 时刻 ATT 和 DPT 的快照。这种做法的缺点是 Latch 的持有时间有点长,对系统负载影响比较大。实际上我们并不需要拿到 ATT 和 DPT 快照。我们可以把 ATT 和 DPT 分成很多个 Partition,每次只加单个 Partition 的 Latch, 然后拷贝这个 Partition,最终经过多次拷贝我们就能够得到一份完整的 ATT 和 DPT。这种做法 Latch 的持有时间很短,对系统的负载影响很小。拷贝出来的 ATT 和 DPT 相当于某一时刻的快照加该时刻后续的部分增量改动。Analysis 阶段拿着这份 ATT 和 DPT 从这个「某一时刻」开始,重做后续的全部增量改动,Checkpoint 期间拷贝过程中漏掉的增量改动会被重做,已经包含的增量改动也会被重做但不影响正确性,因为增量改动的重做是幂等的。 ARIES 通过记录一条 Checkpoint Begin Log 来明确这个「某一时刻」的位置。
Recovery 的时候,先从 Master Record 中找到 Checkpoint Begin Log 的位置,然后找到 Checkpoint End Log 的位置,恢复出 ATT 和 DPT 的初始状态,接着从 Checkpoint Begin Log 位置开始执行 Analysis 阶段即可。 个人理解: DPT中包含已经提交的事务、未提交的事务、正在回滚的事务的脏页,其都是需要redo的:
所以只需要恢复内存中的ATT和DPT,即可进行redo和undo。
参考: MySQL · 引擎特性 · InnoDB redo log漫游 MySQL · 引擎特性 · InnoDB mini transation |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 1:09:49- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |