MVCC原理

数据库并发带来的问题

数据库并发会带来脏读、不可重复读、幻读等问题。

  • 脏读:当前事务读取了其它事务未提交的数据;
  • 不可重复读:当前事务中,在相同的查询条件下前后读取的结果不一样,主要侧重于查询记录的某些列不一样;
  • 幻读:当前事务中,在相同的查询条件下前后读取的结果集不一样,主要侧重于查询记录的个数增加或减少;

数据库隔离级别

数据库采用了事务的隔离级别来解决这些问题。

  • 读未提交:当前事务可以读取其它事务未提交的数据,不解决脏读、不可重复读、幻读的问题;
  • 读已提交:当前事务可以读取其它事务已提交的数据,解决了脏读,但是不解决不可重复读、幻读的问题;
  • 可重复读:MySQL默认的隔离级别,解决脏读、不可重复读的问题,也解决了幻读的问题(通过行锁和间隙锁);
  • 串行化:并发性最低,所有的事务按照顺序执行,解决了脏读、不可重复读、幻读的问题。

什么是MVCC

MVCC全称多版本并发控制,就是通过保存数据的历史版本,根据比较版本号来处理数据是否显示,从而达到在读操作的时候不会阻塞写操作,写操作的时候不会阻塞读操作,同时可以避免脏读和不可重复读。MySQL的可重复读级别就是用这种方法来处理的。

什么是快照读

快照度可以理解为不加锁的查询操作就是快照读,它的底层原理就是MVCC,由于MVCC是多版本并发控制,所以使用快照读读取的记录不一定是最新的。

MVCC实现原理

MVCC主要由隐藏字段、undolog、read-view来完成。MVCC的目标是如何正确地得到快照结果。

隐藏字段

隐藏字段包含:

  • roll_pointer:回滚指针,指向这条记录的上一个版本;
  • trx_id:记录操作该数据事务的事务ID,也叫做版本号,主要用于版本比较,从而找到快照;
  • db_row_id:隐藏ID,当创建的表没有聚簇索引的时候,会用该ID创建聚簇索引。

undolog

undolog主要用于记录数据被修改之前的日志,在记录修改之前会先把数据拷贝到undolog中,当事务进行回滚时可以通过undolog里的日志进行数据还原。在MVCC多版本控制中,通过读取undolog历史版本数据实现不同的事务之前都有自己的快照数据。

read view

在每个SQL语句执行之前都会得到一个read view,也叫做一致性视图。然后我们查询的数据结果跟read view的几个重要属性匹配从而得到正确的快照结果。
read view的四个重要属性:

  • trx_ids:未提交事务的版本号集合;

  • low_limit_id:执行当前SQL时,当前系统中最大的事务版本号;

  • up_limit_id:执行当前SQL时,当前系统中最小的事务版本号;

  • creator_trx_id:执行当前SQL的事务版本号;

  • 如果当前查找到的数据的事务ID<最小事务版本号,说明该数据是当前事务开启之前就已经存在了,可以显示;

  • 如果当前查找到的数据的事务ID>最大事务版本号,说明该数据是当前事务开启之后才产生的,所以不可以显示;

  • 如果当前查找的数据的事务ID在最小事务版本号和最大事务版本号之间,说明该数据是当前事务开启后,还没有提交;

  • 这时候需要在未提交的事务的版本号集合中查找,如果查找到这个事务ID,说明数据还没有提交,如果还等于creator_trx_id,说明这个数据属于当前事务提交的,自己提交的数据是可以看到的;如果不等于,则说明不是当前事务提交的,不是自己提交的当然不能显示。如果事务ID不存在于未提交的事务的版本号集合中中,说明当前数据是已提交的,这种情况下可以显示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种数据库并发控制机制,主要用于保证在高并发环境下数据的一致性和完整性。在Java中,MVCC通常与关系型数据库系统如Oracle、MySQL等的InnoDB储引擎相关。 MVCC原理主要包含以下几个关键点: 1. 数据版本:每个事务看到的是数据的一个独立版本,而不是实时的最新状态。每个版本都有一个时间戳或版本号,表示该数据的修改时间。 2. 读已提交(Read Committed):当事务开始时,它只会看到已经提交的更改。这样,即使有其他事务在修改同一数据,当前事务也能看到稳定的结果,不会看到未提交的更改。 3. 少数读脏(Read Uncommitted):一些数据库支持更高的并发度,允许事务看到其他事务未提交的修改,但这可能导致“脏读”(读到未提交的数据)。这是有风险的,通常仅在特定场景下使用。 4. 不可重复读(Repeatable Read):事务在执行过程中,如果多次读取同一数据,结果应该一致,不会因为其他事务的提交而改变,这通常通过锁定机制来实现。 5. 可串行化(Serializable):这是最高的隔离级别,确保所有事务看起来像是顺序执行,但实际性能较低。 在Java中,MVCC不直接体现在语言层面,而是由底层数据库管理系统实现。例如,Java应用程序通过JDBC连接数据库时,其实质上是在和数据库进行MVCC相关的交互。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值