12 ポイント 投稿者 GN⁺ 2025-12-13 | 1件のコメント | WhatsAppで共有
  • Litestream VFSは、SQLiteデータベースを**オブジェクトストレージ(S3 など)**から直接読み取り、クエリできるようにするプラグイン形式の拡張機能
  • データベース全体をダウンロードせずに、リモートバックアップファイルに対して即座にクエリでき、**ポイントインタイムリカバリ(Point-in-Time Recovery, PITR)**も実行可能
  • 内部的にはLTXフォーマットを使用して変更されたページ集合を効率的に管理し、**重複ページをスキップするコンパクション(compaction)**によって復旧速度を向上
  • SQLiteのVFSインターフェースを活用して読み取り動作のみを横取りし、書き込み処理は既存のLitestreamプロセスが担当
  • 秒単位のバックアップとインデックス更新により、ほぼリアルタイムに近いレプリカを提供し、クラウド環境での高速なクエリ実行を支援

Litestream VFS 概要

  • Litestream VFSは、SQLiteがオブジェクトストレージURLを直接データソースとして利用できるようにする機能
    • SQLiteシェルで .load litestream.so.open file:///my.db?vfs=litestream コマンドを使って有効化
    • その後、S3に保存されたバックアップファイルを基にクエリを実行可能
  • データベース全体をダウンロードしなくても、リモートバックアップから直接クエリを実行できる
    • 例では SELECT * FROM sandwich_ratings クエリによって、S3に保存されたデータの一部を即座に参照

ポイントインタイムリカバリ(PITR)機能

  • PRAGMA litestream_time = '5 minutes ago'; コマンドにより、特定時点のデータ状態を参照可能
    • 相対時間(5 minutes ago)または絶対時間(2000-01-01T00:00:00Z)を指定可能
  • これにより、**即時のポイントインタイムリカバリ(Point-in-Time Recovery)**をSQLレベルで実行
    • 例では、誤った UPDATE 実行後に5分前の状態へ戻して正常なデータを確認

LTXフォーマットとデータ圧縮

  • Litestream v0.5は、**LTX(Litestream Transaction eXchange)**フォーマットを統合
    • 以前のバージョンではSQLiteページ全体を転送していたが、LTXは順序付きのページ集合のみを転送
  • LTXの中核は**「compaction」**機能で、復旧時に最新バージョンのページだけを選択
    • 例: 1 2 3 5 3 5 4 5 5 のうち、最も右側の 5、4、3、2、1 だけを使用
  • LTXはデータベース全体だけでなく、LTXファイル集合間でも圧縮可能で、これによりPITR復旧が可能になる
  • LTXファイルの**トレーラー(trailer)**には各ページのオフセットインデックスが含まれており、
    • ファイル全体をダウンロードせずに、S3 Rangeリクエストで必要なページだけを読み取れる

VFS 実装方式

  • SQLiteの**VFS(Virtual File System)**インターフェースを利用してLitestream VFSを実装
    • VFSはSQLiteのOSアクセス層を抽象化するプラグイン構造
  • Litestream VFSは**読み取り(Read)**動作のみを処理し、**書き込み(Write)**は既存のLitestreamプロセスが担当
  • SQLiteがページを読む際、VFSは要求されたバイトオフセットの代わりにページインデックスベースのマッピングを実行
    • インデックスからファイル名、実際のオフセット、ページサイズを見つけ、S3 APIのRangeヘッダーで該当ブロックだけをダウンロード
  • LRUキャッシュを実装して、頻繁にアクセスされる「ホットページ」をメモリに保持し、S3呼び出し回数を最小化

リアルタイムレプリケーションと性能

  • Litestreamは1秒ごとにL0レベルバックアップを実行
    • VFSはS3パスを定期的にポーリングしてインデックスを段階的に更新
    • 結果として、**ほぼリアルタイムに近いレプリカ(near-realtime replica)**を生成
  • データベース全体をストリーミングしなくても即座に利用可能
  • この構造により、高速な起動速度短い復旧時間を実現

活用と意義

  • Litestreamはデータベースのあらゆる状態を秒単位の解像度でバックアップ保持
    • DELETEUPDATE のミスがあっても、望む時点へ即座に復元可能
  • オブジェクトストレージから直接クエリする構造により、エフェメラルサーバー環境でも高速に動作
  • 複雑な仕組みなしにSQLiteの基本機能を活用して、シンプルかつ強力なバックアップ・復旧体系を提供
  • Fly.io の内部APIでも使用されており、本番環境でも安定して運用可能

