はじめに
Litestream は Ben Johnson さんが開発されている SQLite のデータベースをストリーミングするソフトウェアです。
I'm All-In on Server-Side SQLite ・ Fly によると Ben Johnson さんは Fly.io にジョインしてフルタイムで Litestream の開発をすることになったそうです。良い話ですねー。
Litestream では AWS S3 互換のオブジェクトストレージが利用可能ということで、さくらインターネットのオブジェクトストレージ でも使えるようにプルリクエストを送ったところマージしていただけました。
さて、この記事では Getting Started - Litestream をさくらのオブジェクトストレージでも試してみましたので以下で手順を説明します。今回試した環境は Ubuntu 22.04 LTS です。
Getting Started のチュートリアルの事前準備
Litestream をソースからインストールする
Releases ・ benbjohnson/litestream には上記の プルリクエスト を取り込んだバージョンはリリースされていないため、ソースからインストールする必要があります。
そのため Go のインストールが必要です。 https://go.dev/ の Download ボタンから
Download and install - The Go Programming Language の手順に従ってダウンロード、インストールしてください。
また Litestream が依存している mattn/go-sqlite3: sqlite3 driver for go using database/sql で cgo を使用しているため C コンパイラも必要です。以下のコマンドでインストールしてください。
sudo apt-get update && sudo apt-get install -y build-essential
あとは以下のコマンドを実行すると Litestream の最新版をソースからインストールできます。
go install github.com/benbjohnson/litestream/cmd/litestream@latest
オブジェクトストレージの API キーの発行
オブジェクトストレージのサイトとバケットは既に作成済みとします。もしまだの場合は ご利用手順 に従って作成してください。
次にAPIキーの発行ですが、バケットごとに発行できる パーミッション設定によるアクセスキーの発行 の手順で発行するのがお勧めです。パーミションは READ/WRITE (読み込みおよび書き込みを許可) を設定してください。
sqlite3 パッケージのインストール
sqlite のデータベースを開いて操作するために CLI をインストールします。
以下のコマンドを実行します。
sudo apt-get update && sudo apt-get install -y sqlite3
Getting Started のチュートリアルの実行手順
実験用データベース作成
作業用のディレクトリを適宜作成してそこに移動して以下のコマンドを実行し、新規にデータベースを作成します。
sqlite3 fruits.db
sqlite>
のプロンプトで以下の SQL を実行して fruits
テーブルを作成します。
CREATE TABLE fruits (name TEXT, color TEXT);
引き続き、sqlite>
のプロンプトで以下の SQL を実行して fruits
テーブルに2行レコードを登録します。
INSERT INTO fruits (name, color) VALUES ('apple', 'red');
INSERT INTO fruits (name, color) VALUES ('banana', 'yellow');
この後さらに SQL を実行するので sqlite>
のプロンプトを抜けずに残しておいてください。
ローカルのデータベースをオブジェクトストレージにレプリケーション
上記の sqlite3 を実行しているのとは別に端末を開きます。
bash のプロンプトで以下のコマンドを実行して LITESTREAM_ACCESS_KEY_ID
と LITESTREAM_SECRET_ACCESS_KEY
の環境変数を設定します。
export LITESTREAM_ACCESS_KEY_ID=発行したアクセスキーID
export LITESTREAM_SECRET_ACCESS_KEY=発行したシークレットアクセスキー
export LITESTREAM_ENDPOINT=s3.isk01.sakurastorage.jp
export LITESTREAM_REGION=jp-north-1
次に Litestream の reprecate コマンドを使ってリプリケーションを開始します。
以下のコマンド例の my_bucket_name
の箇所は実際のバケット名に置き換えて実行してください。
litestream replicate fruits.db s3://my_bucket_name/fruits.db
すると以下のようなメッセージが litestream から出力されます。
…(略)…
initialized db: 作業ディレクトリのパス/fruits.db
replicating to: name="s3" type="s3" bucket="my_bucket_name" path="fruits.db" region="jp-north-1" endpoint="https://s3.isk01.sakurastorage.jp" sync-interval=1s
…(略)…
オブジェクトストレージ上のデータベースをローカルにリストア
さらに別の端末で bash を起動して、LITESTREAM_ACCESS_KEY_ID
と LITESTREAM_SECRET_ACCESS_KEY
の環境変数を設定します。
export LITESTREAM_ACCESS_KEY_ID=発行したアクセスキーID
export LITESTREAM_SECRET_ACCESS_KEY=発行したシークレットアクセスキー
export LITESTREAM_ENDPOINT=s3.isk01.sakurastorage.jp
export LITESTREAM_REGION=jp-north-1
そして以下のように実行してオブジェクトストレージ上のデータベースをローカルの fruits2.db
という別のファイルにリストアします。my_bucket_name
は実際のバケット名に置き換えて実行してください。
litestream restore -o fruits2.db s3://my_bucket_name/fruits.db
すると作業ディレクトリに fruits2.db
というデータベースファイルが作成されます。
sqlite3 コマンドで開いて確認します。
sqlite3 fruits2.db
sqlite>
プロンプトで以下の SQL を実行して fruits
テーブルの中身を確認します。
select * from fruits;
すると以下のように2行の結果が表示されます。
apple|red
banana|yellow
こちらは .quit
を入力して抜けてください。
継続的なレプリケーション
ここで 最初の (ローカルでデータベースを作成した) 端末 に戻って、以下のSQLを実行してレコードを1行追加します。
INSERT INTO fruits (name, color) VALUES ('grape', 'purple');
次に 3番目の (データベースをリストアした) 端末 で以下のコマンドを実行して、別のデータベースファイル fruits3.db
にリストアします。
litestream restore -o fruits3.db s3://my_bucket_name/fruits.db
以下のコマンドで fruits3.db
を開きます。
sqlite3 fruits3.db
sqlite>
プロンプトで以下の SQL を実行して fruits
テーブルの中身を確認します。
select * from fruits;
すると以下のように、上で1行追加した3行の結果が表示されます。
apple|red
banana|yellow
grape|purple
おわりに
Getting Started のチュートリアルではSQLite の DB ファイルからオブジェクトストレージへの継続レプリケーションでしたが、I'm All-In on Server-Side SQLite ・ Fly を読むと、今後のリリースではオブジェクトストレージ無しで 2つの SQLite のデータベースファイル間での継続レプリケーションも計画されているようです。こちらも楽しみですね!