Mysql MVCC 原理 low_limit_id ReadView

  • 参考:感觉好多地方写的都不对。。还是看源码吧
  • MVCC Multi-version Concurrency Control
    • 怎么个MultiVersion法?
      • 每个开启的事务,会有一个tx_id,是不断自增长的,后面开的事务比前面开的事务大
      • 在默认的隔离级别:RepeatableRead,可重复读,需要做成,在事务中,看不到别人的修改,怎么做到呢?
        • 先引入一个概念:ReadView。ReadView里包含:
          • 当前活跃的事务id列表
          • 创建者的事务id
          • up_limit_id , low_limit_id 上下限,小于up_limit_id 可见, 大于low_limit_id 不可见。
            • 那么这个两个值是怎么赋值的呢。
            • low_limit_id 是系统最大的事务id值。up_limit_id是活跃事务列表的最小事务id
              • /* No future transactions should be visible in the view */
              • 349  view->low_limit_no = trx_sys->max_trx_id;
              • 350  view->low_limit_id = view->low_limit_no;
              • /* The last active transaction has the smallest id: */
              • view->up_limit_id = view->trx_ids[view->n_trx_ids - 1];
          • 这样理解Read View :保存了不应该让这个事务看到的其他的事务 ID 列表
        • 再引入关于可见性的规则
          • 读某一行数据的时候,如果发现他的事务id < up_limit_id (活跃id列表最小值),可见。
          • 如果发现数据的事务id>low_limit_id(ReadView时系统中最大的事务id) ,不可见。
          • 如果发现数据的事务id在列表范围内
            • 如果是id集合中的,不可见
            • 如果不在id集合中,可见
        • 根据上面的规则,以RepeatableRead举个例子吧,要求读一个值,一直读都是同一个值。
          • 这种隔离级别下,开启事务的时候开启一个ReadView,在整个事务过程中都用这个ReadView。
          • 我开启是事务是10,ReadView是 (4,8, 10),【我自己也活跃】,up_limit_id=11,low_limit_id=4
          • 如果我读到一个数据的事务id是1,小于活跃列表的最小值,可见。
            • 为什么?事务开启的时候生成的ReadView,除了4,8,10,其他都已经提交了,所以其实版本<4,以及5、6、7、9,都是肯定在我开启的时候已经提交了。这些版本的的数据,再怎么读都不会变。放心读吧。
          • 如果我读到一个数据的事务id是12,说明他在我创建ReadView之后提交的,我不应该看见这个值,应该去undolog里找这个数据的前面的版本,如果找到<4,或者5、6、7、9都是安全的,可以读。
          • 如果我读到一个数据事务id在活跃列表的范围内
            • 如果就是活跃的事务之一,比如说是8,说明这个数据在我开启事务之后提交了,这个我不能看见,应该去undo log中找上一个版本来读,假设说是7。
            • 7也是在这个活跃范围里,但是并不是活跃事务之一,这个版本是在开启事务之前提交的,这个我可见。
        • 再举个读已提交的例子。
          • 这个隔离级别是每次读都采用新的ReadView。
          • 开启的事务是10。
          • 读一个数据,事务id是9,ReadView活跃id是(4,8,10),按照规则,可见。
          • 过一会再读这个数据,发现事务id变成了11,活跃的id还是(4,8,10),但是因为开启了新的ReadView,当前系统最大事务id>11(因为我们已经读到11了嘛),判断规则是:不在活跃id列表,所以可见。这回就读到了这个数据的新版本了
  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
MySQLMVCC(Multi-Version Concurrency Control,多版本并发控制)是一种多版本的数据控制机制,它允许多个事务同时读取同一个数据快照,而不会出现读取冲突。 MVCC的实现原理主要是通过在每个数据行中保存多个版本的数据,每个版本数据都有自己的时间戳,用于标识数据的版本。当一个事务开始时,它会创建一个快照并锁定所有需要修改的数据行,此时其他事务只能读取旧版本的数据。当事务提交时,它会把新版本的数据写入数据库,并释放锁定的数据行。同时,其他事务也可以读取新版本的数据。 MVCC的实现要依赖于InnoDB引擎下的两个重要的结构:undo log和read view。 - undo log:当一个事务对数据进行修改时,InnoDB会将旧版本的数据保存到undo log中。在事务回滚时,InnoDB可以通过undo log将数据恢复到之前的版本。 - read view:每个事务在启动时会创建一个read view,它记录了事务启动时数据库中所有活跃的事务ID列表以及这些事务所对应的undo log的状态。在事务执行过程中,read view会随着时间不断更新。 通过undo log和read view的协作,InnoDB可以实现多版本并发控制。当一个事务读取数据时,它会根据read view的状态来选择正确的数据版本,即没有被其它事务修改的最新版本。如果出现读取冲突,则InnoDB会自动回滚事务并重新尝试读取数据。 总之,MVCC是通过保存多个版本的数据来实现并发控制的,它可以提高数据库的并发性能和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值