底层二进制格式单元说明(存储 × 线格式)
本文是 KernLab.Tier 全系列二进制格式的互操作手册——外部解析工具 / 审计 / 数据恢复 / 其他语言
实现可据此解析全套磁盘存储格式与网络线格式。每个格式给出字节图、字段表、CRC/校验、版本演进
与源码位置;精确到字节(偏移/宽度/端序),与生成 Codec([BinaryLayout] 声明即代码)一致。
覆盖范围:Runtime 存储结构(磁盘可解析)× Products 产品封装 × Core.Net 网络线格式。 与使用指南的关系:log.md/storage-engine.md/tierwal.md 等讲行为,本文讲字节。
代码引用为仓库相对路径(Structures/… = src/KernLab.Tier.Runtime/Structures/…)。
1. 通用约定(跨全部格式族)
| 约定 | 值 |
|---|---|
| 端序 | 全多字节标量 Little-Endian(生成 Codec 统一 Write*LittleEndian) |
| CRC32C | Castagnoli 反射多项式 0x82F63B78;规范 init 0xFFFFFFFF、final XOR 0xFFFFFFFF |
| CRC64 | ECMA-182 Annex B 多项式 0x42F0E1EBA9EA3693;init 0、无异或输出(≠ zlib 式) |
LogicalAddress(16B) |
[0] SegId int LE + [4] Extension int LE + [8] Offset long LE;Empty=(0,0,0)、Invalid=(-1,-1,-1) |
NodeId(16B) |
不透明字节串(Opaque16:_hi@0/_lo@8 双 ulong,小端承载字 = 字节原序直拷) |
| Magic 常量 | 全 uint32 LE 落盘,登记于 src/KernLab.Tier.Contracts/Layout/RecordMagic.cs |
| 版本编码 | major << 8 \| minor(ushort);Version 字段语义由各格式自述 |
| flags 位约定 | bits0-1 = CRC 算法(0x00 无 /0x01 CRC32 /0x02 CRC64 /0x03 CRC32C);bit2 FLAG_CRC_IN_FOOTER(0x04);bits3-4 payload 宽度(0x08=2B /0x10=4B /0x18=8B);bit7 FLAG_ENTRY_IS_META(0x80);bit12 FLAG_FOOTER_MAGIC(0x1000) |
2. 存储结构格式(Runtime)
2.1 Log 页帧(LogPageFrame)
EntryLog/DeltaLog 的物理写单元——N 条 entry 攒满一页(默认 4MiB)组帧写入引擎地址空间。
[LogPageFrameHeader 8B][data: alignedLen B][Crc32Footer 4B][padding: 0..Sector-1 B]
0 8 8+alignedLen
| 偏移 | 宽度 | 字段 | 校验/含义 |
|---|---|---|---|
| 0 | 4 | MagicValue | 0x4647504C "LPGF" |
| 4 | 4 | DataLength | 数据区有效字节数 = AlignUp(pageUsed, Sector)(读侧定界) |
| 8 | alignedLen | data | entry 流(见 2.2/2.3) |
| 8+alignedLen | 4 | Crc | CRC32C,覆盖 [0, 8+alignedLen)(header+data,不含 padding) |
| 后 | var | padding | 全零,把整帧撑到扇区对齐 |
无版本字段;DataLength 即写侧对齐字节数,恢复端按帧头前向扫描。
源码:Structures/Log/LogPageFrameHeader.cs、LogBase.Write.cs:328-417、LogBase.Recovery.cs:144-282。
2.2 EntryLog entry 头(22B,CRC64 in-Header)
raft WAL 底层单条记录头,data 区内连续、每条 4B 对齐。
[MagicValue 4][Version 2][Flags 2][PayloadLength 4][PaddingLength 2][Crc64 8][payload][padding 4 对齐]
0 4 6 8 12 14 22
| 偏移 | 宽度 | 字段 | 校验/含义 |
|---|---|---|---|
| 0 | 4 | MagicValue | 0x474F4C45 "ELOG" |
| 4 | 2 | Version | 0x0100 |
| 6 | 2 | Flags | 含 0x32 = CRC64(0x02)|PAYLOAD_4B(0x10)|META_EMBEDDED(0x20);可叠加 FLAG_ENTRY_IS_META(0x80) |
| 8 | 4 | PayloadLength | ≤ 4MiB(MaxEntrySize=1<<22) |
| 12 | 2 | PaddingLength | 4B 对齐补零 |
| 14 | 8 | Crc | CRC64 in-Header——覆盖 [0,14) ∪ {Crc 置零 8B} ∪ [22, 22+payload+padding) |
源码:Structures/Log/EntryLog.Header.cs:16-48、EntryLog.Codec.cs:26-63。
2.3 DeltaLog entry 头(18B,CRC32C in-Header)
临时增量日志记录头,与 EntryLog 同构。
[Magic 4][Version 2][Flags 2][PayloadLength 4][PaddingLength 2][Crc32C 4][payload][padding]
0 4 6 8 12 14
| 偏移 | 宽度 | 字段 | 含义 |
|---|---|---|---|
| 0 | 4 | MagicValue | 0x474F4C44 "DLOG" |
| 6 | 2 | Flags | 含 0x33 = CRC32C(0x03)|PAYLOAD_4B|META_EMBEDDED |
| 14 | 4 | Crc | CRC32C in-Header(覆盖同 2.2 语义) |
源码:Structures/Log/DeltaLog.Header.cs:16-49、DeltaLog.Codec.cs:26-71。
2.4 LogMeta 水位块(12B + 80B(+opaque) + 4B)
Log 持久化水位 / 2PC 事务恢复元数据(MetaPolicy 原子落盘)。
[LogMetaHeader 12B][LogMetaPayload 80B + opaque][Crc32Footer 4B]
LogMetaHeader(12B):[0] Magic 0x44484D4C "LMHD" + [4] Version 0x0100 + [6] Flags 0x4B(CRC32C|PAYLOAD_2B|CRC_IN_FOOTER|META_STANDALONE)+ [8] PayloadLength 2B + [10] PaddingLength 2B。
LogMetaPayload(80B):
| 偏移 | 宽度 | 字段 |
|---|---|---|
| 0 | 16 | BeginAddress(头回收边界) |
| 16 | 16 | TailAddress(写游标) |
| 32 | 16 | CommittedOffset(group commit 落盘边界) |
| 48 | 8 | LastCommittedSeq(-1 = 未参与事务) |
| 56 | 8 | LastPreparedSeq(-1 = 从未 Prepare) |
| 64 | 16 | PreparedTailAddress(2PC Abort 回退点;Empty = 无窗口) |
CRC:CRC32C 落尾部 Crc32Footer(offset 12+PayloadLength),覆盖 [0, 12+PayloadLength)。
源码:Structures/Log/Contracts/LogMetaHeader.cs、LogMetaPayload.cs、LogBase.LogMeta.cs:103-112。
2.5 Ring 记录帧(BlittableRing record,40B)
Ring = 产品数据真源(Kv/TimeSeries/Blob 共用),记录直接裸写在引擎页内存(无页帧包裹)。
[BlittableRingHeader 40B][key: sizeof(TKey) B][value: 8B..N B][padding 8 对齐]
0 40
[Magic 4][Ver 2][Flags 2][PayloadLength 4][PadLen 2][PreviousAddress 16][Reserved 4][Crc32C 4]
0 4 6 8 12 16 32 36
| 偏移 | 宽度 | 字段 | 含义 |
|---|---|---|---|
| 0 | 4 | MagicValue | 0x44485242 "BRHD" |
| 4 | 2 | Version | 0x0200(v2 泛型改版——KeyLength 字段退役,key 长度 = sizeof(TKey) 类型事实) |
| 6 | 2 | Flags | 含 0x13 = CRC32C(0x03)|PAYLOAD_4B(0x10);状态位 bits8-11:0x0100=VALID /0x0200=TOMBSTONE /0x0400=SEALED /0x0800=INNEWVERSION;0x2000=VALUE_OVERFLOW |
| 8 | 4 | PayloadLength | = KeySize + ValueLength(数据记录)或 blockSize(meta 记录) |
| 12 | 2 | PaddingLength | 8 对齐补零 |
| 16 | 16 | PreviousAddress | 版本链前驱(8B 对齐) |
| 32 | 4 | Reserved | 恒 0(写零防 CRC 脏字节) |
| 36 | 4 | Crc32C | in-Header,覆盖 [0, 40+PayloadLength),Crc 区置零 |
- key 以原始 blittable 字节直写(
Unsafe.WriteUnaligned);value 紧随;溢出记录 value 区 = 24BAddressInfo([0] LogicalAddress 16B+[16] long Size)。 - 空位判定 =
Magic==0(从未写入槽)。 - Ring 7 水位 CAS128(内存态):7 个 16B 槽经
NativeAtomic128原子单调推进——槽序Begin/FlushedUntil/ReadOnly/SafeReadOnly/Head/SafeHead/ClosedUntil;盘上持久化的是 2.7 的子集。
源码:Structures/Ring/BlittableRing.Header.cs:19-48、BlittableRing.Codec.cs、RingBase.Watermarks.cs。
2.6 OverflowRecord(18B)
WiscKey value-log 溢出帧(大值分块写)。
[Magic 4][Ver 2][Flags 2][PayloadLength 4][PadLen 2][Crc32C 4][value][padding 4 对齐]
0 4 6 8 12 14
CRC32C 覆盖 [0,14)(Crc 区外)+ value + padding。版本 0x0100。
源码:Structures/Ring/Contracts/OverflowRecordHeader.cs:14-28。
2.7 RingMeta 水位块(12B + 132B + 4B)
Header 与 LogMeta 同构(Magic 0x44484D52 "RMHD"、Version 0x0100、Flags 0x4B)。Payload 132B:
| 偏移 | 宽度 | 字段 |
|---|---|---|
| 0 | 16 | BeginAddress |
| 16 | 16 | FlushedUntilAddress |
| 32 | 16 | SafeReadOnlyAddress |
| 48 | 16 | ReadOnlyAddress |
| 64 | 16 | TailAddress |
| 80 | 8 | LastCommittedSeq |
| 88 | 8 | LastPreparedSeq |
| 96 | 16 | OverflowTailAddress |
| 112 | 4 | KeySize(打开时与实例 sizeof(TKey) 校验) |
| 116 | 16 | CommittedTailAddress(2PC Abort 回退点) |
HeadAddress/SafeHeadAddress/ClosedUntilAddress 不落盘(恢复从 BeginAddress 重建)。CRC32C 尾部 footer。
源码:Structures/Ring/Contracts/RingMetaHeader.cs、RingMetaPayload.cs:18-46。
2.8 段元组(SegmentTuple,36B + 变长 + 4B)
段表恢复时逐段的磁盘权威(per-segment FileExtra 元数据)。
[MagicValue 8][Ver 1][State 1][MaxOffset 8][GrowthLimit 8][RealSize 8][SummaryLength 2][Summary var][CRC32C 4]
0 8 9 10 18 26 34 36
| 偏移 | 宽度 | 字段 | 含义 |
|---|---|---|---|
| 0 | 8 | MagicValue | 0x54435F5345475455 "TC_SEGTU" |
| 8 | 1 | Version | = 2 |
| 9 | 1 | State | StableState 枚举 |
| 10 | 8 | MaxOffset | 段已提交水位 |
| 18 | 8 | GrowthLimit | 段生长上限 |
| 26 | 8 | RealSize | 物理大小 |
| 34 | 2 | SummaryLength | 区间摘要字节数(0 = 无摘要;预算 ≤ 1496B) |
| 36+len | 4 | CRC32C | 覆盖 [0, 36+len) |
SegId 不编码(文件名 data.{segId} 承载)。段表盘上无独立"地址表文件"——恢复走扫盘
(枚举段文件 + 读段元组 → LoadAddressTable);footer 双尾水位由 meta/扫盘现算。
源码:src/KernLab.Tier.Runtime/Storage/SegmentTupleCodec.cs:13-108、AddressSpace/SegmentTable.Checkpoint.cs。
2.9 索引帧
ProbingIndex 主存储帧(探测族 = HashIndex):[Header 20B][Body: BodyLength B][Footer 32B] 紧邻连续。
- Header(Magic
0x44484950"IXHD",Version 0x0100,Flags0x1002=CRC64|FOOTER_MAGIC):[0]Magic 4[4]Version 2[6]Flags 2[8]Kind 2[10]Reserved 2[12]BodyLength 8。 - Body 首部 32B
HashIndexGeometry:[0]TableSize 8[8]OverflowCapacity 8[16]EntryCount 8[24]OverflowCount 8。 - Footer(Magic
0x54464950"IXFT"):[0]Magic 4[4]Reserved 4[8]Watermark W 16B[24]Crc64 8。CRC64 覆盖 Header+Body+Footer 前 24B。 - 帧走版本链(N 版轮替),恢复从 MinAddress 前向扫帧、CRC 总验收取最新完整帧。
SortedIndex 固定锚点帧(BTree/SkipList,84B 定长):[Header 20B][Geometry 32B][Footer 32B]。
- Header(BTree Magic
0x44484942"BIHD";SkipList0x44484C53"SLHD"):结构同 Probing。 - BTree 几何:
[0]RootSegId 4[4]RootExtension 4[8]RootOffset 8[16]EntryCount 8[24]NodeStructSize 4[28]Reserved 4。 - SkipList 几何:
[0]CurrentLevel 4[4]pad 4[8]EntryCount 8[16]HeadSegId 4[20]HeadExtension 4[24]HeadOffset 8。 - Footer(BTree
0x54464942"BIFT";SkipList0x54464C53"SLFT"):[0]Magic 4[4]Reserved 4[8]Watermark W 16B[24]Crc64 8。 - 恢复直读 MinAddress 锚点 + CRC 总验收,W∈[Begin,End] 校验,失败 fail-safe 全量重放。
- 盘上 Kind 恒 0(
SortedIndexConstants.KindSorted=0——与ProbingIndexFormat.KindSorted=1常量存在源码不一致,BTree/SkipList 实际写/验 0)。
源码:Structures/ProbingIndex/ProbingIndexFormat.cs、Structures/SortedIndex/Layout/*、SortedIndexBase.Persistence.cs。
2.10 快照帧
IncrementalSnapshot 段帧(一帧 = 一次增量):
[StreamFrameHeader 14B][N₀ 前缀 8B + 条目流(扇区对齐填充)][StreamFrameFooter 28B]
- Header(Magic
0x44484E53"SNHD",Version 0x0100,Flags0x1016=CRC64|PAYLOAD_4B|CRC_IN_FOOTER|FOOTER_MAGIC):[0]Magic 4[4]Version 2[6]Flags 2[8]PayloadLength 4[12]PaddingLength 2。 - Footer(28B,Magic
0x54464E53"SNFT"):[0]Magic 4[4]TotalLength 8[12]EntryCount 8[20]Crc64 8。 - CRC64 覆盖 Header + data(N₀ 前缀 + 条目流)+ Footer 前 20B。
TotalLength = 8(N₀) + Σchunk。 - 段表 opaque(meta 载体):
[Count 4B LE][pad 4B][条目 40B × N],每条 = LogicalStart(16B) + PhysStart(16B) + N₀(8B)。
SnapshotBase meta 水位(12B + 80B + 4B):Header Magic 0x444D4E53 "SNMD"。Payload 80B:
[0]WriteAddress 16 [16]PhysicalWriteAddress 16 [32]TruncatedAddress 16 [48]CommittedWriteAddress 16(Abort 回退点) [64]LastCommittedSeq 8 [72]LastPreparedSeq 8。
源码:Structures/Snapshot/IncrementalSnapshot.cs、StreamSnapshot.Header.cs、Contracts/SnapshotMetaHeader.cs。
2.11 TierVolume 虚拟卷盘上格式(Core.IO virtual:// 介质)
.tier 虚拟磁盘文件(TierVolumeFs)的完整盘上布局——superblock + 位图 + journal + delta +
数据 extent。崩溃一致性 = CoW 元数据 + superblock 代数翻转(单一原子提交点)。
卷布局总览:
[Superblock 4096B @0] [位图区] [Journal 区] [镜像区(检查点)] [数据区]
主侧 superblock → 备份侧 superblock(代数+1 翻转)——双侧轮替
Superblock(4096B,"RAW1")——标量区 + 表区 + Crc@4088:
| 偏移 | 宽度 | 字段 | 含义 |
|---|---|---|---|
| 0 | 4 | MagicValue | 0x31574152 "RAW1" |
| 4 | 2 | Version | — |
| 6 | 2 | Flags | — |
| 8 | 4 | BlockSize | 块大小(字节) |
| 12 | 8 | CapacityBlocks | 卷容量(块) |
| 20 | 8 | BitmapStart / BitmapBlocks | 位图区位置 |
| 36 | 4 | ImageRunCount | 镜像区间数 |
| 136 | 8 | ImageLength / ImageCrc | 镜像长度 + CRC |
| 148 | 8 | Generation | 代数(崩溃一致性翻转点) |
| 172 | 2 | CarrierIndex | 成员载体索引 |
| 174 | 4 | MemberCount | 成员数 |
| 178 | 8 | JournalStart / JournalBlocks / JournalGeneration / JournalState / JournalCkptLsn / JournalHeadLsn | journal 区(日志模式检查点) |
| 4088 | 4 | Crc | CRC32C 覆盖 [0, 4088) |
表区几何(固定容量槽,v1 冻结格式):image runs 8×12B(SuperblockImageRun:[0] Start u64 + [8] Count u32)、members 8×40B(SuperblockMember:uuid 16B 裸区 + [16] CapacityBlocks + [24] BitmapStartLocal + [32] BitmapBlocksLocal)、snapshots 16×180B(SuperblockSnapshot:name 32B + ticks/lsn/runs 表 ≤8×12 + image 字段 + bitmap 字段 + inUse)。
成员载体身份头(512B,"RAWC"):[0] Magic 4 [4] Version 2 [24] CarrierIndex 4 [28] BitmapStartLocal 8 [36] BitmapBlocksLocal 8 [44] Capacity 8 [508] Crc 4(CRC32C 覆盖 [0,508))。uuid 裸区 @8..24。
位图(空间事实真相源):1 bit/块,容量成比例、格式化时静态定长;64 块对齐(保证位字不跨成员——BitmapAlignBlocks=64);小端位序(位 i 在字 i/64 的位 i%64)。
Journal 帧(32B,"RJRN"):[0] Magic 4 [4] Type 1B [8] Lsn u64 [16] Generation u64 [24] BodyLength u32 [28] BodyCrc u32。记录类型(JournalRecordType):FileCreate=1 / FileDelete=2 / FileMove=3 / DirCreate=4 / DirDelete=5 / DirMove=6 / SetLength=7 / ExtentTailExtend=8 / ExtentAppend=9 / ExtentCover=10 / PunchHole=11(+)。日志模式:WAL 记录先于屏障、LSn 发射预分配、检查点 CkptLsn 前进 + 区代数复位随 superblock 翻转原子生效。
Delta 流(跨载体增量/快照):文件头 44B [Magic "TCD1"][Ver][Flags][BlockSize 4][uuid 16B 裸区][BaseLsn 8][BaseCrc 4][HeaderCrc 4];数据段 12B [Magic "TCD3"][Count u64] + 条目 12B [Block u64][BlockCrc u32];流尾 16B [Magic "TCD2"][Count u64][PayloadCrc u32]。
区间状态(文件 extent,ExtentState):Unwritten=0(预分配 fallocate 语义——物理已留、读零、写时转 Written)/ Written=1(已写数据);Sparse 洞 = 无 extent 条目(读零)——"区间三态" = 洞 / Unwritten / Written。
崩溃一致性:CommitMetadata——元数据序列化为镜像 → 新块落盘(旧块不动 = CoW)→ 位图落盘 → 备份侧翻转(代数+1)→ 主侧翻转。提交序不变量:数据先于元数据、元数据先于翻转。恢复:取 CRC 有效且代数最高的一份 superblock → 载入其镜像 → dirty 则可达性对账重写位图(孤儿回收——未提交的分配消失,位图 = 可达集恢复)→ 可写继续。
源码:src/KernLab.Tier.Core/IO/TierVolume/TierVolumeFrameLayouts.cs、TierVolumeFs.Superblock.cs、TierVolumeFs.Bitmap.cs、TierVolumeFs.Journal.cs、TierVolumeFs.Consistency.cs、TierVolumeFs.Delta.cs、TierVolumeFs.Metadata.cs。
3. 产品格式(Products)
3.1 TierWAL 数据帧 + opaque 容器
raft 条目载荷帧前缀(9B,TierWalRaftStore 层):[Term 8B LE][Kind 1B][entry content …]——index 由 WAL 起点 + 顺序计数推导,帧内零 index。
TierWAL opaque 容器(WalOpaqueHeader,56B + raft meta 预留区):
[Magic 4B][Version 2B][pad 2B][TailIndex 8B][TailAddress 16B][HeadIndex 8B][HeadAddress 16B][raft meta …]
0 4 6-7 8 16 32 40 56
| 偏移 | 宽度 | 字段 | 含义 |
|---|---|---|---|
| 0 | 4 | MagicValue | 0x44484C57 "WLHD" |
| 4 | 2 | Version | 0x0100 |
| 8 | 8 | TailIndex | 最后一条已分配 entry index(持久化水位) |
| 16 | 16 | TailAddress | 尾 index 对应 record 地址 |
| 32 | 8 | HeadIndex | 头截断边界 index |
| 40 | 16 | HeadAddress | 头边界地址 |
| 56 | var | raft meta | 原样追加(内容零知识;容量 = MetaOpaqueBytes - 56) |
⚠ 注意:段 anchor 表(24B/条 = index 8B + LogicalAddress 16B,每 AnchorInterval=1024 条一个)是纯内存结构,不落盘(恢复从头顺序扫重建)——opaque 只记 head/tail 两个锚点。
TierWAL raft 元数据 opaque(RaftStoreMeta,41B,Products.Net):[Version 1B][Term 8B][VotedFor 16B][AppliedIndex 8B][SnapshotIndex 8B]。
TierWAL 快照传输格式:Header 14B([Magic 4B "WTHD"][Version 2B][SnapshotIndex 8B]);Payload 帧 [PayloadLength 4B][payload];Footer 24B([Magic 4B "WTFT"][EntryCount 8B][TotalPayload 8B][Crc32C 4B],CRC32C 增量覆盖 Header+全部 payload 帧字节)。
源码:Products/Wal/WalOpaqueHeader.cs、WalOpaqueLayout.cs、WalSnapshotFormat.cs、Products.Net/RaftStore/TierWalRaftStore.Layouts.cs:40-71。
3.2 Kv 值帧 + KvVersionOpaque
KvValueFrameHeader(9B):[Tag 1B = 0xC8][ExpiryTicks 8B LE] + payload。ExpiryTicks = UTC Ticks(0 = 无过期)。全量封装不变式:经 TierKv 写入的一切值都带帧(无 TTL = ticks 0)——读侧嗅探 tag 无歧义。
KvVersionOpaque(24B,Ring opaque meta):
[0..8) HighWater 8B LE 已分配最高版本
[8..12) Magic 4B LE 0x544B5631 "TKV1"(代际守卫)
[12..16) SweepSegId 4B LE 过期回收扫描水位 SegId(<0 = 未持久化态)
[16..24) SweepOffset 8B LE 扫描水位 Offset
旧 12B 块兼容(仅 HighWater+Magic)。版本随 2PC Prepare 同块原子落盘。
源码:Products/Kv/KvValueFraming.cs、KvVersionAllocator.cs。
3.3 TimeSeries 键 / envelope / 水位
TimeKey(16B,单序列):[Timestamp 8B][Tiebreaker 8B] LE。Ring record key = (Timestamp, 0);索引 key = (Timestamp, addr.Offset)。
DenseTimeKey(20B,dense 多序列):[SeriesId 4B uint][Timestamp 8B][Tiebreaker 8B](SeriesId 领先 → 单树逐序列键域连续)。
TTS1 envelope 头(21B,单序列):[Magic 4B "TTS1"=0x31535454][Flags 1B][Timestamp 8B][Seq 8B] + payload;Flags bit0 HAS_SEQ(0x1)。
TTS2 envelope 头(25B,dense):[Magic 4B "TTS2"=0x32535454][Flags 1B][SeriesId 4B][Timestamp 8B][Seq 8B] + payload。两模式 magic 换代互不误读。
TimeSeriesWatermarkState(40B,VersionedMetadata payload):[0..8) TrimmedUntilTimestamp 8 [8..12) TrimmedSegId 4 [12..16) TrimmedExtension 4 [16..24) TrimmedOffset 8 [24..32) SampleCount 8 [32..40) WatermarkEpoch 8。
DenseSeriesWatermarkBlock(36B/条):[SeriesId 4][TrimmedUntilTimestamp 8][TrimmedSegId 4][TrimmedExtension 4][TrimmedOffset 8][SampleCount 8]。
Dense 水位文档:[默认槽 40B(seriesId 0)][BlockCount 4B][n × 36B 块]。
源码:Products/TimeSeries/TimeKey.cs、DenseTimeKey.cs、TimeSeriesEnvelope.cs、TimeSeriesWatermark.cs、DenseSeriesWatermark.cs。
3.4 Blob 对象表帧
{name}.blob.meta 上基于 StreamSnapshot 的版本链记录帧流(每条登记/删除/标损 = 一帧):
[StreamFrameHeader 14B][BlobObjectEntryPayload 48B + 对齐补零][StreamFrameFooter 28B]
BlobObjectEntryPayload(48B):
| 偏移 | 宽度 | 字段 |
|---|---|---|
| 0 | 4 | ObjectIdSegId |
| 4 | 4 | ObjectIdExtension |
| 8 | 8 | ObjectIdOffset |
| 16 | 8 | Length |
| 24 | 8 | FrameLength |
| 32 | 8 | CreatedTicks |
| 40 | 8 | StateAndReserved(低字节 = BlobState,高 7B 恒 0) |
帧头/帧尾 = 2.10 的 StreamFrameHeader/Footer(CRC64 帧级自校验)。帧扇区对齐不变式(物理 = 逻辑布局,重启恒等映射读回成立)。恢复 = meta O(1) 水位 + 定步长逐帧重放(步长不齐 fail-fast)。
源码:Products/Blob/BlobObjectTable.cs(FrameHeaderSize=14、FrameFooterSize=28、PayloadSize=48)。
4. 网络线格式(Core.Net)
4.1 Wire FrameHeader(16B,介质无关)
[0..4) PayloadLength 4B LE(≤ 16MB) [4] Kind 1B [5] ChannelId 1B [6] ProtocolId 1B [7] Version 1B(=1)
[8..12) HeaderCrc 4B(CRC32C 覆盖此前全部头字节——防半帧/错位)
[12..16) PayloadCrc 4B(CRC32C 覆盖载荷)
头版本 1 的字段永不再解释——演进走版本协商 + 新 FrameKind。[BinaryLayout] 声明即代码(零手写偏移)。
源码:Wire/FrameHeader.cs、FrameCodec.cs。
4.2 Raft RPC 消息族([WireMessage] 声明即线格式)
编码规则:[Tag 1B][根字段声明序][子类字段声明序],全 LE。根 RaftRpc 公共前缀 = [Term 8B]。bool=1B;定长原语小端原宽;NodeId=16B 不透明串;blob=[Len 4B][bytes];数组=[Count 4B][item×N]。消息不携带 CorrId(RpcId 取消由传输承载)。
| Tag | 消息 | 子类字段(根 Term 8B 在前) |
|---|---|---|
| 0x01 | PreVoteReq | CandidateId(16) + LastLogIndex(8) + LastLogTerm(8) |
| 0x02 | PreVoteResp | Granted(1) |
| 0x03 | RequestVoteReq | CandidateId(16) + LastLogIndex(8) + LastLogTerm(8) |
| 0x04 | RequestVoteResp | Granted(1) |
| 0x05 | AppendEntriesReq | LeaderId(16) + PrevLogIndex(8) + PrevLogTerm(8) + LeaderCommit(8) + EntriesRegion(blob) |
| 0x06 | AppendEntriesResp | Success(1) + MatchIndex(8) + ConflictTerm(8) + ConflictIndex(8) + SnapshotIndex(8) |
| 0x07 | InstallSnapshotReq | LeaderId(16) + SnapshotIndex(8) + Swarm(1) + ManifestId(16) + BlockSize(4) + TotalBytes(8) + Checksums(数组 u32) + Holders(数组 NodeId) |
| 0x08 | InstallSnapshotResp | Success(1) + SnapshotIndex(8) |
| 0x09 | JoinReq | CandidateId(16) + AutoPromote(1) + EndPointBytes(blob ≤64) + AsWitness(1) |
| 0x0A | JoinResp | Accepted(1) + LeaderId(16) |
| 0x0B | ReadIndexReq | (仅根 Term) |
| 0x0C | ReadIndexResp | ReadIndex(8) |
| 0x0D | TransferLeaderReq | (仅根 Term) |
| 0x0E | TransferLeaderResp | Accepted(1) |
线格式版本 v3(WireFormatVersion=3)。防御上限 MaxEntriesPerAppend=8192、MaxEntriesRegionBytes=16MiB。未知 tag/截断/超上限 = 畸形丢弃;已知 tag 尾部扩展字节容忍。
源码:Raft/RaftRpc.cs、WireMessageGenerator.cs。
4.3 RaftEntriesRegion(AppendEntries 条目区)
[Count 4B LE][×N: RaftAppendEntryHeader 13B + Content]
RaftAppendEntryHeader(13B):[0] Term 8B LE + [8] Kind 1B + [9] ContentLength 4B LE,Content 紧随。
源码:Raft/RaftEntriesRegion.cs:98-121。
4.4 Gossip 帧(37B)
[MsgId 16B][Origin 16B][Ttl 1B][PayloadLength 4B LE][data]
MsgId = 广播身份(去重键,同消息至多投递一次);Origin = 最初广播者(中继逐跳不变)。[BinaryLayout] 生成 codec。
源码:P2P/GossipFrameHeader.cs。
4.5 HyParView 消息族
六类消息(协议域 0x02):Join [Tag 1B][Origin 16B][Ttl 4B]、Neighbor [Tag][Priority 1B][Count 4B][NodeId×Count]、Disconnect [Tag]、Fail [Tag][Failed 16B]、Shuffle [Tag][Count 4B][NodeId×Count]、Heartbeat [Tag]。发送方身份不上线(分发即身份);解码防御(未知 tag/截断/Count 超上限 = 丢弃,尾部扩展容忍前向兼容)。
源码:P2P/HyParViewMessage.cs。
5. 版本与演进速查
| 格式 | 当前版本 | 演进要点 |
|---|---|---|
| LogPageFrame | 无版本字段 | DataLength 即写侧扇区对齐字节数 |
| EntryLogHeader | 0x0100 | codecId 在 flags bits8-11 |
| DeltaLogHeader | 0x0100 | 同构 EntryLog,CRC32C |
| LogMetaHeader | 0x0100 | PreparedTailAddress 追加(旧块零扩展降级) |
| BlittableRingHeader | 0x0200 | v2 泛型改版 KeyLength 退役(v1 旧盘不认) |
| OverflowRecordHeader | 0x0100 | — |
| RingMetaHeader | 0x0100 | — |
| SegmentTupleHeader | Version=2 | Magic "TC_SEGTU",Summary 内联 |
| ProbingIndexHeader | 0x0100 | 版本链 N 版轮替 |
| BTree/SkipListHeader | 0x0100 | — |
| StreamFrameHeader | 0x0100 | TotalLength/EntryCount 在 Footer |
| WalOpaqueHeader | 0x0100 | 只记 head/tail 锚点(段 anchor 表纯内存) |
| WalSnapshotHeader | 0x0100 | — |
| RaftStoreMeta | 1(byte) | 前向兼容门归消费面 |
| KvVersionOpaque | magic "TKV1" | 12B→24B(扫描水位追加),旧块兼容 |
| RaftRpc 线格式 | WireFormatVersion=3 | 信封之死,条目区 blob 化 |
CRC 校准(外部解析器最容易错的两点):
- CRC64 = ECMA-182(多项式
0x42F0E1EBA9EA3693、init 0、无异或输出)——不是 zlib/ISO 常见约定。 - CRC32C 为标准 Castagnoli(init 0xFFFFFFFF、final XOR 0xFFFFFFFF)。
6. 相关文档
- 存储行为面:log.md / ring.md / meta.md / snapshot.md / segment-table.md(
src/KernLab.Tier.Runtime/docs/) - 跨层持久化稳定性:persistence-architecture.md
- TierVolume 虚拟卷(§2.11 格式的介质行为面):virtual-file-system.md(载体写穿/两档 IO/崩溃窗口谱系)
- 产品格式使用面:tierwal.md / tierkv.md / tierseries.md / tierblob.md(
src/KernLab.Tier.Products/docs/) - 网络线格式行为面:transport-architecture.md(§5 线协议帧)、p2p-architecture.md(§3 帧格式)
- 格式真源(声明即代码):各
[BinaryLayout]类型 + 生成 Codec;src/KernLab.Tier.Contracts/Layout/(Magic/RecordFlags/CRC)