Mysql的MVCC机制分析

1、MVCC 机制是什么
多版本并发控制 (MVCC,Multi-Version Concurrency Control) ,是一种用于数据库管理系统的技术,旨在提高并发性能的同时保证数据的一致性。

通过为每一行数据记录维护多个历史版本,在读取的时候根据版本号来决定是否把数据显示出来,从而减少了使用锁的竞争和阻塞现象

2、MVCC 机制用来解决什么问题

(1)解决传统锁机制下读写之间相互阻塞的问题。通过 MVCC 可以让读写互相不阻塞,读不相互阻塞,写不阻塞读,可以提高数据并发处理能力

(2)解决了一致性读问题。当读取某个数据库在某个时间点的快照时,只能看到这个时间点之前事务提交更新的结果,不会看到时间点之后事务提交的更新结果

(3)降低死锁概率。因为 MVCC 采用了乐观锁的方式,读取数据时,不需要加锁,写操作,只需要锁定必要的行

3、MVCC 机制的实现原理是什么

InnoDB 是如何存储记录多个版本的?

这里涉及几个概念: 事务 id(事务版本号),行记录中的隐藏列 、Undo Log 以及 ReadView。

(1)事务版本号

每开启一个事务都会从数据库中获得一个事务 id,一般会使用全局的单调递增的计数器来生成全局唯一的id,可通过 id 大小来判断事务的时间顺序

(2)行记录的隐藏列
row_id :隐藏的行 id ,用来生成默认的聚簇索引。如果创建数据表时没指定聚集索引,这时 InnoDB 就会用这个隐藏 id 来创建聚集索引。采用聚集索引可以提升数据查询效率
trx_id :操作这个数据的事务 id ,也就是最后一个对数据插入或者更新的事务 id
roll_ptr :回滚指针,指向这个记录的 Undo Log 信息

(3)Undo Log

InnoDB 将行记录快照保存在 Undo Log 中

数据行通过快照记录都通过链表结构串联起来,每个快照都保存了事务 id,如果要找到历史快照,就可以通过遍历回滚指针的方式进行查找。

(4)Read View

Read View 是每个事务启动时生成的一致性视图,用来解决一个事务在运行期间如何确定哪些数据版本对当前事务可见的问题。

Read View 保存了当前事务开启时所有活跃的事务列表。

a. trx_ids ,系统当前正在活跃的事务 ID 集合。

b. low_limit_id,活跃事务的最大的事务 ID。

c. up_limit_id,活跃的事务中最小的事务 ID。

d. creator_trx_id,创建这个 ReadView 的事务 ID。

如果当前事务的 creator_trx_id 想要读取某个行记录,这个行记录的事务 id 为trx_id ,这会有以下情况:

  • 如果该行是由创建 Read View 的事务自己插入或更新的,那么这些更改对当前事务是可见的。
  • 如果 trx_id < 活跃的最小事务ID(up_limit_id),也就是说这个行记录在这些活跃的事务创建前就已经提交了,那么这个行记录对当前事务是可见的。
  • 如果trx_id > 活跃的最大事务ID(low_limit_id),这个说明行记录在这些活跃的事务之后才创建,说明这个行记录对当前事务是不可见的。
  • 如果 up_limit_id < trx_id <low_limit_id,说明该记录需要在 trx_ids 集合中,可能还处于活跃状态,因此我们需要在 trx_ids 集合中遍历 ,如果trx_id 存在于 trx_ids 集合中,证明这个事务 trx_id 还处于活跃状态,不可见,否则 ,trx_id 不存在于 trx_ids 集合中,说明事务trx_id 已经提交了,这行记录是可见的。

4、查询一条记录的过程是怎样的
(1)检查当前行版本

InnoDB 首先检查当前行的 trx_id(即最后一次修改该行的事务 ID),如果这个 trx_id 符合 Read View 的可见性规则,则直接返回该行版本给事务。

(2)回滚指针 (roll_ptr) 检查

如果当前行的 trx_id 不符合 Read View 规则,InnoDB 会使用行中的 roll_ptr 字段(回滚指针)指向 undo 日志中的旧版本记录。

(3)遍历历史版本链

InnoDB 通过 roll_ptr 访问 undo log,并逐步回溯到更早的行版本。对每个历史版本重复上述可见性检查过程,直到找到一个符合 Read View 规则的版本或到达最早的版本。

(4)处理结果

找到可见版本:一旦找到符合 Read View 规则的行版本,就将其返回给查询。

未找到可见版本:如果遍历完所有历史版本后仍未找到符合规则的版本,意味着该行对于当前事务是完全不可见的。此时,查询结果中不会包含这条记录。

大佬,点个赞在走呗!

相关推荐
等一场春雨2 分钟前
linux 使用 MySQL Performance Schema 和 Prometheus + Grafana 来监控 MySQL 性能
linux·mysql·prometheus
Pandaconda25 分钟前
【Golang 面试题】每日 3 题(二十三)
开发语言·后端·面试·golang·go·channel
等一场春雨25 分钟前
linux 查看 MySQL 在 Linux 或 WSL 上的运行状态
linux·mysql·adb
网络安全-杰克1 小时前
【漏洞分析】UDF提权漏洞——CVE-2016-6662-MySQL ‘malloc_lib’变量重写命令执行
数据库·mysql
2401_840192271 小时前
来说数据库
数据库·oracle
Retrograde-lx1 小时前
利用logstash同步100万MySQL数据到es
数据库·mysql·elasticsearch
黄鹂绿柳2 小时前
django的mysql数据库配置
数据库·mysql
CoderJia程序员甲2 小时前
MySQL事件功能简介
数据库·mysql·事件调度
xsh801442422 小时前
MySQL派生表合并优化的原理和实现
mysql
ccc_9wy2 小时前
HackMyVM-Alive靶机的测试报告
mysql·网络安全·代码审计·udf提权·hackmyvm·文件包含漏洞getshell·qdpm