mongod 一直在往 diagnostic.data 里写什么?格式是什么?能不能自己读出来?这篇写了个解码器,拿已知的 5,000 次插入去验证。
参数: {'diagnosticDataCollectionDirectorySizeMB': 500, 'diagnosticDataCollectionEnabled': True, 'diagnosticDataCollectionFileSizeMB': 10, 'diagnosticDataCollectionPeriodMillis': 1000, 'diagnosticDataCollectionSamplesPerChunk': 300, 'diagnosticDataCollectionSamplesPerInterimUpdate': 10}
刚启动约 3 秒后目录里的文件: [('metrics.2026-10-12T06-07-05Z-00000', 69922)]
在运行期间精确插入了 5,000 个文档(serverStatus 的 opcounters.insert 从 2000 涨到 7000)
运行约 36 秒后(mongod 还在运行)目录里的文件: [('metrics.2026-10-12T06-07-05Z-00000', 69922), ('metrics.interim', 32159)]
mongod 正常关闭之后: [('metrics.2026-10-12T06-07-05Z-00000', 102144)]FTDC 默认开启,每秒一个采样,每块 300 个采样,单文件 10 MB、目录 500 MB。
metrics.2026-10-12T06-07-05Z-00000:102,144 字节,共 4 个 BSON 文档,type 的计数 = {0: 1, 2: 1, 1: 2}
type 0 文档的字段: ['_id', 'type', 'doc'],doc 里的顶层字段: ['start', 'buildInfo', 'getCmdLineOpts', 'hostInfo', 'end']
type 1 文档:_id = 2026-10-12 06:07:05.004000,data 是 BinData 30,356 字节,前 4 字节 = 解压后长度 177,308
type 1 文档:_id = 2026-10-12 06:07:06.005000,data 是 BinData 32,183 字节,前 4 字节 = 解压后长度 181,762顺序排列的 BSON 文档:type 0 元数据、type 1 压缩指标块、type 2 周期性元数据;未满的块先写在 metrics.interim,正常关闭时刷成正式块。
块 0:1 个采样,5,033 个指标,压缩后 30,356 字节,解压后 177,308 字节 块 1:37 个采样,5,036 个指标,压缩后 32,183 字节,解压后 181,762 字节 取采样最多的块 1:压缩后 32,183 字节 → 解压后 181,762 字节(压缩比 5.6×) 参考文档的顶层字段: ['start', 'serverStatus', 'connPoolStats', 'networkInterfaceStats', 'transportLayerStats', 'end'] 指标个数(数值型叶子字段)= 5,036,采样个数 = 37
zlib 解压后是参考文档、指标数、增量数,然后是 varint 编码的差值;指标集变化时开新块。
{'serverStatus.metrics': 1922, 'serverStatus.wiredTiger': 1460, 'serverStatus.queues': 433, 'serverStatus.incrementalRollout': 192, 'serverStatus.lockContentionMetrics': 144, 'serverStatus.locks': 132, 'serverStatus.opLatencies': 84, 'serverStatus.searchTaskExecutorMetrics': 82, 'serverStatus.network': 68, 'connPoolStats': 59}一个采样 5,036 个指标,主要是 serverStatus 的各个部分,另有连接池统计。
所有块的指标名完全相同: False(每个块的指标集若变了就要开新块) 共 38 个采样;start 时间戳相邻差(毫秒)最常见的取值: [(1000, 15), (996, 3), (1004, 3), (995, 3)] opcounters.insert 序列首尾: 0 → 7000 insert 计数有变化的采样 (第几个采样, 增量): [(5, 2000), (10, 2000), (11, 2000), (12, 1000)] 增量之和 = 7000;其中 2,000 来自先插入的那批,后面 5 次 insert_many(各 1,000 个)分落在三个采样里;serverStatus 自己读到的 2000 → 7000,增量 5000 serverStatus.connections.current 序列的取值: [0, 3, 5]
写了解码器还原序列:opcounters.insert 的增量之和 7000,与 serverStatus 读到的一致。
取采样最多的块(37 个采样)分开压缩:参考文档(完整的第一个采样,177,418 字节)压缩后 30,562 字节;其余 36 个采样的差值流(4,344 字节)压缩后 1,536 字节 → 每个采样的差值约 43 字节 按每块 300 个采样估算:每块约 43 KB,每天 288 块约 12.5 MB;500 MB 的目录上限约够 40 天(这是空闲实例的外推,不是实测)
参考文档压缩后约 30 KB,每个采样的差值约 43 字节;空闲实例每天约 12.5 MB 的估算下,500 MB 约能保存 40 天。