Skip to content

Commit ce207dd

Browse files
committed
chore(search): keep retirement usage in the CLI
1 parent 46e9c73 commit ce207dd

4 files changed

Lines changed: 22 additions & 216 deletions

File tree

‎packages/db/maintenance/search-retirement.md‎

Lines changed: 0 additions & 194 deletions
This file was deleted.

‎packages/db/script-migrations/index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export const scriptMigrations: readonly ScriptMigration[] = [
6060
userTableSchemaForWriteMigration,
6161
/**
6262
* Search retirement (0027–0029) is an operator-run maintenance command, not a deploy step:
63-
* see `search-embedding-retirement.md`.
63+
* run `packages/db/scripts/retire-indexed-search.ts --help` for usage.
6464
*/
6565
]
6666

‎packages/db/script-migrations/search-embedding-retirement.md‎

Lines changed: 0 additions & 18 deletions
This file was deleted.

‎packages/db/scripts/retire-indexed-search.ts‎

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,26 @@ Every write except abort requires --health-file PATH --health-policy PATH.
3939
Policy databaseId must equal the identity command's fingerprint.
4040
Run options: --page-size 25 (1–100), --pages 1 (1–120), --seconds 60 (1–600).
4141
A fixed pause of at least 5 seconds follows each page. Timeouts stop; no automatic retry.
42-
Connection: MIGRATION_DATABASE_URL, direct primary or session pooling only.
43-
See packages/db/maintenance/search-retirement.md before use.`
42+
Connection: MIGRATION_DATABASE_URL, PostgreSQL 17+, direct primary or session pooling only.
43+
44+
Deploy the code-removal release and drain old workers first. Then:
45+
prepare -> run until ready -> cutover -> verify retrieval -> begin-purge
46+
-> run until finalize -> finalize. Repeat run if late writes return the phase to purge.
47+
Reads use the old projection until cutover. The retained backup is not an instant rollback.
48+
Cutover requires pg_read_all_stats and no old snapshots; never automatically retry DDL gates.
49+
Abort, backup removal and finalization cap implicit DROP lock waits at 1 ms.
50+
After retirement starts, use versioned migrations; db:push would restore old projection machinery.
51+
52+
Health files are UTF-8 JSON, at most 8 KiB, atomically refreshed by trusted telemetry.
53+
Sample fields: observedAt (oldest metric timestamp, UTC ISO), databaseId, healthy,
54+
maintenanceAllowed, cutoverAllowed, replicaLagBytes, replicaLagSeconds,
55+
walBytesPerSecond, databaseP95Ms, cpuPercent, freeStorageBytes.
56+
Policy fields: databaseId, maxReplicaLagBytes, maxReplicaLagSeconds, maxWalBytesPerSecond,
57+
maxDatabaseP95Ms, maxCpuPercent, minFreeStorageBytes, maxSampleAgeMs (at most 30000).
58+
Choose limits from actual capacity and latency requirements; missing/stale telemetry stops work.
59+
Use worst replica lag and CPU, and minimum free storage; healthy includes application error/latency checks.
60+
Set cutoverAllowed only after primary and replica snapshots are clear for DDL.
61+
Pacing limits load but cannot eliminate latency or replica-conflict risk.`
4462

4563
function integerOption(value: string | undefined, fallback: number, ceiling: number): number {
4664
const parsed = value === undefined ? fallback : Number(value)
@@ -201,7 +219,7 @@ try {
201219
? error.message
202220
: code
203221
? 'Database refused the operation'
204-
: 'Preflight or command failed; check the runbook and options',
222+
: 'Preflight or command failed; use --help to check options',
205223
...(code ? { code } : {}),
206224
})
207225
process.exitCode = 1

0 commit comments

Comments
 (0)