好的,我们来系统地比较几种主流数据库的 MVCC(多版本并发控制)实现,包括其 机制、优缺点、版本存储方式、读写冲突处理 等。为了清晰,我整理成表格和分析。
1️⃣ MVCC概念回顾
MVCC (Multi-Version Concurrency Control) 是一种数据库并发控制技术,通过为数据行保存多个版本来允许 读操作不阻塞写操作,同时保证事务的隔离性(通常可达 可重复读(Repeatable Read)或快照隔离(Snapshot Isolation))。
MVCC 的核心:
- 每条记录有多个版本(历史版本)
- 事务读取时根据时间戳/事务ID选择可见版本
- 写操作创建新版本而不直接覆盖旧版本
2️⃣ 主流数据库 MVCC 对比
数据库 | 版本存储方式 | 事务可见性判定 | 写入策略 | 清理历史版本 | 特点与限制 |
---|---|---|---|---|---|
MySQL InnoDB | 行内隐藏字段:DB_TRX_ID (创建事务ID)、DB_ROLL_PTR (回滚指针) | 通过事务ID判断版本是否可见 | 更新操作生成新版本(undo log) | 后台线程 purge 旧版本 | 读不会阻塞写;快照读支持可重复读;大量更新/删除需注意 undo log 空间 |
PostgreSQL | Tuple header 保存 xmin (创建事务ID)、xmax (删除事务ID) | 判断 xmin <= 当前事务ID < xmax | 更新生成新行(old row 保留) | VACUUM 定期回收死行 | MVCC实现完整;可实现快照隔离;VACUUM 必须维护,否则表膨胀 |
Oracle | Undo 表空间 + SCN(系统变更号) | 读取时通过 SCN 获取版本 | 写操作写入数据文件,新旧版本保存在 undo 表空间 | 自动回收 | 强大的事务一致性;支持读不阻塞写;读取历史数据方便 |
SQL Server (Snapshot Isolation) | TempDB + row version | 根据版本号判断可见性 | 更新生成新版本保存在 TempDB | 自动清理 | 支持快照隔离;需要 TempDB 空间;可能导致 TempDB 瓶颈 |
CockroachDB / TiDB | MVCC + 分布式时间戳(TSO) | 根据时间戳判断版本可见 | 写操作生成新版本 | 垃圾回收(GC)定期清理旧版本 | 分布式支持;行级 MVCC;读写不阻塞;需要 GC 配置 |
3️⃣ 对比分析
3.1 版本存储
- InnoDB:undo log 内部保存历史版本
- PostgreSQL:每行 tuple header 直接保存 xmin/xmax
- Oracle:undo 表空间
- SQL Server:TempDB
- TiDB/CockroachDB:分布式存储 + 时间戳
3.2 读写冲突
- 读不阻塞写:几乎所有支持 MVCC 的数据库都可做到
- 写写冲突:InnoDB/Oracle/PG 都使用行级锁或事务检测
- 快照隔离支持:
- PostgreSQL 默认支持快照隔离
- MySQL InnoDB 可在可重复读下使用
- SQL Server 需开启 Snapshot Isolation
3.3 历史版本清理
- InnoDB:purge 线程自动清理 undo log
- PostgreSQL:VACUUM
- Oracle:自动管理 undo 表空间
- SQL Server:TempDB 自动清理
- TiDB/CockroachDB:GC 策略清理旧版本
4️⃣ 小结
特性 | MySQL InnoDB | PostgreSQL | Oracle | SQL Server | TiDB/CockroachDB |
---|---|---|---|---|---|
版本存储 | Undo log | Tuple header | Undo tablespace | TempDB | 分布式 MVCC |
隔离级别 | RR / RC | RR / SI | SI / Serializable | Snapshot | SI / RC / Serializable |
读写阻塞 | 无 | 无 | 无 | 无 | 无 |
清理历史 | purge | VACUUM | 自动 | 自动 | GC |
优点 | 简单高效 | 灵活,历史数据可追踪 | 强一致性 | 快照隔离 | 分布式支持 |
缺点 | Undo log 空间可能膨胀 | VACUUM 必须维护 | undo 空间压力 | TempDB 瓶颈 | GC 参数复杂 |
发表回复