MVCC
简介
oGRAC 通过锁机制、多版本并发控制(Multi-Version Concurrency Control, MVCC)和数据库隔离级别的协同设计,显著提升了系统的高并发处理能力。其中,MVCC 是实现高性能并发访问的核心技术之一,其核心思想是在不依赖或极少使用传统锁的情况下,解决读写冲突竞争问题,从而实现读不阻塞写,写不阻塞读的理想并发模型。
核心思想
- 数据版本化:每一行数据可以存在多个历史版本,由
Undo记录维护。每个事务看到的数据版本取决于SCN。 - 一致读(
Consistent Read):某事务在读取数据时,并非读取当前数据的最新版本,而是读取一个可见性前提下的历史数据版本,通过MVCC技术实现,此过程无需加锁,不会阻塞其他事务的写入操作,适用于SELECT类查询。 - 当前读(
Current Read):事务读取的是数据的最新状态,通常发生在UPDATE、DELETE或SELECT FOR UPDATE等修改类操作中。当前读会进行可见性判断并可能施加行锁,以确保操作的安全性。 - 通过MVCC避免锁冲突:通过多版本控制,多数只读事务通过一致读完成,避免了与写事务之间的锁等待,极大提升了并发性能。
MVCC原理描述
SCN
oGRAC 的 MVCC 实现基于 64位时间戳SCN(System Change Number) 和Undo 日志机制,构建了一个高效的行级多版本管理系统。
SCN 是 oGRAC 中全局单调递增的时间戳,用于标识事务发生的时间顺序。它是一个 64 位整数,结构如下:
{second[32bit]} {micro-second[20bit]} {sequence[12bit]}Second & Microsecond提供精确的时间基准,Sequence在同一微秒内区分多个事务,确保唯一性。
多版本存储与可见性判断
- "多版本"指的是 oGRAC 会同时物化并维护多个版本的数据,历史版本数据与当前最新的版本数据分开存储,前者保留在
Undo Page中,进行链式保存,形成一条按SCN逆序排列的版本链,后者保留在Data Page中。 - 当事务执行一致读时,若查询事务
Query SCN > Commit SCN,该行版本未被后续活跃事务修改,对当前事务可见;当前Data Page上的版本不可见,则沿着Undo链向上追溯,直到找到第一个满足条件的历史版本。
行锁原理描述
尽管MVCC解决了大部分读写冲突,但写-写冲突仍需通过锁机制来保障数据一致性。oGRAC 使用 ITL(Interested Transaction List,感兴趣事务列表)实现高效的行级锁管理。
ITL 结构与作用
ITL 并非集中式锁表,而是嵌入在每个数据页Page尾部的一个动态数组,Page页上的每行记录的头部记录ITL指针,用于记录当前页面中正在被哪些事务锁定的行信息。每个 ITL 条目包含事务 ID、锁类型、事务活跃状态、回滚段指针等。Page上默认存在2个ITL条目(假设同一个页面上事务并发的数量超过2个的概率较小),同一页面上的并发事务增加时可扩展ITL,最大支持255个,超过255个需要等待,ITL一旦扩展,其空间会保留在页中供后续使用,避免频繁分配开销。
行锁获取流程
当事务尝试对某行执行当前读或更新操作时,执行如下步骤:
检查该行是否已被锁定:查看 Row Header 是否指向某个活跃 ITL 条目,若存在且事务仍在运行,则等待该事务提交或回滚;若无冲突,申请当前页面上的ITL,设置待修改行的 Row Header ,开始执行修改操作,旧版本推入 Undo,并将新版本写入 Data Page。ITL锁释放时机为事务commit或者事务rollback。
机制优势
- 高并发读写性能:多数
SELECT操作通过一致读完成,无需加锁,彻底消除读写互斥,显著提升并发能力。 - 低行锁维护开销:基于 ITL 的行锁机制将锁信息本地化到数据页内部,减少全局锁管理的复杂性。
- 高效的存储结构:Data Page 仅保留最新版本,提高缓存命中率和 I/O 效率;历史版本按需从 Undo 加载,节省内存占用。
- 自动版本清理与回收:Undo 表空间支持自动回收,过期版本在无事务引用后被异步回收,防止无限膨胀。
- 良好的架构延续性:基于 SCN + Undo 的 MVCC 方案兼容性强,易于扩展。