Table of Contents

底层二进制格式单元说明(存储 × 线格式)

本文是 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 区 = 24B AddressInfo([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,Flags 0x1002=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";SkipList 0x44484C53 "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";SkipList 0x54464C53 "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,Flags 0x1016=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 校准(外部解析器最容易错的两点):

  1. CRC64 = ECMA-182(多项式 0x42F0E1EBA9EA3693、init 0、无异或输出)——不是 zlib/ISO 常见约定。
  2. 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)