1件のコメント

 
GN⁺ 2025-12-13
Hacker Newsのコメント
  • おお、これは自分が作った Go 用の sqlite vfs モジュール を使っている
    自分の作ったコードが他の人の役に立っていると分かるたびに本当にうれしい
    psanford/sqlite3vfs
    • ちゃんと動いた。ありがとう
    • 結局、人生で求めているのはこういう瞬間だよね
  • これは本当にすばらしい。Litestream VFS は Unix 哲学をそのまま体現している
    SQLite はいつも通りに動作し、Litestream はその上で透過的に動く
    つまり、SQL と SQLite pragma だけで ポイントインタイムリカバリ (PITR) を実現できる。
    本番データセットに直接触れなくても過去のデータをすばやく参照できる
  • インターフェース設計が本当にきれい
    環境変数で S3 バケットを指定し、SQLite で .load litestream.so の後、
    PRAGMA litestream_time = '5 minutes ago'; で過去時点のデータをすぐに参照できる
    • macOS では brew install sqlite3 の後、
      .load litestream sqlite3_litestreamvfs_init のように init 関数名を明示的に指定する必要がある
  • bun:sqlite でも問題なく動かせた
    "LITESTREAM_REPLICA_URL"AWS キーの環境変数 だけ設定すればよい
    temp.loadExtension("/path/to/litestream.dylib", "sqlite3_litestreamvfs_init") で拡張を読み込んだ後、
    file:my.db?vfs=litestream で開けばすぐ使える
    • これは主に JavaScript サーバー (bun) 環境で使う用途なのか気になる
    • うまく動いたのはすごい。ところで .dylib ファイルのパスはどうやって見つけたのか気になる
    • 参考までに、この例では環境変数の設定部分は dotenv では動かない。必ず実行時に直接指定する必要がある
  • 本当にすばらしい機能だ。
    私のユースケースは、S3 に保存された 読み取り専用 SQLite DB を Web サイトから直接使うこと
    DB は cron ジョブなどで更新され、Web サイトは Litestream VFS を通して最新データを読み取るだけ
    こういう使い方でも問題ないのか、それと Python 統合モジュールがあるのか知りたい
    今は Flask アプリが Google Spreadsheet からデータを取得して SQLite に変換し、毎日更新している
    私のアプリのコード
    • 作者です。Litestream VFS は 1 秒ごとにバックアップデータを自動ポーリングして最新状態を保つ
      追加の Python コードなしで SQLite CLI でもそのまま動作する
    • 似た用途なら ZeroFS もおすすめ
      外部依存は S3 だけで、SQLite とも相性がよい
      ZeroFS の SQLite パフォーマンス
  • Go 用 SQLite ドライバにもすでに実装してある
    ncruces/go-sqlite3 のサンプルコード
    環境変数なしで プログラムコードから制御でき、複数の DB を同時に扱える
    ただし、PRAGMA litestream_timeコネクション単位で適用されるので、コネクションプール使用時は注意が必要
    • .load litestream.so を見てすぐに ncruces/go-sqlite3 を思い出した
      wasm 環境でも動かすのは難しかったのか気になる
  • 最近 DuckDB を学びながら SQLite との違いを感じている
    DuckDB の「DuckLake」拡張はトランザクションごとに スナップショット を作って「タイムトラベル」機能を提供する
    これは Litestream VFS の PITR と似ている
    OLTP ではこれを復旧機能と呼び、OLAP では「Time Travel」と呼ぶ
    DuckLake は外部カタログ DB (PostgreSQL/MySQL/SQLite) を使ってマルチプロセスアクセスを調整する
    一方 Litestream は S3 の 不変 LTX ファイル を通じて複数のリーダーが同時アクセスできる
    どちらの世界も「共有ストレージ + メタデータ + コンパクション」という構造に収束しつつある
    こうしたプロジェクト間の クロスコラボレーション がもっと増えるといい
  • サンドイッチ愛好家として、その サンドイッチ評価データ が本当に気になる
  • 興味深いけれど、正確にはどのソフトウェアが発表されたのか分かりにくい。Litestream の新バージョン?
    • 作者です。そうです、Litestream v0.5.3 が新たにリリースされ、読み取り専用 VFS オプション が追加された
      v0.5.3 リリースノート
    • 今回のバージョンには マルチテナント DB 向けのディレクトリ複製サポート も含まれている。すばらしい追加機能だ
  • sqlite 拡張機能とも一緒に動くのか気になる
    たとえば sqlite-vecvss のようなベクター検索拡張を使っているとき、
    Litestream で S3 にリアルタイムバックアップし、Litestream VFS でリモート参照できるのか知りたい
    • 私も気になる。たぶんクエリはローカルで実行され、必要な ページ単位で S3 から取得する構造 ならそのまま動くはず
      実際に試してみるしかなさそう
    • 可能です(以上)