fix(fts): drop and recreate code_fts to clear recurring SQLITE_CORRUPT_VTAB#138
Conversation
…T_VTAB (#135) migration 0002 で適用した FTS5 'rebuild' のみではトライグラム側 (code_fts) の SQLITE_CORRUPT_VTAB が再発したため、migration 0003 で `DROP TABLE` + `CREATE VIRTUAL TABLE` + 'rebuild' によりテーブル本体を作り直す形に強化する。 影響範囲は `search_docs_code_fts` のみ。`search_docs_nat_fts` は再発が観測されていないため触らない。0001 のトリガ (`trg_search_docs_ai/ad/au`) はテーブル名参照のため、再作成後そのまま機能する。 適用は merge 後に Master が `npx wrangler d1 migrations apply github-rag-fts --remote` で実行する (`package.json` に専用スクリプトはない)。 Closes #135
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
github-rag-mcp | a12e9e7 | Apr 28 2026, 12:19 PM |
liplus-lin-lay
left a comment
There was a problem hiding this comment.
Self-review (auto mode)
Why DROP+CREATE is more thorough than 'rebuild'-only
FTS5 の 'rebuild' コマンドは内部インデックスの再構築 (segments / docsize / config の再書き出し) であり、仮想テーブルそのもののスキーマメタデータが malformed になっているケースには届かない。0002 適用後 4 日で code_fts のみ再発した事実は、root cause が「インデックス内容の不整合」ではなく「仮想テーブル定義レコード側の破損」にある可能性を示している。DROP TABLE で sqlite_master から定義を削除し、CREATE VIRTUAL TABLE で fresh に再作成した後で 'rebuild' で search_docs から再投入する手順は、その上位の故障モードまでカバーする。
Risk: 適用中の一時的乖離
migration 適用中、DROP TABLE 完了から 'rebuild' 完了までの間、search_docs と search_docs_code_fts の間で行が乖離する瞬間がある。ただし:
pollDiffs→processAndUpsertCommitDiff側に try/catch 包囲があり、FTS upsert 失敗は primary store (Vectorize) を阻害しない (#135 観測時の挙動と同じ)。- 適用は短時間 (
search_docs≒ 1100 行規模)。 - 適用は merge 後 Master の手動実行で、cron トリガ (
:30の pollDiffs) と重なる窓は短い。
許容範囲。
Why nat_fts is untouched
PR #137 のログ強化以降、再発エラーは tokenizerKind=code のみで観測されており、nat 側の corruption は 0002 適用後再発していない。trigram tokenizer 側だけの故障モードと判断できるため、scope を絞って code_fts のみ作り直す。nat_fts を巻き込むのは blast radius を不要に広げる。
適用手順の明確さ
PR body に raw コマンド (npx wrangler d1 migrations apply github-rag-fts --remote) と D1 binding 情報 (DB_FTS / github-rag-fts) を明記済み。package.json に専用 script がない事実も付記。
0001 との定義一致確認
0001 の search_docs_code_fts 定義 (lines 82-87) と 0003 の CREATE VIRTUAL TABLE 句を文字単位で照合済み。USING fts5、content、tokenize = 'trigram case_sensitive 0'、content = 'search_docs'、content_rowid = 'rowid' すべて完全一致。
Verdict
APPROVE. Merge 可。
概要
D1 FTS5 仮想テーブル
search_docs_code_fts(trigram tokenizer) でSQLITE_CORRUPT_VTABが再発し続けている件 (#135) の根本対処。DROP TABLE+CREATE VIRTUAL TABLE+ FTS5'rebuild'でテーブル本体を作り直す migration 0003 を追加する。Closes #135経緯 (なぜ 0002 から 0003 へ)
nat_fts/code_fts両方に FTS5'rebuild'を適用して SQLITE_CORRUPT_VTAB を一旦解消。errorName=Error/D1_ERROR: database disk image is malformed: SQLITE_CORRUPT_VTABがcode_fts側のみ 全 5 リポジトリの diff upsert で再発していることを確認 (tokenizerKind=code, contentChars=965-1164)。'rebuild'は内部インデックスの再構築だが、仮想テーブル本体のメタ構造そのものが malformed の場合は不十分。テーブルを DROP して作り直すのがより徹底した対処。変更内容
migrations/0003_fts5_code_recreate.sqlDROP TABLE IF EXISTS search_docs_code_fts;CREATE VIRTUAL TABLE IF NOT EXISTS search_docs_code_fts USING fts5 (...)— 0001 の定義と完全一致 (trigram, case_sensitive=0, content=search_docs, content_rowid=rowid)INSERT INTO search_docs_code_fts(search_docs_code_fts) VALUES('rebuild');—search_docsから再投入src/pipeline.ts/src/fts.tsは正しい。corruption は D1 schema 状態のみの問題)。影響範囲
search_docs_code_ftsのみ。search_docs_nat_ftsは再発が観測されていないため触らない。trg_search_docs_ai/ad/au) はテーブル名参照のため、新テーブル作成後にそのまま機能する。search_docsとsearch_docs_code_ftsが一時的に乖離するが、pollDiffs側に try/catch があるため許容範囲。適用手順 (merge 後 Master が実行)
(
package.jsonに専用スクリプトはないため raw コマンド。D1 binding 名 =DB_FTS、database_name =github-rag-fts。)実行モード
auto mode。CI pass 後に AI が self-review し、parent agent が squash merge する。