MVCC

作者: 深入浅出 | 来源:发表于2018-07-02 17:58 被阅读0次

    一、WHAT 什么是MVCC?

    MVCC(Multi-Version Concurrency Control)多版本并发控制。

    读锁 :也叫共享锁、S锁。
    若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S 锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。

    写锁:又称排他锁、X锁。
    若事务T对数据对象A加上X锁,则事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的锁。这保证了其他事务在T释放A上的锁之前不能再读取和修改A。

    表锁:操作对象是数据表。
    MySQL大多数锁策略都支持(常见mysql innodb),是系统开销最低但并发性最低的一个锁策略。事务T对整个表加读锁,则其他事务可读不可写,若加写锁,则其他事务增删改都不行。

    行级锁:操作对象是数据表中的一行。
    是MVCC技术用的比较多的,但在MYISAM用不了,行级锁用MySQL的储存引擎实现而不是MySQL服务器。但行级锁对系统开销较大,处理高并发较好。

    二、WHY 为什么使用MVCC?

    如果有人从数据库中读数据的同时,有另外的人写入数据,有可能读数据的人会看到不一致的数据。有很多种方法来解决这个问题,叫做并发控制方法。

    最简单的方法,通过加锁,让所有的读者等待写者工作完成,但是这样效率会很差。

    MVCC 使用了一种不同的手段,每个连接到数据库的读者,在某个瞬间看到的是数据库的一个快照,写者写操作造成的变化在写操作完成之前(或者数据库事务提交之前)对于其他的读者来说是不可见的。

    当一个 MVCC 数据库需要更新一条数据记录的时候,它不会直接用新数据覆盖旧数据,而是将旧数据标记为过时(obsolete)并在别处增加新版本的数据。

    这样就会有存储多个版本的数据,但是只有一个是最新的。这种方式允许读者读取在他读之前已经存在的数据,即使这些在读的过程中半路被别人修改、删除了,也对先前正在读的用户没有影响。

    这种多版本的方式避免了填充删除操作在内存和磁盘存储结构造成的空洞的开销,但是需要系统周期性整理(sweep through)以真实删除老的、过时的数据。

    对于面向文档的数据库(Document-oriented database,也即半结构化数据库)来说,这种方式允许系统将整个文档写到磁盘的一块连续区域上,当需要更新的时候,直接重写一个版本,而不是对文档的某些比特位、分片切除,或者维护一个链式的、非连续的数据库结构。

    MVCC 提供了时点(point in time)一致性视图。MVCC 并发控制下的读事务一般使用时间戳或者事务 ID去标记当前读的数据库的状态(版本),读取这个版本的数据。读、写事务相互隔离,不需要加锁。读写并存的时候,写操作会根据目前数据库的状态,创建一个新版本,并发的读则依旧访问旧版本的数据。

    MVCC就是用同一份数据临时保留多版本的方式实现并发控制。

    三、HOW 如何实现MVCC?

    MVCC 关键的两个点:

    1 在读写并发的过程中如何实现多版本

    2 在读写并发之后,如何实现旧版本的删除

    MVCC 使用时间戳(TS)、递增的事务 ID(T)实现事务一致性。

    MVCC 通过维护多版本数据,保证一个读事务永远不会被阻塞。对象 P 维护有多个版本,每个版本会有一个读时间戳(Read TimeStamp, RTS)和写时间戳(Write TimeStamp, WTS),事务 Ti 读对象 P 的最新版本,该版本早于事务 Ti 的读时间戳 RTS(Ti)。

    事务 Ti 要对 P 执行写操作,如果有其他事务 Tk 同时对 P 操作,则 RTS(Ti)必须要早于 RTS(Tk),即有 RTS(Ti) < RTS(Tk),这样对 Ti 对 P 的写操作才能完成。一般地,如果其他事务拥有 P 的一个更早的读时间戳的情况下,写操作是不能完成的。打个比方就是在存储前面有一道线,只有等你前面的人的完成了他们的事务,你的修改事务才可以提交完成。

    重复说一下:每个对象 P 有一个时间戳 TS,如果事务 Ti 想要对 P 执行写操作,(写要先读)事务的读时间戳是 RTS(Ti),如果有其他事务拥有一个比较早的时间戳,有 TS(P) < RTS(Ti),这时事务 Ti 会退出并重新开始。否则,事务 Ti 创建一个 P 的新版本,并设置新版本 P 的时间戳,似的 TS = TS(Ti)。

    MVCC 系统明显的缺点是会存储多个版本数据的冗余开销。但同时,读操作永不会被阻塞,这对那些以读操作为主的数据库来说非常重要。MVCC 实现了真的快照隔离(snapshot isolation),然后其他的并发控制方法要么是不完整的快照隔离方式,要么需要较高的性能损耗。

    相关文章

      网友评论

          本文标题:MVCC

          本文链接:https://www.haomeiwen.com/subject/rlvluftx.html