数据库系统原理:MVCC

  • 什么是MySQL InnoDB下的当前读和快照读?
    • 当前读
      • 它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。
    • 快照读
      • 快照读的前提是隔离级别不是可串行化,串行级别下的快照读会退化成当前读。
      • 快照读是基于提高并发性的考虑,快照读的实现基于MVCC。可以认为MVCC是行锁的一个变种,但它在很多情况下,避免了加锁操作。
      • 快照读可能读到的并不一定是最新版本,而有可能是之前的历史版本。
    • MVCC就是为了实现读或写冲突不加锁,而这个读指的就是快照读,而非当前读,当前读实际上是一种加锁的操作,是悲观锁的实现。
    • MVCC + 悲观锁:MVCC解决读写冲突,悲观锁解决写写冲突
    • MVCC + 乐观锁:MVCC解决读写冲突,乐观锁解决写写冲突
  • MVCC是为了解决什么问题?
    • 锁机制可以控制并发操作,但是其系统开销较大,而MVCC可以在大多数情况下代替行级锁,使用MVCC能降低系统开销。
  • MVCC基本原理
    • MVCC的实现通过保存数据在某个时间点的快照来实现的。这意味着一个事务无论运行多长时间,在同一个事务里能够看到数据一致的视图。根据事务开始的时间不同,意味着在同一个时刻不同事物看到的相同表里的数据可能是不同的。
    • 不同存储引擎的MVCC实现是不同的,典型的有乐观并发控制和悲观并发控制。
    • 基本特征:
      • 每个数据都存在一个版本,每次更新数据时都更新该版本。
      • 修改时copy出当前版本随意修改,各个事务之间无干扰。
      • 保存时比较版本号,如果成功,则覆盖原纪录,失败则放弃。
  • InnoDB实现MVCC
    • 通过在每行记录后面保存两个隐藏的列来实现。这两个列分别保存了这个行的创建时间和删除时间(并非实际的时间值,而是系统版本号)。
  • next-key lock解决幻读
    • InnoDB有三种锁机制
      • record lock:单行记录锁(行锁)。它的实质是通过对索引的加锁实现,只有通过索引条件检索数据,InnoDB才使用行级锁,否则,使用表级锁。在事务隔离级别为读已提交下,仅采用record lock。
      • gap lock:间隙锁,锁定一个范围,但不包含记录本身。
      • next-key lock:record + gap lock,锁定一个范围,并且锁定记录本身。
    • 为什么会存在next-key lock?
      • 一般的数据库避免幻读需要在串行化的事务隔离级别,而InnoDB在可重复读的隔离级别下消除幻读,这样能够有效提高数据库的并发度。
    • 原理:对查询范围进行加锁,在另一个事务执行插入操作时不被允许,从而避免了幻读。

猜你喜欢

转载自www.cnblogs.com/xiaobaizzz/p/12305656.html