加载中...

| InnoDB 旧版本存储位置 | Undo Log(回滚段) |
| PostgreSQL 旧版本存储 | 堆表页内(需 VACUUM 清理) |
| 解决的核心问题 | 读写不互相阻塞 |
MVCC(Multi-Version Concurrency Control)的核心思想是:写操作不覆盖旧数据,而是创建新版本;读操作根据自己的事务时间戳选择一个可见的历史版本来读取。这样读和写操作在大多数情况下互不阻塞。
InnoDB 在每行数据上隐式附加两个字段:DB_TRX_ID(最后修改该行的事务 ID)和 DB_ROLL_PTR(指向 Undo Log 中旧版本的指针)。读操作通过这个链表向前追溯,找到在当前事务开始时就已提交的最新版本——这个版本链就是 MVCC 的数据基础。[1]
InnoDB 在事务执行快照读时会生成一个 ReadView,记录当前活跃的事务 ID 列表(m_ids)、最小活跃事务 ID(m_up_limit_id)和下一个分配的事务 ID(m_low_limit_id)。判断某个版本是否对当前事务可见,就是拿该版本的 DB_TRX_ID 与 ReadView 进行比对。
可重复读级别下,ReadView 在事务第一条 SQL 执行时创建,之后整个事务都用同一个;读已提交级别下,每条 SQL 都创建新的 ReadView,所以能看到最新提交的数据。这就是两种隔离级别行为差异的底层原因。
PostgreSQL 的 MVCC 实现有所不同:旧版本直接存储在堆表的数据页中(死元组),需要定期通过 VACUUM 清理,否则会造成表膨胀和性能下降。

| InnoDB 旧版本存储位置 | Undo Log(回滚段) |
| PostgreSQL 旧版本存储 | 堆表页内(需 VACUUM 清理) |
| 解决的核心问题 | 读写不互相阻塞 |
登录 后参与讨论
暂无讨论,来发表第一条评论吧