版本管理器设计与实现
约 1031 字大约 3 分钟
2025-01-15
1.PL/MVCC
1.1 冲突操作
在数据库中,多个事务可能会同时操作同一个数据项,这就可能导致冲突。
两个事务对同一数据的update操作
两个事务对同一数据的update、read操作
1.2 2PL
- 定义:两阶段锁在事务执行过程中分为两个阶段:增长阶段和收缩阶段。在增长阶段,事务可以获取任意数量的锁,但不能释放任何锁;在收缩阶段,事务只能释放锁而不能再获取新的锁
- 两阶段锁怎么解决数据库的冲突操作?
要求事务在增长阶段获取所需的锁,并保证在释放锁前,其他事务无法访问已被锁定的资源,从而避免了操作冲突
- 问题:导致了事务的相互阻塞,性能差
1.3 MVCC
- 定义:多版本并发控制,用于解决数据库中多个事务并发执行时的读写冲突问题。MVCC通过维护数据的多个版本,允许并发的读操作和写操作更有效地进行
- 核心概念:
- 版本控制:每个数据项都有多个版本,当事务对数据进行修改时,系统不会直接覆盖旧版本的数据,而是创建一个新版本
- 事务标识:每个事务在开始时都会获得一个唯一的事务ID,这个事务ID用于决定事务可以访问哪些数据版本,从而确保数据的一致性和隔离性
- 优点:
- 并发性高:MVCC允许多个事务同时读取数据,而不需要加锁
- 避免读写冲突:通过维护数据的多个版本,读操作不会被写操作阻塞
- 缺点:存储开销大、版本管理复杂性高
- MiniDB中的MVCC:
- 给VM之上的模块提供抽象数据:记录(Entry)
- 版本管理器在内部,为每个记录维护了多个版本。当上层模块对某个记录修改时,版本管理器就创建一个新的版本
2.Entry
- Entry定义:
- XMIN:创建该记录的事务ID
- XMAX:删除该记录的事务ID
- data:该条记录持有的数据
- 创建一个新的记录对象、加载一个记录
3.事务隔离级别
MiniDB实现了两种事务隔离级别:读已提交、可重复读
3.1 读已提交
3.1.1 定义
一个事务只能读取其他事务已经提交的数据,可能导致不可重复读问题
3.1.2 实现逻辑
- 如果版本的创建事务ID等于当前事务ID,并且版本的标志删除为空(表示未被删除)(即该版本由当前事务创建并且还没被删除,可见)
- 如果版本的创建事务ID对应的事务已经提交,并且版本的标志删除为空(未被删除); 或者标志删除的事务ID不是当前事务ID,并该事务ID还没提交 即由一个已提交的事务创建且尚未被删除;或者由一个已提交的事务创建且只是未被提交的事务删除
3.2 可重复读
3.2.1 定义
定义:事务只能读取,事务开始时已经提交了的事务产生的数据的版本,确保事务在执行期间读取到的数据是一致的
3.2.2 实现逻辑
- 如果版本的创建事务ID等于当前事务ID,并且版本的标志删除为空(表示未被删除)(即该版本由当前事务创建并且还没被删除,可见)
- 如果版本的创建事务ID已经提交,并创建事务ID小于当前事务ID,并创建事务ID不在当前事务开始前火活跃的事务集合中,且
- 删除版本的事务ID为空,表示该版本尚未被删除