. MVCC (多版本并发控制)
- 概念:
- MVCC 是一种并发控制技术,用于在数据库中实现并发事务的读写操作,同时保证事务的隔离性。
- MVCC 的核心思想是,在数据库中维护数据的多个版本,每个事务在读取数据时,读取的是特定版本的数据,而不是最新的数据。 这样可以避免读写冲突,提高并发性能。
- 解决的问题:
- 读写阻塞: 在传统的锁机制中,读操作和写操作之间会相互阻塞,导致并发性能下降。 MVCC 可以避免读写阻塞,提高并发性能。
- 脏读、不可重复读、幻读: MVCC 可以通过控制事务读取的数据版本,避免脏读、不可重复读、幻读等并发问题。
- 工作原理:
- 版本号: 数据库中的每一行数据都有一个版本号,用于标识数据的不同版本。
- 事务 ID: 每个事务都有一个唯一的事务 ID,用于标识事务的开始和结束。
- Read View (读视图): 每个事务在开始时,都会创建一个 Read View,用于确定该事务可以读取的数据版本。 Read View 包含以下信息:
- m_ids: 当前系统中所有活跃事务的 ID 列表。
- min_trx_id:
m_ids
中最小的事务 ID。 - max_trx_id: 当前系统中下一个要分配的事务 ID。
- creator_trx_id: 创建该 Read View 的事务 ID。
- 版本选择: 当事务需要读取一行数据时,会根据 Read View 和数据的版本号进行比较,选择合适的数据版本。
- 如果数据的版本号小于
min_trx_id
,则表示该版本的数据在当前事务开始之前就已经提交,可以读取。 - 如果数据的版本号大于等于
max_trx_id
,则表示该版本的数据在当前事务开始之后才创建,不能读取。 - 如果数据的版本号在
min_trx_id
和max_trx_id
之间,则需要判断该版本号是否在m_ids
列表中。- 如果在
m_ids
列表中,则表示该版本的数据是当前系统中其他活跃事务创建的,不能读取。 - 如果不在
m_ids
列表中,则表示该版本的数据在当前事务开始之前就已经提交,可以读取。
- 如果在
- 如果数据的版本号小于
- 数据更新: 当事务需要更新一行数据时,会创建一个新的数据版本,并将新的版本号设置为当前事务的 ID。 同时,会将旧的版本号保存在新的版本中,形成一个版本链。
- InnoDB 中的 MVCC:
- InnoDB 存储引擎通过在每一行数据中增加两个隐藏列来实现 MVCC:
- DB_TRX_ID: 创建或修改该行的最后一个事务 ID。
- DB_ROLL_PTR: 指向该行的 undo log 的指针。 undo log 中保存了旧版本的数据。
- InnoDB 使用 Read View 来判断事务可以读取的数据版本。
- InnoDB 的 MVCC 机制可以保证在 READ COMMITTED 和 REPEATABLE READ 隔离级别下的事务隔离性。
- InnoDB 存储引擎通过在每一行数据中增加两个隐藏列来实现 MVCC:
- MVCC 的优势:
- 提高并发性能: 避免读写阻塞,提高并发性能。
- 保证事务隔离性: 避免脏读、不可重复读、幻读等并发问题。
- MVCC 的缺点:
- 存储空间: 需要维护多个数据版本,占用更多的存储空间。
- 版本维护: 需要定期清理旧版本的数据,避免存储空间过度增长。