0
点赞
收藏
分享

微信扫一扫

108-MySQL(MVCC和undo log)

小a草 2022-04-29 阅读 107

1、MVCC

  • InnoDB的事务隔离级别已提交读和可重复读的底层实现原理:MVCC(多版本并发控制)–》并发的读取方式:快照读
  • InnoDB提供了2种读取操作: 锁定读和非锁定读
  • 锁定读就是读取的时候加锁了(S锁或者X锁)
  • 非锁定读就是读取的时候没有加锁,指的就是MVCC提供的快照读–》依赖底层的undo log回滚日志

事务日志: undo log回滚日志 和 redo log重做日志

ACID,A:原子性,C:一致性,I:隔离性,D:持久性

  • ACD:(依靠 事务日志 保证的)
  • I:(依靠 锁+MVCC 保证的)

undo log回滚日志的主要作用:

  • 事务发生错误时回滚rollback ,回滚日志(数据在更新的时候,把改之前的数据存下来在回滚日志中,目的是为了事务万一出错回滚了或者我们手动回滚的时候,能够把最初的数据在回滚日志中找到)
  • 提供了MVCC的非锁定读(快照读)—》undo log的原理

2、undo log回滚日志

undo log:回滚日志, 保存了事务发生之前的数据的一个版本,用于事务执行时的回滚操作,同时也是实现多版本并发控制(MVCC)下读操作的关键技术。

  • DB_TRX_ID:事务ID
  • DB_ROLL_PTR:回滚指针

在这里插入图片描述
在MVCC下,针对表的所有记录,除了我们能看到的book_id,book_name等存放书籍信息的一张表,如下:
在这里插入图片描述
它还会给这张表添加额外的字段如下:
在这里插入图片描述
我们看到额外添加了3个字段。

1、DB_ROW_ID

  • DB_ROW_ID和MVCC的关系不大,这个是你在创建表的时候,如果没有加主键列,那么InnoDB就给你增加的主键列id,为了区分每一行记录,通过这个id作为主键创建索引树,在B+树的叶子节点上存放一行一行的数据,因为InnoDB的数据和索引是存放在一起的,如果你没有设置主键,它会帮你设置主键。

2、DB_TRX_ID

  • DB_TRX_ID(事务ID) (1002, 1001, 1000),我们在之前经常登录两个窗口session,然后各输入begin;这个意思就是在两个窗口上各开启一个事务,事务开启的请求最终会发到MySQL server上,MySQL server为每1个事务都会分配一个全局的,不冲突的事务ID。(InnoDB存储引擎分配的,因为它才支持事务)
  • 那也就是说,当我这个事务1修改数据的时候,DB_TRX_ID放的就是事务1的ID,同一个事务对这个数据不断改来改去,这个事务ID是不会改变的。

3、DB_ROLL_PTR

  • DB_ROLL_PTR(回滚指针)
  • 我们看到,存放的是地址,这个地址表示的是一个数据的内存的位置,看起来是一个链表,上图中的这个橙色表是最后的成品,那么这个表是怎么变来的呢?

最初的时候表是这样的:
在这里插入图片描述
假设现在有一个事务来更改这条数据了。
这个事务把book_name给更改了。
改成了这个:
在这里插入图片描述
此时数据涉及到修改了,修改的数据存放在当前这个位置,那修改之前的数据存放在哪里?存放在undo log中!

假设最初是 最初给这条数据赋值的事务的ID是1000,回滚指针是空
在这里插入图片描述
现在另一个事务要对数据进行修改:
在这里插入图片描述
对这条数据修改的事务的ID是1020,它的DB_ROLL_PTR指针就指向修改之前的数据(undo log,是写在缓存中的,提高效率
在这里插入图片描述
假设现在1000这个事务又把book_name给更改了
此时之前的这2条数据就是老数据了,都到undo log里面了
在这里插入图片描述

  • MVCC会给我们创建的表增加2个列,一个是事务ID,一个是指向修改前的数据的指针
  • 修改之前的数据都是放在undo log回滚日志当中。
  • 当前数据中是哪个事务ID改的就写哪个事务ID号,DB_ROLL_PTR指针把当前数据和旧数据串成1个链表。从当前行的DB_ROLL_PTR可以访问到旧数据,进行回滚是理所当然的。
    在这里插入图片描述
  • 绿色数据表示当前行的最新修改的数据,是事务1002修改的,从指针DB_ROLL_PTR可以找到undo log找到上次修改数据的是事务1001,从事务1001的数据的DB_ROLL_PTR还可以找到上上次的数据是事务1000修改的。以此类推。

举例讲解

在这里插入图片描述
我们现在对id=7这条记录进行更改。

  • 在MVCC机制下,对这张表增加2列。修改当前数据的事务ID和指向undo log的指针。

我们把id=7的age改为16。如下图所示:
在这里插入图片描述
假如我们增加了1行新数据。
因为新的数据就没有老数据,如下图所示:
在这里插入图片描述

  • 回滚的时候发现是空,就知道是insert增加的数据。回滚的时候执行delete就把这条数据删除了。
  • 如果我们对这条新数据进行修改了,那么这些数据就都跑到undo log中了!

如下图所示:
在这里插入图片描述

MVCC多版本并发控制

  • MVCC是多版本并发控制(Multi-Version Concurrency Control,简称MVCC),是MySQL中基于乐观锁理论实现隔离级别的方式,用于实现已提交读和可重复读隔离级别的实现,也经常称为多版本数据库。
  • MVCC机制会生成一个数据请求时间点的一致性数据快照 (Snapshot), 并用这个快照来提供一定级别 (语句级或事务级) 的一致性读取。从用户的角度来看,好象是数据库可以提供同一数据的多个版本(系统版本号和事务版本号)。
举报

相关推荐

0 条评论