第 5 篇 说明更新挂在 insert list / update chain 上。要把脏页写成可持久、可驱逐的形态,必须做 reconciliation:把内存页翻译成一套 on-disk format 的页镜像。触发方主要是 Eviction 与 Checkpoint(第 4、9 篇);与 History Store 的写入契约在 Architecture Guide History Store 与 第 08 篇 已钉死,本篇补上「如何收镜像、何时分裂」。
本文是「WiredTiger 内核」系列第 6 篇(共 17 篇)。→ 系列目录
先修:第 4–5 篇。续读:第 7–8 篇;第 9 篇 Checkpoint。
版本锚定:
- Architecture Guide Version 12.0.0 /
develop:History Store、Eviction、Cache、Checkpoint- WiredTiger wiki Reconciliation overview(标注撰写于 2015 前后,可能落后于源码;分裂算法骨架仍作 A 级工程说明,字段名以
mongodb-8.0为准)- 源码
mongodb-8.0:src/reconcile/(入口__wt_reconcile等)、src/history/hs_rec.c(__wt_hs_insert_updates)
一、定义与触发
Wiki Reconciliation overview:
Reconciliation in WiredTiger is the process of translating a page from its memory resident form to a set of pages in on-disk format.
Cache 补充动机:内存布局为并发优化,磁盘布局为空间优化,读写都要转换。
| 触发 | 目的 |
|---|---|
| Dirty eviction | 腾 cache:reconcile 后写存储,再释放内存(第 4 篇) |
| Checkpoint | 为一致快照生成干净页版本(第 9 篇) |
| 其它内部路径 | 视版本而定;以源码调用点为准 |
入口函数(mongodb-8.0 / develop
同系注释):
/* wiredtiger: src/reconcile/rec_write.c */
int
__wt_reconcile(WT_SESSION_IMPL *session, WT_REF *ref, ...);注释口径:Reconcile an in-memory page into its on-disk format, and write it.(具体形参以标注分支为准。)
二、用户表 reconcile 与 History Store
Architecture Guide History Store 不变量:
用户文件 btree 上 reconcile 脏页时,检查 update chain,选出最新已提交更新作为 on-disk 值;尚未过时的更旧更新写入 History Store。
示意与第 08 篇相同:链上 U1@70 → U2@80 → U3@90 → U4@100(均已提交)时,用户页留 U4,U1–U3 进 HS,且 U1 的 stop 等于 U2 的 start。
源码侧把边界上保存的更新列表拷进 HS:
/* mongodb-8.0: src/history/hs_rec.c */
int
__wt_hs_insert_updates(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_MULTI *multi);Prepared 边界(Guide):页被 evict 时,prepared 更新写在用户表 on-disk 页上,更旧版本进 HS;HS 不应含 prepared 更新。提交/回滚时再改 HS 最新条目的 stop 或恢复 on-disk 值——细节见第 08、11 篇。
flowchart LR
chain["Update chain + inserts"] --> rec["Reconciliation"]
rec --> img["On-disk page image(s)"]
rec --> hs["History Store inserts"]
img --> bm["Block manager write"]
三、Row-store leaf:遍历顺序与分裂
Wiki 聚焦 row-store leaf(MongoDB
默认路径)。内存页上要合并的来源包括:读盘时的
WT_ROW 数组、各间隙的 insert list、各键的
update list(与第 3、5 篇一致)。
3.1 遍历与缓冲
Reconcile 时创建可容纳一页数据的缓冲,按顺序遍历:先看 insert list 头部,再交替处理「盘上键值 + 其更新」与下一条 insert,直到结束。键值按序拷入缓冲。
3.2 Split boundary
配置相关(wiki / WT_SESSION::create
文档):
| 项 | 含义 |
|---|---|
leaf_page_max |
on-disk 叶页最大尺寸 |
split_pct |
若内存页内容装不进单页,填充 on-disk 页时用到的
leaf_page_max 百分比 |
memory_page_max |
内存页可增长的上限(可更早因 cache 压力被 evict) |
internal_page_max 等 |
internal / overflow 相关;本篇不展开词典 |
算法骨架(wiki):
- 填充直到约
leaf_page_max * split_pct,记录 split boundary。 - 若全部内容在用尽页面前结束 → 写出单个 on-disk 页。
- 否则 → 在 split boundary
处切出一页镜像,把缓冲中多出的键值移回缓冲起点,继续按
split_pct切后续页。 - 消费完所有键值后,写出全部 disk-image。
分裂逻辑由 src/reconcile/rec_write.c 中的
__rec_split(wiki
命名;符号以当前分支为准)一类函数管理。
注意: wiki 标注 subject to change;今日实现还处理 reverse modify、乱序时间戳、与 checkpoint 并发等——那些是正确性补丁,不改变「内存页 → 一或多页磁盘镜像」的范式。
四、History Store 页的 reconcile
Guide:HS 自己的脏页被 reconcile 时,生成去掉 globally visible tombstone 后的新镜像,只保留 oldest reader / application oldest timestamp 仍需要的历史。这是 HS 文件收缩的机制入口之一(与 checkpoint 删「只含全局可见 tombstone 的页」衔接,第 8–9 篇)。
五、与 Eviction / Checkpoint 的分工
| 路径 | reconcile 角色 |
|---|---|
| Eviction | 为离开 cache 服务;dirty 路径写用户表 + 可能写 HS |
| Checkpoint | 为一致持久化点服务;遍历脏页 reconcile;先用户表后 HS(因用户表 reconcile 会向 HS 追加写) |
Checkpoint 对「eviction 已提前写干净的页」仍可跳过,即使该写出更新对 checkpoint 事务未必可见——Guide Checkpoint 保证的是:树中每个页都存在可落盘的 clean 版本。细节第 9 篇。
六、工程间隙与开放问题
- Wiki 年代:2015 起稿的布局叙述与
mongodb-8.0字段别名可能不一致;冲突时以 Guide + 源码为准。 - 压缩:on-disk image 写出前可压缩(第 12 篇);reconcile 本身先谈逻辑镜像与分裂。
- 开放问题: 高频小更新导致的反复 reconcile / HS 写入放大,是否可用增量历史编码缓解——第 08 篇开放问题 1;本篇不给未测数字。
七、收束
- Reconciliation = 内存页 →(一或多页)on-disk image,并写出。
- 用户表路径上:最新已提交 → 用户页镜像;更旧未过时 → History Store。
- 分裂由
leaf_page_max/split_pct等配置约束;实现见src/reconcile/。
下一篇:Timestamps、Snapshot 与事务——决定链上哪一环「已提交且可见」,从而决定 reconcile 选谁上盘。
参考资料
规范 / 官方文档 / Wiki
- WiredTiger wiki, Reconciliation overview:https://github.com/wiredtiger/wiredtiger/wiki/Reconciliation-overview
- WiredTiger Architecture Guide, History Store、Eviction、Checkpoint、Cache
- WiredTiger, Tuning page size and compression(页大小与 reconcile 关系)
源码
mongodb-8.0:src/reconcile/(rec_write.c等)、src/history/hs_rec.c(__wt_hs_insert_updates)
站内
上一篇:B-Tree
与 update chain
下一篇:Timestamps、Snapshot
与事务
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【WiredTiger 内核】文档库存储引擎全景:MongoDB 默认引擎的生态位
定位文档库默认引擎 WiredTiger 相对 PG/InnoDB/SQLite/RocksDB 的生态位;钉住 Session→Cache→Reconcile→HS→Checkpoint 主线、站内分工与 17 篇阅读路线,并以 Berenson 隔离词汇与 Durable History 为学术/工程锚点。
【WiredTiger 内核】Cache · Eviction · Reconciliation · History Store · Checkpoint
补齐文档库默认引擎内核层:从 Connection/Session、Cache/Eviction、B-Tree update chain、Reconciliation 到 Timestamps、History Store、Checkpoint/Journal 与 Rollback-to-Stable,并以 MongoDB 嵌入边界与 PG/InnoDB/RocksDB 对照收束。
【WiredTiger 内核】Eviction:脏页必须先 reconcile
拆解 WiredTiger Eviction 的 server/worker/队列、target/trigger 阈值,以及 dirty eviction 经 reconciliation 把最新值写入用户表、旧版本写入 History Store;说明应用线程被迫协助驱逐的条件。
【WiredTiger 内核】Checkpoint:跨文件一致快照
拆解 WiredTiger checkpoint 算法:先借 eviction 减压,再按用户表→History Store→元数据顺序 reconcile 并原子切换;说明 checkpoint generation 与 eviction 的可见性约束,以及与 journal 的耐久分工。