【WiredTiger 内核】Rollback to Stable:把库收到稳定时间戳

💡 原文中文,约3700字,阅读约需9分钟。
📝

内容提要

本文介绍WiredTiger的Rollback to Stable(RTS)机制:当stable时间戳落后于durable或存在未提交事务时,RTS扫描表并移除不稳定修改,保留稳定版本。它跳过logged表,需独占数据库,完成后常执行checkpoint。RTS通过时间聚合减少读页,并处理History Store中的不稳定条目,确保恢复后数据一致性。

🔎

延伸解读

RTS 的触发与代价

RTS 在启动、关闭或应用显式调用时运行,且需要独占数据库,不允许并发事务。这意味着 RTS 是一个重量级操作,可能阻塞正常服务。此外,RTS 会产生大量 clean/dirty 页,带来 cache 与写 I/O 压力,因此在实际运维中需关注其执行频率和耗时。

RTS 与 History Store 的协作

RTS 不仅处理内存中的不稳定更新,还会清理 History Store 中的不稳定条目,并将稳定版本写回用户表。它通过时间聚合跳过无需处理的页,减少读页开销。但 HS 中可能出现 start==stop、prepared 回滚残留等非直觉形态,RTS 需专门校验,随后由 reconcile 清理。

RTS 与 Checkpoint 的关系

RTS 运行期间不能做 checkpoint,因为需要持有 checkpoint 锁且系统须静止。RTS 完成后通常再执行一次 checkpoint,使内存与磁盘一致(可配置跳过)。这种串行化设计保证了数据一致性,但也意味着 RTS 和 checkpoint 不能并发,可能影响整体性能。

Q&A

WiredTiger的Rollback to Stable(RTS)机制是什么?

RTS是WiredTiger在启动、关闭或应用显式调用时执行的一种恢复操作,它扫描数据库中的表,移除那些被视为不稳定的修改(即durable timestamp大于stable timestamp或事务未提交的修改),只保留stable的修改,从而将数据库恢复到稳定时间戳的状态。

哪些修改会被WiredTiger视为不稳定?

如果修改的durable timestamp大于stable timestamp,或者其事务ID在recovery checkpoint snapshot中判定为未提交,则该修改被视为不稳定。

WiredTiger的RTS会跳过哪些表?

RTS会跳过空表、没有设置stable时间戳的表、文件缺失或损坏的表、元数据专用表、logged表(因为logged表通过WAL实现commit级耐久,无需RTS),以及没有aggregated time window的旧版表(如MongoDB 4.4之前的表)。

RTS如何处理History Store中的不稳定条目?

RTS会使用标准History Store cursor,从最高start timestamp向旧删除到rollback时间戳为止,删除不稳定的History Store条目;同时,如果存在稳定的版本,会将其写回用户表。

RTS运行期间为什么不能执行checkpoint?

因为RTS需要独占数据库,不允许并发事务,并且需要持有checkpoint锁,系统必须静止,所以RTS运行期间不能执行checkpoint。RTS完成后通常会再执行一次checkpoint,使内存与磁盘一致。

RTS的dry-run模式有什么特点?

dry-run模式会走与正常RTS相同的访问路径,但不修改数据或History Store,仍然需要独占锁;统计信息只反映访问了哪些内容,不反映中止了多少更新。

RTS如何减少读取的页数?

RTS利用页上的时间聚合信息(time aggregate)与stable timestamp或recovery snapshot比较,跳过无需处理的页;对于internal页,不执行RTS更新逻辑,但仍会读入以导航到leaf页。

🏷️

标签

➡️

继续阅读