
2025/12/12 2:59
Litestream VFS
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Litestream は、SQLite のオープンソースバックアップ/リストアシステムであり、オブジェクトストレージ(例:Amazon S3)からページをストリーミングしてローカルデータベースをどこでも実行できるようにします。毎秒「レベル‑0」スナップショットを作成し、30 秒間隔でインクリメンタルな「レベル」(L1 まで)を維持することで、ポイント・イン・タイムリカバリが高速化されます。データは LTX ファイルに送信され、これには順序付きページセットと小さなトレーラ―インデックス(約 1 %)が含まれ、ページ番号を S3 のオフセットにマッピングします。VFS は必要時にページを読み取り、LRU キャッシュを使用してネットワークトラフィックを削減します。Litestream のコンパクションアルゴリズムは LTX ファイルを逆方向に読んで最新のページバージョンだけを保持し、復元速度を向上させつつ帯域幅を節約します。
システムは Litestream VFS プラグイン(
.load litestream.so)を公開しており、SQLite の読み取り側を実装しています。書き込みは従来の Litestream Unix プログラムで処理されるため、アプリケーションコードは変更せずに済みます。VFS をロードすると、S3 からファイル全体をダウンロードすることなくリモートデータベースを直接クエリできます。PRAGMA litestream_time = '5 minutes ago' や任意の絶対タイムスタンプで瞬時にポイント・イン・タイムリカバリが可能です。
バックアップは毎秒 L0 に書き込まれるため、VFS は S3 をポーリングしてインクリメンタルにインデックスを更新し、完全な復元なしにほぼリアルタイムのレプリカを提供します。Litestream は Fly.io API で本番環境でも使用されており、オブジェクトストレージからの即時 PITR(ポイント・イン・タイムリカバリ)といった高価値機能を提供しつつ、開発者が自ら類似のソリューションを実装できるほどシンプルです。
本文
画像はAnnie Ruygtさんのものです。
私はBen Johnsonと申します。Fly.ioでLitestreamを開発しています。LitestreamはSQLite用の欠落していたバックアップ/リストアシステムです。無料でオープンソースなソフトウェアで、どこでも動作するよう設計されており、詳細はここにあります。
仮にサンドイッチ評価を保存したSQLiteデータベースがあり、それをLitestreamでS3バケットへバックアップしたとします。
ローカルマシン上ではAWSの認証情報とS3パスを環境変数に設定し、SQLiteを起動します。
$ sqlite3 SQLite version 3.50.4 2025-07-30 19:33:53 sqlite> .load litestream.so sqlite> .open file:///my.db?vfs=litestream
これでSQLiteはLitestreamのバックアップファイルが指し示すリモートデータベースから動作します。クエリも可能です。
sqlite> SELECT * FROM sandwich_ratings ORDER BY RANDOM() LIMIT 3; 22|Veggie Delight|New York|4 30|Meatball|Los Angeles|5 168|Chicken Shawarma Wrap|Detroit|5
Litestream VFSはオブジェクトストレージのURLからSQLiteをホットに実行します。共有ライブラリが読み込めれば、SQLiteシェルと同じようにアプリケーションで動作します。
面白い事実:このクエリを実行するためにデータベース全体をダウンロードする必要はありませんでした。詳細は後述します。
一方、本番環境のどこかでは、誰かがミートボールサブに対して嫌気がさし、レーティングをすべて1にしたいと思っています——おっと、問題です:
sqlite> UPDATE sandwich_ratings SET stars = 1;
WHERE句を書き忘れたのですね!
sqlite> SELECT * FROM sandwich_ratings ORDER BY RANDOM() LIMIT 3; 97|French Dip|Los Angeles|1 140|Bánh Mì|San Francisco|1 62|Italian Beef|Chicago|1
イタリアンビーフとバインミーがすべて1星です。大惨事!
しかし、開発マシンに戻ると:
sqlite> PRAGMA litestream_time = '5 minutes ago'; sqlite> SELECT * FROM sandwich_ratings ORDER BY RANDOM() LIMIT 3; 30|Meatball|Los Angeles|5 33|Ham & Swiss|Los Angeles|2 163|Chicken Shawarma Wrap|Detroit|5
今度はバックアップの特定時点からデータベースをクエリしています。相対時間(例:'5 minutes ago')や絶対時間(例:
2000-01-01T00:00:00Z)など、任意に指定できます。
ここで行っているのは「瞬時ポイントインタイム復旧 (PITR)」です。SQLとSQLiteのPRAGMAだけで表現できるシンプルな仕組みです。
本番データセットを直接操作せずにクエリしたい、または昨日のデータで簡易チェックが必要だが完全復元は不要という場合、Litestream VFSなら簡単に実現できます。結果に大変満足しています。
仕組み
Litestream v0.5 は LTX(SQLite データ転送用ファイルフォーマット)を統合します。以前の Litestream はオブジェクトストレージへ SQLite のページをそのまま送り返していましたが、LTX は順序付けられたページセットを送ります。LiteFS 用に開発した LTX を、FUSE ファイルシステムなしで Litestream に組み込む方法を今年取り組みました。
圧縮(Compaction)
LTX が提供する大きなメリットは「圧縮」です。オブジェクトストレージからデータベースを復元するとき、各ページの最新バージョンだけが必要です。中間版は不要です。例えばページ 1〜5 が必要なら、バックアップに
1 2 3 5 3 5 4 5 5 のような順序があっても、最右側の 5, 4, 3, 2, 1 を取り出し、それ以外はスキップします。LTX はシーケンスの末尾から逆に読み込み、既に読んだページを飛ばすことで復元速度を大幅に向上させます。
圧縮はデータベース全体だけでなく、LTX ファイルセット単位でも可能です。これが Litestream で PITR を実現する鍵となります。
図では毎日フルスナップショットを取得し、その下には「レベル」別の変更セット(小さな時間窓から取り出したページ群)が並びます。デフォルトでは最高レベルが1時間ごと、レベル 1 は30秒ごとの間隔です。L0 は毎秒ファイルをアップロードしますが、圧縮されて L1 に移行するまでに保持されます。
PITR を実施するには:
- 最も近いスナップショットから開始
- ターゲット時点に到達するために必要な各レベルの最小限の LTX ファイルを決定
インデックス
LTX のトレーラーにはファイル内の各ページオフセットを追跡する小さなインデックスが含まれています。このトレーラー(ファイル全体の約1%)だけを取得すれば、ページごとの検索表を構築できます。現代のオブジェクトストレージはスライス取得をサポートしているため、S3 から直接個別ページを読み取ることが可能です。
実装
SQLite は「VFS(Virtual File System)」というプラグインインターフェースを持ち、OS層を抽象化します。Litestream VFS は既存の SQLite ライブラリに対するプラグインであり、SQLite 本体を置き換えるものではありません。
ロードすると、SQLite がページ読み込みを要求するたびに
Read() メソッドが呼ばれます。このメソッドは:
- 期待されるバイトオフセットからページ番号(既知のページサイズ)へ変換
- インデックスでリモートファイル名と実際のバイトオフセットを検索
- 正確なブロックに対する S3 の範囲リクエスト
を行います。LRU キャッシュを実装し、S3 への呼び出し回数を削減します。ほとんどのデータベースは「ホット」ページが少数であるため、頻繁に更新される部分はわずかです。
Litestream は L0 レイヤーへ1秒ごとにバックアップするので、VFS は S3 パスをポーリングしインデックスを増分更新できます。これにより、全データベースを一度にストリーミングせずともほぼリアルタイムのレプリカが実現します。
Marty McFly へ
Litestream はデータベースが存在したすべての状態を1秒間隔で保持し続けます。DELETE の WHERE 節を書き忘れた?一時間(あるいは日、週)前の状態に戻すには、Litestream が管理する LTX インデックスを調整するだけです。
「取得せずにクエリ」を行うこの機能は起動が高速です。サーバーが短命で AI エージェントが増える現代では、オブジェクトストレージへバックアップされたデータベースに対して瞬時にクエリを投げることが可能になります。
Litestream は本格的なプロダクション利用にも耐え得ます(Fly.io の重要な API でも採用しています)。この記事のアイデアをもとに自分で Litestream を作成することもできます。重い処理はすべて SQLite 自体に委ねられている点が、この製品の魅力です。