Skip to content

fix(fts): drop and recreate code_fts to clear recurring SQLITE_CORRUPT_VTAB#138

Merged
liplus-lin-lay merged 1 commit into
mainfrom
135-bugfts-d1-fts5-upsert-failures-observed-for-diff-rows-across-all-repos-1
Apr 28, 2026
Merged

fix(fts): drop and recreate code_fts to clear recurring SQLITE_CORRUPT_VTAB#138
liplus-lin-lay merged 1 commit into
mainfrom
135-bugfts-d1-fts5-upsert-failures-observed-for-diff-rows-across-all-repos-1

Conversation

@liplus-lin-lay
Copy link
Copy Markdown
Member

概要

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 へ)

  • 2026-04-24: migration 0002 で nat_fts / code_fts 両方に FTS5 'rebuild' を適用して SQLITE_CORRUPT_VTAB を一旦解消。
  • 2026-04-28: PR chore(fts): enrich D1 upsert failure logs to surface root cause (#135) #137 のログ強化で errorName=Error / D1_ERROR: database disk image is malformed: SQLITE_CORRUPT_VTABcode_fts 側のみ 全 5 リポジトリの diff upsert で再発していることを確認 (tokenizerKind=code, contentChars=965-1164)。
  • 'rebuild' は内部インデックスの再構築だが、仮想テーブル本体のメタ構造そのものが malformed の場合は不十分。テーブルを DROP して作り直すのがより徹底した対処。

変更内容

  • 追加: migrations/0003_fts5_code_recreate.sql
    • DROP 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 は再発が観測されていないため触らない。
  • 0001 のトリガ (trg_search_docs_ai/ad/au) はテーブル名参照のため、新テーブル作成後にそのまま機能する。
  • migration 適用中に search_docssearch_docs_code_fts が一時的に乖離するが、pollDiffs 側に try/catch があるため許容範囲。

適用手順 (merge 後 Master が実行)

npx wrangler d1 migrations apply github-rag-fts --remote

(package.json に専用スクリプトはないため raw コマンド。D1 binding 名 = DB_FTS、database_name = github-rag-fts。)

実行モード

auto mode。CI pass 後に AI が self-review し、parent agent が squash merge する。

…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
@liplus-lin-lay liplus-lin-lay added the bug 動いていない、壊れている label Apr 28, 2026
@liplus-lin-lay liplus-lin-lay self-assigned this Apr 28, 2026
@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
github-rag-mcp a12e9e7 Apr 28 2026, 12:19 PM

Copy link
Copy Markdown
Member Author

@liplus-lin-lay liplus-lin-lay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_docssearch_docs_code_fts の間で行が乖離する瞬間がある。ただし:

  • pollDiffsprocessAndUpsertCommitDiff 側に 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 fts5contenttokenize = 'trigram case_sensitive 0'content = 'search_docs'content_rowid = 'rowid' すべて完全一致。

Verdict

APPROVE. Merge 可。

@liplus-lin-lay liplus-lin-lay merged commit 1727a0b into main Apr 28, 2026
3 checks passed
@liplus-lin-lay liplus-lin-lay deleted the 135-bugfts-d1-fts5-upsert-failures-observed-for-diff-rows-across-all-repos-1 branch April 28, 2026 12:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug 動いていない、壊れている

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(fts): D1 FTS5 upsert failures observed for diff rows across all repos

1 participant