mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-14 14:40:52 +00:00
47 lines
2.4 KiB
SQL
47 lines
2.4 KiB
SQL
-- v1.32.40 — indexes for the retention purges.
|
|
--
|
|
-- The nightly tombstone purge asks for `deleted_at IS NOT NULL AND deleted_at
|
|
-- < cutoff`, and the audit-log purge asks for `created_at < cutoff`. Neither
|
|
-- predicate had an index: every `deleted_at` index in the schema is PARTIAL on
|
|
-- `deleted_at IS NULL` (the live-rows predicate, the exact opposite of what a
|
|
-- purge needs), and every `audit_logs` index leads with `user_id` or `action`.
|
|
-- Both purges therefore planned a sequential scan and paid index maintenance
|
|
-- on every removed row. Each connection carries `statement_timeout=60000`
|
|
-- (`src/lib/db.ts`), so past a certain backlog the statement aborts, the
|
|
-- transaction rolls back, nothing is purged, and the next night runs the same
|
|
-- statement against the same rows. The purge that was meant to give deletion a
|
|
-- horizon could not close on the instances that needed it most.
|
|
--
|
|
-- The purges are batched as of the same release, so no single statement is on
|
|
-- the hook for a whole backlog; these indexes are what make each batch's
|
|
-- lookup cheap instead of a fresh sequential scan per batch.
|
|
--
|
|
-- The three tombstone indexes are PARTIAL on `deleted_at IS NOT NULL`, which
|
|
-- is the shape that matters here: on a healthy instance the index covers only
|
|
-- the tombstones, so it stays tiny and shrinks as the purge drains. Prisma
|
|
-- cannot express a partial predicate, so these stay raw-SQL-only — the same
|
|
-- convention as migrations 0087 / 0108 / 0243, noted at the model in
|
|
-- `schema.prisma`. `audit_logs(created_at)` is expressible and is declared on
|
|
-- the model.
|
|
--
|
|
-- Additive-only: every statement is `CREATE INDEX IF NOT EXISTS`, no table
|
|
-- rewrite, no data change. NON-CONCURRENT on purpose — Prisma Migrate wraps a
|
|
-- migration file in a transaction and `CREATE INDEX CONCURRENTLY` cannot run
|
|
-- in one; these build at boot, where docker-entrypoint runs `migrate deploy`
|
|
-- before the app serves traffic, so the build lock lands pre-traffic.
|
|
|
|
CREATE INDEX IF NOT EXISTS "measurements_tombstone_purge_idx"
|
|
ON "measurements" ("deleted_at")
|
|
WHERE "deleted_at" IS NOT NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS "mood_entries_tombstone_purge_idx"
|
|
ON "mood_entries" ("deleted_at")
|
|
WHERE "deleted_at" IS NOT NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS "medication_intake_events_tombstone_purge_idx"
|
|
ON "medication_intake_events" ("deleted_at")
|
|
WHERE "deleted_at" IS NOT NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS "audit_logs_created_at_idx"
|
|
ON "audit_logs" ("created_at");
|