storage-format について
Turso の SQLite データベースファイルの構成とストレージ構造を解説する、ディスク上のデータを調査・デバッグする開発者向けガイドです。ヘッダー、ページやセル、レコード、B-tree、オーバーフローページ、フリーリストを扱います。
主な機能
- 01データベースヘッダーの項目とエンコーディング
- 02ページとセルのレイアウト
- 03テーブルとインデックスの B-tree 構造
- 04レコードとシリアル型の形式
- 05オーバーフローページとフリーリスト
活用シーン
- 01SQLite データベースファイルの調査
- 02ページや B-tree の動作のデバッグ
- 03整合性とページ数の確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ tursodatabase/ turso --skill storage-formatインストール後、Claude Code で/storage-formatを入力して読み込まれたか確認します。
詳細
ストレージ形式ガイド
データベースファイルの構造
┌─────────────────────────────┐
│ Page 1: Header + Schema │ ← First 100 bytes = DB header
├─────────────────────────────┤
│ Page 2..N: B-tree pages │ ← Tables and indexes
│ Overflow pages │
│ Freelist pages │
└─────────────────────────────┘
ページサイズ:2 の累乗で、512~65536 バイトです。デフォルトは 4096 です。
データベースヘッダー(先頭の 100 バイト)
| オフセット | サイズ | フィールド |
|---|---|---|
| 0 | 16 | マジック:"SQLite format 3\0" |
| 16 | 2 | ページサイズ(ビッグエンディアン) |
| 18 | 1 | 書き込み形式のバージョン(1=ロールバック、2=WAL) |
| 19 | 1 | 読み取り形式のバージョン |
| 24 | 4 | 変更カウンター |
| 28 | 4 | ページ単位のデータベースサイズ |
| 32 | 4 | 最初のフリーリストのトランクページ |
| 36 | 4 | フリーリストの総ページ数 |
| 40 | 4 | スキーマ Cookie |
| 56 | 4 | テキストエンコーディング(1=UTF8、2=UTF16LE、3=UTF16BE) |
複数バイトの整数はすべてビッグエンディアンです。
ページの種類
| フラグ | 種類 | 用途 |
|---|---|---|
| 0x02 | 内部インデックス | インデックス B ツリーの内部ノード |
| 0x05 | 内部テーブル | テーブル B ツリーの内部ノード |
| 0x0a | リーフインデックス | インデックス B ツリーのリーフ |
| 0x0d | リーフテーブル | テーブル B ツリーのリーフ |
| - | オーバーフロー | セル容量を超えるペイロード |
| - | フリーリスト | 未使用ページ(トランクまたはリーフ) |
B ツリーの構造
B ツリーには 2 種類あります。
- テーブル B ツリー:64 ビットの rowid キーで、行データを格納します
- インデックス B ツリー:任意のキー(インデックス列 + rowid)を使用します
Interior page: [ptr0] key1 [ptr1] key2 [ptr2] ...
│ │ │
▼ ▼ ▼
child child child
pages pages pages
Leaf page: key1:data key2:data key3:data ...
ページ 1 は常に sqlite_schema テーブルのルートです。
セル形式
テーブルのリーフセル
[payload_size: varint] [rowid: varint] [payload] [overflow_ptr: u32?]
テーブルの内部セル
[left_child_page: u32] [rowid: varint]
インデックスセル
同様ですが、キーは rowid だけではなく、任意の値(列 + rowid)です。
レコード形式(ペイロード)
[header_size: varint] [type1: varint] [type2: varint] ... [data1] [data2] ...
シリアル型:
| 型 | 意味 |
|---|---|
| 0 | NULL |
| 1-4 | 1/2/3/4 バイトの符号付き整数 |
| 5 | 6 バイトの符号付き整数 |
| 6 | 8 バイトの符号付き整数 |
| 7 | IEEE 754 浮動小数点数 |
| 8 | 整数 0 |
| 9 | 整数 1 |
| ≥12 偶数 | BLOB、長さ=(N-12)/2 |
| ≥13 奇数 | テキスト、長さ=(N-13)/2 |
オーバーフローページ
ペイロードがしきい値を超えると、超過分はオーバーフローチェーンに格納されます。
[next_page: u32] [data...]
最後のページでは next_page=0 です。
フリーリスト
トランクページのリンクリストで、各ページにはリーフページ番号が格納されています。
Trunk: [next_trunk: u32] [leaf_count: u32] [leaf_pages: u32...]
Turso の実装
主なファイル:
core/storage/sqlite3_ondisk.rs- オンディスク形式、PageType列挙型core/storage/btree.rs- B ツリー操作(大きなファイル)core/storage/pager.rs- ページ管理core/storage/buffer_pool.rs- ページキャッシュ
ストレージのデバッグ
# Integrity check
cargo run --bin tursodb test.db "PRAGMA integrity_check;"
# Page count
cargo run --bin tursodb test.db "PRAGMA page_count;"
# Freelist info
cargo run --bin tursodb test.db "PRAGMA freelist_count;"
参考資料
コメント
Markdown 対応