MySQL-MVCC(Multi-Version Concurrency Control)

MySQL-MVCC(Multi-Version Concurrency Control)

MVCC(多版本并发控制):为了解决数据库并发读写和数据一致性的问题,是一种思想,可以有多种实现方式。

核心思想:写入时创建行的新版本,读取时查看当前行版本。

InnoDB解决方法思路:undo log+read view

1.undo log

trx_id:表示最近修改该行的事务id。

roll_pointer:指向的是上一个版本数据地址。

trx_id:每次开启一个事务时,事务都有一个id,如果事务对行进行了修改,同时修改行的trx_id为当前事务的id。

roll_pointer:事务对行进行了修改,同时将历史版本数据写入undo log,并修改roll_pointer指针指向修改前的版本。

举例:使用更新语句更新表中内容。

sql 复制代码
update users set age = 30 where id = 1;
update users set age = 40 where id = 1;

undo是一种逻辑日志,主要在事务的执行过程中,记录数据修改的历史版本,在必要的时候恢复到历史的状态。这些连接的版本数据称为版本链。

undo的回滚方式:如果要将数据回归为历史的版本,InnoDB做的是与之前相反的工作,对于insert,InnoDB会执行一个delete。对于delete,InnoDB会执行一个insert。对于update,会执行一个相反的update。

2.Read View

随着版本链的增长,事务读取的时候可以读取哪一个版本呢?这将是我们接下来要解决的问题。

什么时候生成Read View:在READ COMMITTED隔离级别下,每次读取数据时都会生成一个新的Read View。而在REPEATABLE READ隔离级别下,只有在事务中的第一个SELECT操作(快照读)时才会创建Read View,之后的SELECT操作不会再创建新的Read View。

Read View的几个属性:

  1. trx_ids:表示的是在Read View生成时刻系统里活跃的事务ID列表。
  2. up_limit_id:记录trx_list列表中事务ID最小的ID。
  3. low_limit_id:Read View生成时刻系统尚未分配的下一个事务ID,也就是目前已出现过的事务ID的最大值+1。

读取数据过程:

  1. 如果读取的行的事务id是创建Read View事务id,说明该事务修改了,返回的是当前事务修改后的数据。
  2. 如果读取行的事务id是trx_ids列表中的,说明是对自己不可见的数据,需要从版本链中查找。
  3. 如果读取的行的事务id不是trx_ids列表中的且行事务id小于当前事务id,说明是已经提交了的事务,对自己可见。

快照读和当前读

快照读:实现是基于Read View。

当前读:始终读取的是最新的数据。

MVCC是否有解决幻读问题

对于部分场景解决了幻读问题,部分场景没有解决。如果仅仅是查询操作的话可以解决幻读(快照读),如果是对新插入的数据进行更新(当前读),就会发生幻读。

3.总结

MVCC只在RC(READ COMMITED)和RR(READ REPEATABLE )中生效,因为READ UNCOMMITED读取的永远都是最新数据,SERIALIZABLE会对读取的行加锁,不需要解决并发和数据一致性问题。

参考书籍:

1\]High Performance MySQL\[M\].,:792. \[2\]MySQL技术内幕\[M\].,:391.

相关推荐
GDAL1 小时前
Node.js v22.5+ 官方 SQLite 模块全解析:从入门到实战
数据库·sqlite·node.js
DCTANT2 小时前
【原创】国产化适配-全量迁移MySQL数据到OpenGauss数据库
java·数据库·spring boot·mysql·opengauss
程序员岳焱3 小时前
Java 与 MySQL 性能优化:MySQL全文检索查询优化实践
后端·mysql·性能优化
喜欢敲代码的程序员4 小时前
SpringBoot+Mybatis+MySQL+Vue+ElementUI前后端分离版:项目搭建(一)
spring boot·mysql·elementui·vue·mybatis
AI、少年郎4 小时前
Oracle 进阶语法实战:从多维分析到数据清洗的深度应用(第四课)
数据库·oracle
赤橙红的黄4 小时前
自定义线程池-实现任务0丢失的处理策略
数据库·spring
钢铁男儿4 小时前
C# 委托(调用带引用参数的委托)
java·mysql·c#
叁沐5 小时前
MySQL 02 日志系统:一条SQL更新语句是如何执行的?
mysql
DataGear5 小时前
如何在DataGear 5.4.1 中快速制作SQL服务端分页的数据表格看板
javascript·数据库·sql·信息可视化·数据分析·echarts·数据可视化
weixin_438335405 小时前
分布式锁实现方式:基于Redis的分布式锁实现(Spring Boot + Redis)
数据库·redis·分布式