SQLite 的备份故事一向简单:复制文件、定时快照,或者借助 WAL 模式下的 .backup。当数据库膨胀到数十 GB、且业务要求 “零停机、秒级 RPO” 时,传统脚本就显得力不从心。Litestream 在 2025 年发布的 VFS 插件给出了一条新路径 —— 把备份数据当成 “远程只读副本”,通过 FUSE 虚拟文件系统直接挂载到本地,让 SQLite 在查询时按需拉回最新页面,而写入端仍以秒级频率把 WAL frame 流式推送到 S3。结果是:不中断业务、不占用本地全量空间,却能在一行 SQL 内回到任意秒级快照。
1. 从 “文件级拷贝” 到 “页级流式复制”
传统备份的粒度是 “整个文件”,而 Litestream VFS 把粒度拆成 “页面”。
- 写入侧:Litestream 进程监听
-wal文件,每凑满一批帧就封装成 LTX(LiteStream Transaction)对象上传。默认 L0 层 1 s 刷盘,L1 层 30 s 合并,L2 层 1 h 再合并,每日一次完整快照。 - 读取侧:VFS 插件拦截 SQLite 的
xRead(),把 “页号 + 页大小” 映射成 “对象键 + 偏移”,用 S3 Range-Get 拉取 4 KiB 页面,LRU 缓存热页,索引仅 1 % 对象体积,首次查询即可在秒级完成。
由于 LTX 文件内部已做 compaction,同一页面的旧版本会被丢弃,因此 S3 上实际存储量 ≈ 数据库体积 + 7 天内增量,网络流量与费用可控。
2. 架构拆解:LTX 格式与反向索引
LTX 文件由 Header、Page Data、Trailer 三段组成:
| 字段 | 长度 | 含义 |
|---|---|---|
| page_size | 2 B | SQLite 页面大小,默认 4096 |
| page_count | 4 B | 本文件包含的页面数 |
| max_txid | 8 B | 最大事务 ID,用于一致性判断 |
| page_offset[] | page_count × 4 B | 每页在文件内的偏移数组,构成 “小索引” |
| checksum | 8 B | Trailer 校验和 |
VFS 在启动时只拉取所有 LTX 的 Trailer(约 1 % 大小),即可在内存拼出一张 <page_no → (file_key, offset, version)> 的反向表;后续查询直接按 page_no 命中对应 Range,省去整文件下载。
3. 秒级 RPO 落地:配置与参数
以下 litestream.yml 可直接用于生产,RPO ≤ 1 s,RTO ≤ 10 s(首次查询需预热索引):
dbs:
- path: /var/lib/app/prod.db
replicas:
- type: s3
bucket: myapp-litestream
path: prod/
region: us-east-1
retention: 720h # 30 天
sync-interval: 1s # L0 层 1 秒刷盘
checkpoint-interval: 30s # L1 层合并
compression: gzip # 页面级压缩
客户端加载 VFS:
$ sqlite3
sqlite> .load /usr/local/lib/litestream.so
sqlite> .open "file:///var/lib/app/prod.db?vfs=litestream"
关键可调参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
| litestream_vfs_page_cache_size | 4096 | 页缓存数,16 MiB 内存 |
| litestream_vfs_index_prefetch | 8 | 并行拉取 Trailer 的线程数 |
| litestream_vfs_range_size | 262144 | Range-Get 字节数,建议 256 KiB |
监控点:
litestream_replication_lag_seconds> 5 触发告警;- S3
RangeLatencyP99 > 200 ms 需考虑就近接入点或 CDN 边缘缓存。
4. 场景、成本与限制
适用场景
- 读多写少、分析查询占主导,例如报表、日志检索、配置中心;
- 边缘节点需要 “离线副本”,但本地磁盘不足;
- 开发调试阶段,快速拉取生产快照而无需全量 restore。
成本估算 以 50 GB 库、日新增 1 GB、查询热点 5 % 为例:
- 存储:50 GB × 2(多版本)× 0.023 USD/GB = 2.3 USD / 月;
- 请求:5 % 页面 × 1 k 查询 / 天 × 30 天 ≈ 15 k Range-Get,0.0004 USD / 千次 ≈ 0.06 USD / 月;
- 出流量:热点 2.5 GB × 0.09 USD/GB = 0.23 USD / 月; 总计约 2.6 USD / 月,远低于同规格 RDS 只读实例。
限制与权衡
- 只读:写入仍需回源主库;若需双写,需引入 LiteFS 或 rqlite;
- 冷查询放大:随机扫描全表时,Range 请求可能暴涨,需配合索引或分区;
- 网络隔离:边缘节点离线时,首次查询会失败,可提前本地缓存一份最新快照作为兜底。
5. 结论:嵌入式数据库的云级备份最短路径
Litestream VFS 把 “备份” 从运维脚本升级为 “可挂载的远程副本”,让 SQLite 在保持嵌入式零运维优势的同时,获得云级存储的持久性与弹性。只需加载插件、改一行连接串,就能在本地命令行里查询云端任意秒级快照 ——RPO 秒级、RTO 秒级、零停机、零改造。对于读密集型业务,这是一条成本最低、复杂度可控、且可立即落地的流式备份方案。
资料来源
[1] Fly.io Blog: Litestream VFS — Hot SQLite queries off S3, 2025-07
[2] Litestream 官方文档:LTX 文件格式与 VFS 插件实现,2025-11