【WiredTiger 内核】Block manager、页格式与压缩

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

内容提要

本文介绍WiredTiger存储引擎的Block Manager子系统。每个数据文件由若干块组成,采用无覆盖分配策略,重写时写入新位置。块通过address cookie寻址,包含偏移、大小和校验和。分配使用best fit或first fit策略,checkpoint维护alloc、avail、discard三张extent列表管理空间。写入时计算校验和,支持压缩。旧checkpoint删除后块才可复用。

🔎

延伸解读

无覆盖分配与崩溃安全

WiredTiger 采用 no-overwrite 策略,重写数据时写入新位置,旧块在所属 checkpoint 删除后才可复用。这种设计避免了崩溃时半写块被读取的风险,因为正在覆盖的块不会被写入原位置。理解这一点有助于解释为何 WiredTiger 文件可能比实际数据大,以及为何 checkpoint 删除前空间不会立即释放。

extent 列表与空间管理

每个 checkpoint 维护 alloc、avail、discard 三张 extent 列表,分别记录新分配、可用和释放的区间。avail 列表按大小排序以加速 best fit 分配。当某块在旧 checkpoint 的 alloc 列表和新 checkpoint 的 discard 列表同时出现时,该块可被回收。这种机制确保了空间在 checkpoint 合并或删除后能被安全复用。

校验和与压缩的权衡

校验和默认开启,对写入缓冲做全长校验,关闭时仅校验前 64 字节,这提供了性能与安全性的权衡。压缩在 reconcile 生成逻辑镜像后、块写出前进行,可减少磁盘占用,但会增加 CPU 开销。MongoDB 允许配置压缩算法,用户需根据工作负载平衡压缩率与性能。

Q&A

WiredTiger的Block Manager主要负责什么?

Block Manager是WiredTiger存储引擎中负责磁盘读写的子系统,目标是高性能、省空间与可定制。它管理数据文件的块分配、地址cookie、校验和、压缩以及空间回收。

WiredTiger的块分配策略有哪些?分别适用于什么场景?

WiredTiger有两种块分配策略:Best fit(默认)在按大小排序的avail extent skiplist上找精确或下一更大空闲段,减少碎片;First fit放进第一个可用extent,所有root页用first fit,compaction期间也切换到first fit。

WiredTiger的address cookie包含哪些信息?

Address cookie包含offset(按allocation_size缩放)、可选的object_id(用于tiered storage)、size(同样缩放)和checksum。它用于对上层不透明地寻址块。

WiredTiger的checkpoint如何管理空间回收?

每个checkpoint维护三张extent list:alloc(新分配)、avail(未使用可分配)、discard(释放的区间)。当旧checkpoint删除时,如果某块同时出现在某代的alloc和更后代的discard中,则可进入avail,实现空间复用。

WiredTiger的校验和是如何工作的?

当checksum=on(默认常开)时,对写入缓冲做全长checksum;关闭时仍可能只校验缓冲前64字节。读取时,cookie内的checksum必须与内容计算值一致。

WiredTiger的压缩在哪个阶段进行?

压缩在reconcile生成逻辑镜像后、块写出路径上进行。MongoDB可配置表/journal压缩算法,但具体实现细节(如snappy/zstd)不在本文展开。

WiredTiger的no-overwrite策略是什么?

WiredTiger采用no-overwrite策略:重写内容时写到文件新位置,旧块在所属checkpoint删除后才可复用。这样崩溃时正在覆盖的半写块会被避开。

🏷️

标签

➡️

继续阅读