Litestream:给 SQLite 装上流式复制的灾备层
阅读时间: 大约 10 分钟
Litestream:给 SQLite 装上流式复制的灾备层

SQLite 是世界上部署最广的数据库,单文件、零运维、性能足够好,但它长期被诟病的一点是:没有原生的复制与高可用。数据库文件丢了就是丢了。「Koala 聊开源」介绍的 Litestream(作者 Ben Johnson,曾获 fly.io 支持,MIT 协议)正是为补这块短板而生——它不是一个新数据库,而是一个跑在旁边的独立灾备进程,把 SQLite 的变更持续流式复制到对象存储或本地文件,服务器挂掉后可恢复到最近一次已复制的事务。本文基于其 GitHub 仓库与官方文档,拆解它的机制、代价与边界。
一、背景:SQLite 为什么需要「外挂」复制
官方首页的口号很直白:「Stop building slow, complex, fragile software systems. Safely run your application on a single server.」——不要再搭慢、复杂、脆弱的分布式系统,而是把应用安全地跑在单机上。其逻辑是:很多中小应用根本不需要 Postgres+主从+连接池那套重型栈,SQLite 单机足够快、足够稳,唯一缺的是可靠的异地备份。传统做法是定时 cron 拷贝数据库文件,但那是「整机快照」,两次备份之间的事务会丢,且大文件每次全量复制很贵。
Litestream 的定位因此非常克制:它只做流式、增量、异步的复制与恢复,提供「类似 Postgres/MySQL 那种灾备能力」,但不做实时主从切换、不做多活。
二、是什么
官方 README 的定义:Litestream 是一个 SQLite 的独立灾备工具,作为后台进程运行,把变更增量地安全复制到另一个文件或 S3。它的两条安全承诺很关键:
- 只通过 SQLite API 与数据库通信,因此不会破坏你的数据库文件;
- 作为独立进程运行,现有应用无需改一行代码即可接入。
恢复语义是:服务器宕机后,可恢复到最近一次已复制的事务(point-in-time 到最近复制点),而不是某一天凌晨的快照。
三、技术机制:接管 WAL 的 checkpoint

它的巧妙之处建立在对 SQLite WAL 机制的精确利用上。SQLite 的 WAL(write-ahead log)模式会先把数据库页的改动写到一个独立的 -wal 文件,之后再把这些页回写主库文件(即 checkpoint),从而提供原子事务。WAL 会不断增长,必须在没有活跃事务时做 checkpoint 才能截断重启。
Litestream 的核心动作是接管 checkpoint 流程:
- 它开启一个长读事务,阻止其他进程做 checkpoint、阻止 WAL 被截断;
- 自己持续读取磁盘上新增的 WAL 页;
- 把新页打包成 LTX 文件(Litestream Transaction Log),每个 LTX 带一个单调递增的事务号 TXID,并附带校验和保证页一致性;
- 再把这些 LTX 增量同步到远端副本。
官方特别说明:同步次数与 LTX 文件不是一一对应——某次增量同步若没有发现新提交的 WAL 页,就不会写 LTX。这种设计让它只在真正有变更时才产生网络流量。
需要注意的一个侵入点:Litestream 首次复制时会在源库里创建一个内部表 _litestream_lock,用于在协调 checkpoint 时获取 SQLite 写锁。官方明确警告:这张表属于源库(不是副本侧),会改变源库 schema、页数与字节数;运行期间不要删它,删了会导致 checkpoint 同步失败,重启 Litestream 会自动重建。
四、关键事实与口径
| 维度 | 内容(官方口径) |
|---|---|
| 定位 | SQLite 独立流式复制 / 灾备工具,非实时主从 |
| 复制方式 | 异步、增量,复制 WAL 页为 LTX(TXID 单调+校验和) |
| 副本数量 | 每个数据库默认只复制到单个副本目的地;多目的地需走 replica 配置 |
| 支持后端 | S3、S3 兼容(Backblaze B2、DigitalOcean Spaces、Linode、Scaleway、Tigris、阿里云 OSS、Supabase Storage)、Google Cloud Storage、Azure Blob、SFTP、本地文件路径、NATS JetStream |
| 部署形态 | 独立进程;Docker、Kubernetes、systemd、Windows Service 均有指南 |
| 安全性 | 仅经 SQLite API 读写,承诺不损坏数据库 |
| 成本 | 官方称「每天只要几美分」,复用廉价对象存储 |
| 版本 | v0.5.x,仍在活跃维护(旧版 v0.3.14) |
| 协议 | MIT |
五、评测方法与口径批判
Litestream 官方没有给出延迟、吞吐、RPO 的量化 benchmark,其文档主要描述机制与配置。这意味着阅读其能力时要特别注意口径:
- 「恢复到最近事务」是已复制的最近事务,而复制是异步的——进程崩溃、网络中断的窗口期内尚未同步的 WAL 仍然会丢,它**不是零数据丢失(RPO=0)**方案;
- 「类似 Postgres/MySQL 的灾备」是类比语义,指有持续复制与时间点恢复,并不等于主从实时同步、自动故障切换;
- 「每天几美分」依赖对象存储的低廉定价,但 LTX 会在远端保留历史版本,长期保留策略与 lifecycle 配置会实际决定账单,不能只看这句营销语;
- 单副本目的地是官方明示的硬约束,多副本要靠配置变通,运维复杂度随之上升。
六、适用与不适用场景
适合:
- 单机/单服务器上跑 SQLite 的中小应用、边缘设备、个人博客、内部工具,想要廉价异地备份;
- 想从「每天一次文件拷贝」升级到「持续增量复制、分钟级 RPO」;
- 用对象存储做灾备,不愿额外买数据库副本服务器。
不适合:
- 需要实时主从、自动故障切换、高可用的生产核心库——那应该上服务端数据库;
- 多写、高并发写入导致 WAL 剧烈抖动、且对复制延迟零容忍的场景;
- 期望 RPO=0 的强一致容灾(异步复制做不到)。
七、客观分析:优势与局限
优势:
- 零侵入:独立进程、不改应用代码、仅经 SQLite API 访问,安全边界清晰;
- 增量便宜:只传变更页与 LTX,对象存储成本极低;
- 后端生态广:几乎主流对象存储与 SFTP/本地/NATS 都支持;
- 可恢复:基于 TXID 可做时间点恢复,优于定时快照。
局限:
- 异步复制,非零丢失:崩溃窗口仍可能丢少量未复制事务;
- 单副本默认:多目的地需额外配置;
- 会动源库 schema:
_litestream_lock表改变页数与体积,对某些严格比较 schema/体积的流程有干扰; - 不做高可用切换:它是灾备工具,不是负载均衡器或主从代理。
八、它意味着什么
Litestream 代表了 SQLite 生态「单机够用、但补一块廉价异地灾备」的务实路线:它不试图把 SQLite 变成分布式数据库,而是用一个旁挂进程把数据库页流进对象存储。对于被「要不要为了备份再养一套 Postgres 主从」困扰的团队,Litestream 给出了一个成本低得多的答案——前提是你接受它是异步灾备,而非实时高可用。