Append-only event log database built in MoonBit
| 包 | 职责 |
|---|---|
| src/core | 记录编码/解码(含 CRC32)、Record / RecordKind |
| src/io | 存储抽象:LogWriter / LogReader / LogTruncate 与 IoError |
| src/segment | 单段 append、稀疏索引、范围扫描、恢复 |
| src/log | 多段管理器、tombstone、保留策略、消费游标 |
| src/backend_mem | 内存后端(wasm/js 可用) |
| src/backend_native | native 文件后端(C stub FFI) |
| src/cli | 命令行前端(native 可执行) |
moon build --target native # 构建(含 CLI)
moon test # wasm 目标测试
moon test --target native # native 目标测试
moon bench --target native # 基准:追加 / 点查 / 范围扫描 / 恢复
moon test --enable-coverage --target native # native 覆盖率采集
moon coverage report -f summary # 覆盖率摘要moonlog <command> <dir> [args...]
put <dir> <key> <value> 追加一条 key/value 记录
put-if <dir> <key> <expected|-> <value>
仅当 live 值等于 expected(`-` 要求不存在)才追加
put-batch <dir> <k> <v> ... 一次追加多组 key/value 记录
delete <dir> <key> 追加 key 的 tombstone
get <dir> <offset> 按 offset 读取记录
scan <dir> [from] [to] 列出 [from, to) 区间记录
scan-prefix <dir> <prefix> 按 key 前缀列出(结果按 key 排序)
scan-range <dir> <lo> [hi] 按 key 半开区间 [lo, hi) 列出(hi 省略表示无上界)
scan-time <dir> <lo> <hi> 列出 timestamp 落在 [lo, hi) 的记录
recover <dir> 打开并恢复,报告计数
prune <dir> <keep-segments> 只保留最新 N 个段
prune-bytes <dir> <bytes> 回收最旧段直到总字节 <= bytes
prune-before <dir> <timestamp> 回收末条记录早于 timestamp 的段
prune-expired <dir> <ttl> 回收末条记录早于 now-ttl 的段
prune-superseded <dir> 回收所有记录均被后续覆盖的段
merge <dir> <max-segments> 将连续的已 roll 段合并至不超过 N 段
maintain <dir> <max-segments> [ttl]
一键维护:合并 + 冗余回收 + 过期折叠 + 压缩
已 roll 段 + fsck
cursor <dir> <start|-> <limit> 按批读取消费游标(`-` 从持久化位置续读)
cursor-commit <dir> <position> 持久化消费游标位置
cursor-lag <dir> 报告每个消费游标的滞后量(next_offset -
position),便于发现停滞的消费者
cursor-save <dir> <name> <pos> 持久化命名消费游标位置
cursor-load <dir> <name> 读取命名消费游标位置
cursor-list <dir> 列出全部命名消费游标位置
cursor-drop <dir> <name> 删除命名消费游标位置
follow <dir> [start|-|tail] [--once] [--commit] [--json] [--name <cursor>]
持续打印新追加的记录(`-` 从持久化游标续读,
`tail` 从当前末尾开始;`--commit` 每批后提交
游标,`--name` 指定命名游标以支持多消费者各
自 follow/提交;`--json` 以单行 JSON 输出
(UTF-8 文本,与 export-jsonl 同构);`--once`
拉取一轮即退出;轮询间隔可用
`MOONLOG_FOLLOW_INTERVAL` 调整,默认 200ms)
serve <dir> <max-segments> [ttl] [--every ms] [--fsck-every N] [--once]
周期性执行维护(合并 + 冗余回收 + 可选过期折
叠 + 压缩 + flush 元数据);`--every` 或
`MOONLOG_SERVE_INTERVAL` 设置周期,默认
60000ms;`--fsck-every N` 每 N 轮跑一次快
速 fsck 并输出报告;`--once` 执行一轮即退出
backup <dir> <dst> 将目录的一致快照拷贝到空目录 dst(独占锁内
flush 数据与元数据后原样拷贝段文件、sidecar
与 MANIFEST;不拷贝 LOCK 与游标文件)
restore <src> <dst> 将 backup 产物还原到空目录 dst(offset 原样
保留,恢复后可无缝续写、游标仍有效;完成后
自动 verify_fast 校验并输出报告)
getkey <dir> <key> 查询 key 的最新值(tombstone 生效)
getkey-live <dir> <key> <ttl> 查询 key 的最新值,过期则视为不存在
has-key <dir> <key> 用段级 Bloom 过滤判断 key 是否存在
export <dir> <file> 导出全部记录(含 tombstone)到可移植文件
export-jsonl <dir> <file> [base64]
导出全部记录为 JSON Lines(每行一个 JSON 对
象:offset/timestamp/kind/key/value;默认文
本模式假定 UTF-8 文本、控制字符转义,`base64`
模式对任意字节无损)
import <dir> <file> 从可移植文件回放记录
compact <dir> 折叠为 live 记录并重写目录
compact-expired <dir> <ttl> 折叠 live 记录并剔除已过期记录(offset 重排)
fsck <dir> [fast] [--fix] [--dry-run]
校验完整性(fast 跳过记录解码,段级 CRC);
`--fix` 先执行修复:隔离整段校验失败的段
(改名 `<name>.corrupt` 保留证据)、截断损坏
尾部、重建 MANIFEST 与全部段 sidecar,随后
再校验一次并输出报告;`--dry-run` 只打印修
复计划(将截断/隔离/删除什么),不改盘
stats <dir> [json] 打印逐段统计(含每段逻辑字节 disk 磁盘字节与
压缩汇总;可选 JSON)
version 打印 moonlog 版本号(与 moon.mod 同步)| 类型 / 函数 | 包 | 用途 |
|---|---|---|
| Log::new / Log::recover | log | 建立多段日志 / 从已有段恢复 |
| Log::append / append_batch / append_batch_atomic / Log::delete | log | 追加单条 / 批量 / 原子批量(失败回滚)/ tombstone |
| Log::get / scan / scan_range / scan_reverse / scan_time_range / tail / for_each | log | 点查 / 全扫 / offset 区间 / 逆序区间 / 时间区间 / 最近 N 条 / 流式遍历 |
| Log::for_each_while / Log::for_each_time_range | log | 流式遍历(f 返回 false 提前终止、跨段传播)/ 时间区间流式遍历,大结果集零物化 |
| Log::retain_last / retain_max_bytes / retain_before / drop_before | log | 段级保留策略(段数 / 字节 / 时间戳 / offset) |
| Log::build_key_index / index_build_count / get_latest / get_latest_at / get_latest_bloom / get_many / scan_live / scan_prefix / scan_key_range / snapshot / compact / compact_expired / merge_segments / prune_superseded | log | KV 逻辑视图(带缓存)/ TTL 读取 / Bloom 快查 / 批量点查 / 前缀与区间扫描 / 折叠 live / 过期折叠 / 原地重写 / 段合并 / 冗余段回收 |
| Log::export_bytes / import_bytes | log | 记录流导出 / 回放(可移植交换) |
| ConsumerCursor::new / poll / seek | log | 按批消费、提交与回退读位置 |
| SyncPolicy / Log::flush | log | Never / Always / Batch 持久化策略与显式 fsync |
| Manifest::encode / decode_manifest | log | 目录级元数据编解码 |
| Log::verify / VerifyReport | log | 全日志顺序与段校验和完整性校验 |
| Log::segment_summaries / SegmentSummary | log | 逐段计数 / 大小 / 压缩标志 / 时间跨度统计 |
| rle_compress / rle_decompress | core | 纯 MoonBit RLE 段数据压缩 / 解压(wasm 可用) |
| Segment / SparseIndex | segment | 单段读写、稀疏索引、崩溃恢复 |
| MemLog | backend_mem | 内存后端(wasm / js 可用) |
| NativeFileLog / open_log_dir / index_interval_for / flush_meta / compress_log_dir / count_compressible_segments / DirLock | backend_native | 文件后端、打开快路径、索引间隔、段压缩与计数、目录锁(含超时重试) |
| save_named_cursor / load_named_cursor / list_named_cursors / remove_named_cursor | backend_native | 命名消费游标持久化与管理 |
| backup_log_dir / restore_log_dir | backend_native | 目录级物理备份(对既有备份目录增量拷贝)/ 恢复,offset 保留 |
| repair_log_dir / RepairReport | backend_native | 修复:坏段隔离(.corrupt)、torn-tail 截断、MANIFEST/sidecar 重建 |
| compress_rolled_segments / compress_log_dir / count_compressible_segments | backend_native | 对已打开日志 / 目录执行已 roll 段压缩与计数 |
| file_size / sleep_ms / rename_file | backend_native | 文件尺寸 / 轮询休眠 / 文件改名(增量备份、follow/serve/repair 支撑) |
| Record / crc32 | core | 记录编解码 |
| LogWriter / LogReader / LogTruncate / IoError | io | 存储抽象 |
let store = @backend_mem.MemLog::new()
let log : @log.Log[@backend_mem.MemLog, @backend_mem.MemLog] = @log.Log::new(
1_048_576,
base => @segment.Segment::new(store, store, base),
)
ignore(log.append(b"user:1", b"alice", 0))
let recs = log.scan()moon run examples/mem_demo --target native
moon run examples/mem_demo --target wasmmoon run examples/native_demo --target native ┌──────────────┐
│ cli(CLI) │ put / scan / compact / export / fsck …
└──────┬───────┘
│
┌──────▼───────┐
│ log │ Log[W,R]:多段、offset、保留、游标、KV 视图
└───┬──────┬───┘
│ │
┌─────────▼─┐ ┌─▼──────────┐
│ segment │ │ core │ 记录编解码 / CRC32
└─────┬─────┘ └────────────┘
│
┌──────▼───────────────────┐
│ io:LogWriter/Reader/ │
│ LogTruncate/IoError │
└───┬──────────────────┬───┘
│ │
┌──────▼──────┐ ┌──────▼────────┐
│ backend_mem │ │ backend_native│ flock / C stub FFI
└─────────────┘ └───────────────┘u32 body_len
body:
u8 flags (0 = Put, 1 = Delete)
u64 offset
i64 timestamp
u32 key_len
u32 value_len
key[key_len]
value[value_len]
u32 crc32 (仅覆盖 body)# 主机(生产者):定时增量推送(backup 幂等,重复执行只传变更段)
moonlog backup /data/moonlog primary-bak
rsync -a --delete primary-bak/ backup-host:/data/moonlog-replica/
# 备机(消费者):首次落地 + 周期刷新
moonlog backup /data/moonlog primary-bak # 增量
rsync -a primary-bak/ replica/备机目录结构与主目录字节一致(MANIFEST/段/sidecar),offset 与游标语义原样保留——备机可直接 scan / getkey / follow - 消费,故障切换时把备机目录交给写者即可(游标文件不随 backup 拷贝,如需保留消费进度先 cp CURSOR* 或在备机 cursor-commit)。注意:只做单向复制,双主互写不受支持。Install
Download zipAppend-only event log database built in MoonBit