首页 > 数据库 >Mysql的MVCC机制

Mysql的MVCC机制

时间:2022-12-08 21:11:24浏览次数:42  
标签:事务 log Read MVCC undo Mysql 机制 id

MVCC

Multi Version Concurrency Control的简称,代表多版本并发控制,实现非锁定一致性读

概念:

??非锁定读??快照读(查询的行执行删除或修改操作,则读取快照数据,(历史数据),)多版本控制??锁定读 ???select ... lock in share mode:对记录加 S 锁,其它事务也可以加S锁,如果加 x 锁则会被阻塞? S锁和X锁??? Read View :判断可见性,即其他事务对当前事务是否可见。 Next-key-Lock???
purge 操作?
通过 undo log 读取之前的版本数据,以此实现非锁定读,对同一个数据行的修改,最终undo log记录会形成一个链表,表头就是最新版本记录(ReadView+可读性算法分析时就是根据这个链表所记录的事务id 和 当前事务的id进行比较从而确认读取哪个历史记录)

一致性非锁定读&&锁定读

一致性非锁定读:

通常的做法是: 在每一行记录添加一个隐藏的版本号或时间戳,更新时该行的版本号+1(或时间戳改变),读取时,当前可见的版本号对应记录的版本号进行比对,如果记录的版本小于可见版本,则表示该记录可见。
在RC和RR两个隔离级别的情况下,select(不包括 select ... lock in share mode ,select ... for update)会默认使用MVCC机制。

锁定读:锁定读的语句:
  • insert、update、delete 操作
  • select ... for update 、select ... lock in share mode

InnoDB对MVCC的实现:

MVCC 的实现依赖于:隐藏字段、Read View、undo log。隐藏字段中的DB_TRX_ID和ReadView实现当前数据是否对事务可见,如不可见,则通过数据行的 DB_ROLL_PTR 找到 undo log 中的历史版本。

隐藏字段:
DB_TRX_ID: 表示最后一次插入或更新该行的事务 id。此外,delete 操作在内部被视为更新,只不过会在记录头 Record header 中的 deleted_flag 字段将其标记为已删除DB_ROLL_PTR: 回滚指针,指向undo logDB_ROW_ID: 如果没有主键和唯一非空索引时会自动创建,并使用该id生成聚簇索引

Read View结构:

class ReadView {
  /* ... */
private:
  trx_id_t m_low_limit_id;      /* 如果行记录大于等于这个 ID,
  则 当前事务不可读取这个行号的数据,   值当前事务id+1 */

  trx_id_t m_up_limit_id;       /* 如果行上的DB_TRX_ID小于这个值,则当前事务可读取这个行,
  活跃列表中的最小id,如果活跃列表为空则等于 m_low_limit_id */

  trx_id_t m_creator_trx_id;    /* 创建该 Read View 的事务ID */

  trx_id_t m_low_limit_no;      /* 事务 Number, 小于该 Number 的 Undo Logs 均可以被 Purge */

  ids_t m_ids;                  /* 创建 Read View 时的活跃事务列表,当前未提交事务 ID 集合,
  后续即使这些id里的事务修改了数据,对当前事务时不可见的*/

  m_closed;                     /* 标记 Read View 是否 close */
}

undo log

用于事务回滚时恢复数据。当读取记录时,若该记录被其他事务占用或当前版本对该事务不可见,则可以通过 undo log 读取之前的版本数据,以此实现非锁定读。
undo log类型

  • insert undo log :
    指在 insert 操作中产生的 undo log。因为 insert 操作的记录只对事务本身可见,对其他事务不可见,故该 undo log 可以在事务提交后直接删除。不需要进行 purge 操作
  • update undo log:
    update 或 delete 操作中产生的 undo log。该 undo log可能需要提供 MVCC 机制,因此不能在事务提交时就进行删除。提交时放入 undo log 链表,等待 purge线程 进行最后的删除.

RR和RC两个隔离级别下的MVCC实现差距

