MVCC即多版本并发控制(Multi-Version Concurrency Control),是一种用于数据库管理系统的技术,主要用于提高数据库系统在并发操作下的性能,同时保证事务的一致性和隔离性。其核心思想是为每个读取的数据库对象(如行或记录)提供其事务时间点的快照,而不是锁定数据以防止其他事务访问。
一、MVCC的实现
MVCC中重要的概念和结构,包括2个隐藏列(如事务ID 和 回滚指针)以及2个数据结构(如事务链表 和 ReadView)。
- 事务ID(Transaction ID) :
- 这是一个隐藏列,存储在每行数据中,用来标识最后修改该行的事务。
- 事务ID是一个唯一的标识符,它帮助数据库确定数据的版本。
回滚指针(Rollback Pointer) :
- 另一个隐藏列,指向存储旧数据版本的回滚段。
- 当发生更新时,旧的数据版本不会被覆盖,而是通过回滚指针链接到回滚段中。
事务链表(Transaction Linked List) :
- 这是一个数据结构,用于维护当前活跃的所有事务。
- 每个事务在开始时都会被加入到这个链表中,提交或回滚时则移除。
ReadView:
- ReadView是一种数据结构,用于创建一致性读的快照。
- 它基于事务链表生成,并包含了在特定时间点活跃的所有事务的信息。
- ReadView确保事务能够看到在其开始之前提交的所有更改,同时不看到在其开始之后发生的更改。
二、MVCC的工作原理
- 当事务读取数据时,它只会看到该事务开始时或之前的数据版本。
- 当事务更新数据时,它不会覆盖旧数据,而是创建一个新版本。
- 系统维护数据的多个版本,确保每个事务都可以访问适当的数据版本。
详细介绍:当一个事务尝试读取数据时,它会使用ReadView来决定应该读取哪个版本的数据。这取决于数据行的事务ID和当前活跃的事务(通过事务链表确定)。如果数据行的事务ID指示该数据是由当前ReadView中不存在的事务更新的(即更新发生在读取事务开始之后),那么这个数据版本对当前事务是不可见的。相反,如果数据行的事务ID对应于已提交的事务或读取事务开始之前的事务,那么这个数据版本就是可见的。
- 小于最小id即事务id在图中1所指范围的可见
- 大于最大id即事物id在图中2所指范围的不可见
- 中间事务可见性即图中3所指的范围,由事务隔离级别决定。RR 事务提交不可见,RC 事务提交可见。
三、MVCC的优点
- 提高并发性能:不同事务可以同时读取同一数据的不同版本,减少了锁的需求。
- 避免写入阻塞:更新操作不会直接覆盖旧数据,减少了写入操作之间的冲突。
- 减少锁争用:因为读取操作通常不需要锁,所以降低了锁争用的机会。
四、MVCC的缺点
- 增加存储开销:因为要存储多个版本的数据,所以可能需要更多的存储空间。
- 可能的性能开销:管理多个数据版本可能会增加一些计算开销。
- 需要垃圾回收:随着时间的推移,旧版本数据需要被清理,这就需要有效的垃圾回收机制。
五、使用MVCC的数据库系统示例
- PostgreSQL
- MySQL(InnoDB存储引擎)
- Oracle Database