MySql 多本版并发控制(MVCC)

什么是多版本并发控制

多版本并发控制技术的英文全称是Multiversion Concurrency Control,缩写为MVCC。

多版本并发控制(mvcc)是通过在特定时间点保存数据快照来实现的。 也就是说,无论事务执行多长时间,事务内部看到的数据都不会受到其他事务的影响。 根据事务的开始时间,每个事务可能同时看到同一表的不同数据。

简而言之,多版本并发控制的思想是保存数据的历史版本,并通过管理数据行的多个版本来实现数据库的并发控制。 通过这种方式,我们可以通过比较版本号来确定是否显示数据。 在读取数据时,我们不需要加锁也能确保事务的隔离效果。  

可以认为多版本并发控制(mvcc)是行级锁定的一种变体,但在许多情况下避免了锁定操作,因此成本较低。 尽管实现机制不同,但是大多数实现非阻塞的读操作,而写操作仅锁定必要的行。 

MySQL中的大多数事务存储引擎都不实现简单的行级锁。 为了提高并发性能,它们通常同时实施多版本并发控制(mvcc)。 Mvcc不仅在mysql中实现,在Oracle,PostgreSQL和其他数据库系统中也有实现。 但是,它们各自的实现机制是不同的,因为mvcc没有统一的实现标准,通常包括乐观并发控制和悲观并发控制。

 多版本并发控制解决了哪些问题

1,读写堵塞问题 

通过mvcc,读取和写入不能互相阻塞,即读取不阻塞写入和写入不阻塞读取,这可以提高事务并发处理的能力。

如何提高并发性

  • 普通锁只能以串行方式执行;
  • 读写锁可以实现读写并发;
  • 数据多版本并发控制可以实现读写并发。  

2.减少死锁的可能性

由于InnoDB的mvcc采用了乐观锁定方法,因此在读取数据时无需锁定数据,而只有必要的行才被锁定以进行写操作。 

3.解决读一致性问题

 一致性读取也称为快照读取,当我们在某个时间点查询数据库的快照时,我们只能看到此时间点之前事务提交更新的结果,而不能看到此时间点之后事务提交的结果。

快照读和当前读取(Snapshot read and current read)

快照读取这是一种无锁的一致读取,也是InnoDB并发性能比较优异的原因之一。 事务读取的这些数据都是一致的:事务开始之前就存在的数据,以及事务本身插入或修改的数据。

不带锁的简单select语句属于快照读取,例如:

`SELECT * FROM t WHERE id=1`

与快照读相对应的是当前读(current read),当前读是读取最新数据,而不是数据的历史版本。 加锁的select语句属于当前读取,例如:  

SELECT * FROM t WHERE id=1 LOCK IN SHARE MODE;  

SELECT * FROM t WHERE id=1 FOR UPDATE;

InnoDB的mvcc如何工作

1. InnoDB如何存储记录的多个版本

事务版本号

每次新建一个事务时,我们将从数据库中获取事务D(即事务版本号)。 该事务ID是自增长的。 通过ID大小,我们可以确定事务的时间顺序。

行记录的隐藏列

 InnoDB的叶子节点存储数据页,而数据页存储行记录。 行记录中有一些重要的隐藏字段:

DB_ROW_ID:6字节的隐藏行ID,用于生成默认的聚簇索引。 在这种情况下,当创建聚簇索引时,InnoDB将创建一个隐藏索引列。 聚簇索引可以提高数据搜索的效率。

DB_TRX_ID:6字节,操作数据的事务ID,这是要插入或更新数据的最后一个事务ID。

DB_ROLL_PTR:回滚指针。

Undo Log

InnoDB将行记录的快照保存在Undo Log中。 我们可以在回滚段中找到它们,如下图所示:

 从图中可以看出,回滚指针通过链表的结构连接数据行的所有快照记录,并且每个快照都会记录事务创建的时间(事务的ID也就是该数据的操作点)。 这样,如果我们要查找历史快照,可以通过遍历回滚指针来找到它。

2.InnoDB不可重复读隔离级别在mvcc中如何工作 

查询 (select)

InnoDB根据以下两个条件检查记录的每一行:

  • InnoDB仅查找版本早于当前事务版本的数据行(即该行的系统版本号小于或等于事务的版本号)确保事务读取的行在事务开始之前就已经存在,或者由交易本身插入或修改。
  • 数据行的已删除版本要么未定义,要么大于当前事务版本号。 事务读取的行在事务创建的时候一定没删除。 意思是即使一个新的的事务删除了某行,但是因为这个删除行的版本号比较大,是不会影响到之前的事务的。

 只有满足以上两个条件的记录才能作为查询结果返回。

插入

InnoDB将当前系统版本号保存为每个新插入的行的行版本号。

删除

InnoDB将每个删除行的当前系统版本号保存为行删除标识符。 删除在内部被视为更新,并且行中的特殊标记位设置为删除。

更新

为了插入新记录,InnoDB将当前系统版本号保存为行版本号,并将当前系统版本号保存到原始行中作为行删除标识符。

总结

多版本并发控制(mvcc)在一定程度上实现了读写并发性,它只有不可重复的读和读已提交这两个隔离级别下。 其他两个隔离级别与mvcc不兼容,因为未提交读,总是读取最新的数据行,而不是与当前事务版本匹配的数据行。而串行化则是要上锁。

行锁,并发,事务回滚和许多其他功能都与mvcc有关。

 

文章翻译自https://developpaper.com/,这是一个非常不错的IT技术博客网站

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
版本并发控制(MVCC)是MySQL中的一种技术,它通过维护数据的多个版本,以实现读写操作的并发控制MVCC通过在每行记录后面保存两个隐藏的列(一个保存行的创建时间,一个保存行的删除时间)来实现。当一个事务读取数据时,它会根据事务开始的时间戳和行的版本信息来确定可见的数据版本。这种机制在InnoDB存储引擎中被广泛使用,可以提供一致性读操作的保证。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [MySQL之InnoDB存储引擎-MVCC](https://blog.csdn.net/qq_53267860/article/details/125073612)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [MySQL数据库多版本并发控制MVCC](https://blog.csdn.net/iuu77/article/details/129132863)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [mysql版本并发控制MVCC的实现](https://download.csdn.net/download/weixin_38607195/14907745)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值