在事务隔离级别 RC 和 RR (InnoDB 存储引擎的默认事务隔离级别)下,InnoDB 存储引擎使用 MVCC(非锁定一致性读),但它们生成 Read View 的时机却不同在 **RC 隔离级别下的 每次select **查询前都生成一个Read View **(m_ids 列表)在 ==RR 隔离级别下只在事务开始后 第一次select ==数据前生成一个Read View(m_ids 列表)

MVCC+Next-key-Lock 防止幻读

1、执行普通 select,此时会以 MVCC 快照读的方式读取数据在快照读的情况下,RR 隔离级别只会在事务开启后的第一次查询生成 Read View ,并使用至事务提交。所以在生成 Read View 之后其它事务所做的更新、插入记录版本对当前事务并不可见,实现了可重复读和防止快照读下的 “幻读”
2、执行 select...for update/lock in share mode、insert、update、delete 等当前读在当前读下,读取的都是最新的数据,如果其它事务有插入新的记录,并且刚好在当前事务查询范围内,就会产生幻读 !InnoDB 使用 Next-key Lock 来防止这种情况。当执行当前读时,会锁定读取到的记录的同时,锁定它们的间隙,防止其它事务在查询范围内插入数据。

标签:事务,log,Read,MVCC,undo,Mysql,机制,id
From: https://www.cnblogs.com/habc706/p/16967310.html

相关文章

  • mac Django 连接mysql
    目录macdjango2.2正确连接mysql方式问题描述macdjango2.2正确连接mysql方式macDjango电脑连接mysql时候会出现一些错误,因为版本问题。以下操作Django2.2.22亲测有......
  • 使用SpringBoot连接MySQL数据库,快速上手「建议收藏」
    大家好,又见面了,我是你们的朋友全栈君。使用SpringBoot连接MySQL目录0环境配置1建立MySQL数据库2使用SpringInitializer快速搭建springboot项目3配置pom.xml文件4配......
  • Docker 安装MySql 8.0
    1.下载镜像dockerpullmysql:8.0.312.安装dockerrun-p3306:3306--namemysql8-v/fanqi/mysql/conf:/etc/mysql/conf.d-v/fanqi/mysql/logs:/logs-v/fanqi......
  • PBFT 共识机制-保证区块链上的账值一致性不可篡改
    签名机制,数据篡改成本极高  2 3 4 5 ......
  • MySQL查看数据库、表占用磁盘大小
     直接复制执行1、查询所有数据库占用磁盘空间大小selectTABLE_SCHEMA,concat(truncate(sum(data_length)/1024/1024,2),'MB')asdata_size,concat(truncate(sum......
  • docker 启动mysql 失败 mysqld: Can't read dir of '/etc/mysql/conf.d/
    [root@localhost~]#dockerlogs-f55cca96ac3b62022-12-0808:27:23+00:00[Note][Entrypoint]:EntrypointscriptforMySQLServer5.7.40-1.el7started.2022-12-0......
  • MySQL高可用MHA集群
    一、MHA概述1.1什么是MHAMHA(MasterHighAvailability)是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。MHA的出现就是解决MySQL单点故障的问题。MySQL......
  • MYSQL-INNODB索引构成详解
    作者:郑啟龙摘要:对于MYSQL的INNODB存储引擎的索引,大家是不陌生的,都能想到是B+树结构,可以加速SQL查询。但对于B+树索引,它到底“长”得什么样子,它具体如何由一个个字节构成的,......
  • 国务院联防联控机制印发《新冠病毒感染者居家治疗指南》
    https://baijiahao.baidu.com/s?id=1751618178435029402&wfr=spider&for=pc中新网12月8日电据国家卫健委官方微信消息,按照进一步优化落实疫情防控措施有关要求,为有效做......
  • mysql 常见统计方案整理汇总
    普通分组统计场景一:根据订单状态统计订单数量。一个很常见,也很简单的统计需求。其中状态字段是订单实体的一个属性selectcount(*)countfromordersgroupbystatus;......