1

1. 事务概述

  • 事务执行中要么都修改,要么都不修改,这是事务模型与文件系统重要区别之一。
  • innodb引擎都事务完全符合ACID特征:

    1. 原子性(Atomicity,或称不可分割性)

      • 事务中的所有操作均为一个整体,要么全部成功,要么有一条执行失败后回滚到事务前的状态。通过redo log实现。
    2. 一致性(Consistency)

      • 事务是一致性的单位,如果事务中某个动作失败了,系统可以撤销事务,返回初始状态。通过undo log实现。
      • 例如表中name字段是唯一约束,事务提交后或发生回滚后,name变得不唯一了,这就是破坏了一致性要求。
    3. 隔离性(Isolation)

      • 隔离性要求每个读写事务的对象对其他事务对操作对象都是相互分离的,通常用锁来实现。
      • 通过各种锁来配合实现不同级别都隔离性。例如行锁,间隙锁等。
    4. 持久性(Durability)

      • 事务一旦commit成功,结果就是永久性的。即使发生宕机也能将数据恢复。但外部原因除外。是通过redo log来实现的。

2. 事务分类

扁平事务

  • 所有事务处于同一层次。其操作都是原子性,要不全部成功,要不全部失败。

带有保存点的扁平事务

  • 除了支持扁平事务支持的操作外,为事务几个过程设置保存点,允许回滚到事务中较早的某个节点。
  • 对于扁平事务来说,其隐式设置了一个起始保存点。因此只能回滚到事务开始时的状态。
  • 保存点用SAVE WORK函数建立,保存点在事务内部是递增的,根据应用逻辑选择回到哪个保存点。

链事务

  • 保存点是非持久化都,当系统崩溃时,所有保存点都将消失,当进行恢复时,事务需要重新开始执行。
  • 链事务思想:T1事务提交时,把必要处理都上下文隐式传给T2事务,以此类推。这意味着下一个事务能看到上一个事务的执行结果。
  • 链事务只能保证回滚到最近的一个保存点。

嵌套事务

  • 由若干事务组成一颗事务树,子树可以是嵌套事务也可以是扁平事务。
  • 处于根节点的是顶层事务, 一个顶层事务控制着各个层次的子事务。
  • 处在叶子节点的是扁平事务,每个子事务的从根到叶子节点的距离可以不同。
  • 子事务可以commit或rollback,但是commit并非立即生效,除非父事务已经commit,故任何子事务都在顶层事务提交完毕后才真正提交。
  • 树的任意一个事务回滚会导致它所有的子事务一起回滚。故子事务仅保留ACI特性,不具备D特性。
  • 在Moss理论中,只有叶子节点的事务才能完成访问数据库,发送消息等操作。高层事务仅负责逻辑调度控制,决定何时调用相关等子业务。

分布式事务

  • 通常是在一个分布式环境下运行的扁平事务。

3. 事务实现

概述:事务的隔离行是由锁来实现的。原子性,一致性和持久性是通过redo log和undo log实现的。redo log称为重做日志。用来保证事务的原子性和持久性。undo log用来保证事务的一致性。redo是物理日志,记录的是页的物理修改。undo是逻辑日志,根据每行记录进行记录,可以回滚行记录到某个版本。

3.1 redo

  1. 概述

    • 重做日志用来实现事务的持久性,由两部分组成,一个是内存中的重做日志缓冲(redo log buffer),另一个是重做日志文件(redo log file)这是持久性的。redo log基本上都是顺序写的,数据库运行时不需要进行读取操作。
  2. 与binlog比较

    1. 产生层面

      • binlog产生于mysql数据库上层,不针对innodb引擎。
      • redolog产生于innodb引擎层,是innodb特有的日志。
    2. 内容形式

      • binlog是一种逻辑日志,记录的的是对应的sql语句。
      • redolog是物理格式的日志,记录的是对每个页的修改。
    3. sync时间点

      • binlog只在事务commit完成后写入一次。
      • redolog在事务进行中不断被写入。
  3. log block

    • 概述:innodb中,redolog都是以512字节进行存储的。这意味着redo log buffer和redo log file都是以块(block)进行存储的。由于重做日志块大小和磁盘山区都是512字节,所以写入都是原子性的,不需要double write技术。
  4. LSN

    1. 概述:LSN(Log Sequence Number)代表的是日志序列号。在innodb引擎中LSN占8个字节,并且单调递增。
    2. 含义:

      1. 重做日志的写入总量,单位为字节

        • 例如LSN数值为1000,T1写入100字节,则变为1100,T2写入200字节则变为1300,以此类推,代表着redolog的写入总量。
      2. checkpoint的位置

        • 通过单调增的LSN作为版本号来判断checkpoint点。
      3. 页的版本

        • LSN不仅存在于redolog中,也存在于每个页的头部,页头部的FIL_PAGE_LSN值记录了该页的LSN,在页中LSN表示该页最后刷新时的LSN大小。可以通过LSN判断页是否需要进行恢复操作。
  5. 恢复

    • 概述:innodb引擎无论上次数据库是否正常关闭,都是尝试进行恢复,由于checkpoint已经刷新到磁盘页上到LSN,因此恢复过程中,只需要恢复checkpoint开始到日志部分。

3.2 undo

  1. 作用:

    1. undo为事务回滚提供支持,存放于数据库内部的一个特殊段(segment)内,这个段称为undo段,位于表共享空间内。undo是逻辑日志,因此只是将数据逻辑的恢复到原来到样子,所有修改都被逻辑地取消了。例如对于每一个insert,innodb引擎会完成一个delete,对于每个update也有相反的update。
    2. undolog为mvcc作数据支持,当用户读到一行被事务占用的记录时,可以通过undolog实现非锁定读取
    3. undolog也会产生redolog,undolog也需要持久性保护。
  2. undo 存储管理

    • innodb引擎有rollback segment,每个回滚段记录了1024个undolog segment,undo页在undolog segment里申请。
    • 事务提交时,将undo log放入列表中,以供purge操作。同时判断undo log的页是否可以重用,如果可以分配给下个事务使用。
    • 事务提交后并不会马上删除undo log及所在的页,因为其他事务可能需要通过undo log页拿到行记录之前的版本,是否可以删除需要purge线程来判断。
    • 若为每一个事务都分配一个undo页,空间浪费严重,故undo页是可以重用的,有可能出现一个undo页里存储不同事务的undo log,故purge操作需要涉及磁盘的离散读,是一个缓慢的过程。
  3. undo log 格式

    1. insert undo log格式

      • insert undo log记录的是所有插入数据,因为insert操作的记录只对本事务可见,故在事务commit后不需要purge操作,直接删除。
    2. update undo log格式

      • update undo log记录的是delete和update操作的数据,该undolog可能需要提供对mvcc的支持,提交时放入undolog链表,等待purge线程删除。

3.3 purge

  • purge用于完成delete和update中delete的最终操作。

3.4 group commit

  1. 概念

    • 若事务为非只读事务,则每次事务提交都需要一次fsync操作,因此保证重做日志都写入磁盘。为了提高fsync性能,数据库提供了group commit功能,即一次刷新确保多个事务日志写入文件。
  2. BLGC Binary Log Group Commit

    • 开启binlog后,为了保证引擎层的事务和二进制文件的一致性,二者之间使用了二阶段事务。BLGC使用了一种leader-follower的方式,将事务提交氛围Flush,Sync,Commit三个过程。

4. XA事务

5. 事务控制语句

6. 事务隔离级别

7. 分布式事务


nothingnodust
16 声望2 粉丝

代码界的蔡徐坤