improvement(search): run Search retirement as an operator command instead of a deploy step - #8522
Conversation
…tead of a deploy step Deploys no longer register the 0027-0029 Search retirement. A long cleanup in the deploy migration generated heavy WAL and stalled application writes, and held the release until it finished. The retirement is optional storage reclamation once live Search is on, so it now runs as a resumable operator command, paced by --pause-ratio and --max-rows, with --maintenance running the index rebuilds and vacuum and journaling completion.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
|
There was a problem hiding this comment.
No issues found across 6 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
This PR changes a database schema or migrates data. Ultrareviews find 2.4x more serious bugs than standard reviews. Comment @cubic-dev-ai ultrareview to run one.
Re-trigger cubic
Summary
Deploys no longer run the Search retirement (
0027–0029). It becomes an operator-run, resumable, paced maintenance command. Supersedes #8521, which proposed a background scheduler; that is not needed for a one-off cleanup.Why: a long cleanup inside the deploy migration generated heavy WAL. Checkpoints became WAL-triggered back to back, commits waited on synchronous replication, and application writes hit lock and statement timeouts. It also held the release until it finished. The retirement is optional storage reclamation once live Search is on, so it does not belong on the deploy's critical path.
Changes
packages/db/script-migrations/index.tsdrops0029. The registry rule allows deleting an entry, never renaming or reordering one. A deploy's migration run no longer creates or touches the cleanup tables.0027_retire_search_embeddings.ts, entry point unchanged):--pause-ratio N(default2): after each page, pause N × the page's duration, capped at one minute (it was 1× capped at 5 s). Pages are timed through their commit, so a slow synchronous replica or a checkpoint stall lengthens the pause.--max-rows N(default2000, range 25–8,000): lowers the starting row limit and the ceiling it can grow to.--maintenance: also runs the HNSW rebuilds and vacuum, and journals0029with its superseded names. A plain run only retires, journals nothing, and resumes the saved cursor.0029is nowretireAllSearchEmbeddings(pacing), used by the command and by tests.search-embedding-retirement.mdis rewritten as an operator runbook:Behaviour changes
0026. Databases mid-way through the retirement keep their progress row and cursor, and the command resumes them.Not changed: findings from #8521's review that no longer apply
knowledge_baseIDs in one repeatable-read transaction. It is cheap, and it now runs only when an operator starts the command.Precedent
Test plan
0016_backfill_search_vectors.integration.tsasserts that the cleanup tables do not exist afterrunScriptMigrations(sql). It went red with0029re-registered.0027_retire_search_embeddings.integration.tsuses a statement trigger that makes each delete page take about 100 ms; with a ratio of 3, consecutive pages must start at least 380 ms apart. It went red with the pause removed (123 ms).retireAllSearchEmbeddings()instead of filtering the registry.--max-rowsis rejected, a plain run on an empty database finishes and journals nothing, and--maintenancejournals.bun run lint,packages/dbtype-check, andbun run check:audits(53) all pass.