From b6c430a71fff537956d11131f904eb45e4c21b9d Mon Sep 17 00:00:00 2001 From: Tomas Valenta <49156497+ValentaTomas@users.noreply.github.com> Date: Fri, 24 Jul 2026 20:58:49 -0700 Subject: [PATCH 1/4] fix(db): drop duplicate snapshots sandbox_id index --- ...p_duplicate_snapshots_sandbox_id_index.sql | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 packages/db/migrations/20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql diff --git a/packages/db/migrations/20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql b/packages/db/migrations/20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql new file mode 100644 index 0000000000..9b3aebd328 --- /dev/null +++ b/packages/db/migrations/20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql @@ -0,0 +1,28 @@ +-- +goose Up +-- +goose NO TRANSACTION + +-- DROP only waits on in-flight lock holders; bound the wait so it neither +-- hangs unbounded nor dies to a short session default. +SET statement_timeout = '1h'; + +-- Exact duplicate of snapshots_sandbox_id_unique (same single column, same +-- order): the planner always has the unique index available, and this copy +-- recorded 0 lifetime scans in pg_stat_user_indexes while every snapshot +-- write paid its ~6 GiB maintenance tax. +DROP INDEX CONCURRENTLY IF EXISTS public.idx_snapshots_sandbox_id; + +-- +goose Down +-- +goose NO TRANSACTION + +-- A concurrent rebuild on a table this size can run for hours, and a +-- mid-build timeout would strand an INVALID index. Rolling back is a +-- deliberate manual operation with an operator present — unbounded on +-- purpose. +SET statement_timeout = 0; + +-- An interrupted CONCURRENTLY build leaves an INVALID index that IF NOT +-- EXISTS would then skip forever — clear any leftover before rebuilding. +DROP INDEX CONCURRENTLY IF EXISTS public.idx_snapshots_sandbox_id; + +CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_snapshots_sandbox_id + ON public.snapshots (sandbox_id); From 3e51c88a3486060ef79371f5c82276329e5590c6 Mon Sep 17 00:00:00 2001 From: Tomas Valenta <49156497+ValentaTomas@users.noreply.github.com> Date: Fri, 24 Jul 2026 22:06:23 -0700 Subject: [PATCH 2/4] review: reset statement_timeout for the reused migrator session --- ...0725040700_drop_duplicate_snapshots_sandbox_id_index.sql | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/db/migrations/20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql b/packages/db/migrations/20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql index 9b3aebd328..a41174c4e7 100644 --- a/packages/db/migrations/20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql +++ b/packages/db/migrations/20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql @@ -11,6 +11,10 @@ SET statement_timeout = '1h'; -- write paid its ~6 GiB maintenance tax. DROP INDEX CONCURRENTLY IF EXISTS public.idx_snapshots_sandbox_id; +-- The migrator session is reused for subsequent migrations — don't leak the +-- widened bound into them. +RESET statement_timeout; + -- +goose Down -- +goose NO TRANSACTION @@ -26,3 +30,5 @@ DROP INDEX CONCURRENTLY IF EXISTS public.idx_snapshots_sandbox_id; CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_snapshots_sandbox_id ON public.snapshots (sandbox_id); + +RESET statement_timeout; From 5088995c2d7c7e55285eefa199941802d7d0cf3b Mon Sep 17 00:00:00 2001 From: Tomas Valenta <49156497+ValentaTomas@users.noreply.github.com> Date: Fri, 24 Jul 2026 22:15:41 -0700 Subject: [PATCH 3/4] review: restore the migrator baseline instead of RESET --- ...40700_drop_duplicate_snapshots_sandbox_id_index.sql | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/db/migrations/20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql b/packages/db/migrations/20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql index a41174c4e7..833e6e23c3 100644 --- a/packages/db/migrations/20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql +++ b/packages/db/migrations/20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql @@ -11,9 +11,10 @@ SET statement_timeout = '1h'; -- write paid its ~6 GiB maintenance tax. DROP INDEX CONCURRENTLY IF EXISTS public.idx_snapshots_sandbox_id; --- The migrator session is reused for subsequent migrations — don't leak the --- widened bound into them. -RESET statement_timeout; +-- The migrator session is reused for subsequent migrations: restore its +-- baseline (scripts/migrator.go sets 3h per connection; RESET would clear +-- to the unbounded server default instead). +SET statement_timeout = '3h'; -- +goose Down -- +goose NO TRANSACTION @@ -31,4 +32,5 @@ DROP INDEX CONCURRENTLY IF EXISTS public.idx_snapshots_sandbox_id; CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_snapshots_sandbox_id ON public.snapshots (sandbox_id); -RESET statement_timeout; +-- Restore the migrator session baseline (see Up). +SET statement_timeout = '3h'; From 1670e07895c405796d5f155365bb69fdd58844b1 Mon Sep 17 00:00:00 2001 From: Tomas Valenta <49156497+ValentaTomas@users.noreply.github.com> Date: Sat, 25 Jul 2026 15:32:28 -0700 Subject: [PATCH 4/4] scrub size figure from migration comment --- ...20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/db/migrations/20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql b/packages/db/migrations/20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql index 833e6e23c3..67726bdaf9 100644 --- a/packages/db/migrations/20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql +++ b/packages/db/migrations/20260725040700_drop_duplicate_snapshots_sandbox_id_index.sql @@ -8,7 +8,7 @@ SET statement_timeout = '1h'; -- Exact duplicate of snapshots_sandbox_id_unique (same single column, same -- order): the planner always has the unique index available, and this copy -- recorded 0 lifetime scans in pg_stat_user_indexes while every snapshot --- write paid its ~6 GiB maintenance tax. +-- write paid its maintenance tax. DROP INDEX CONCURRENTLY IF EXISTS public.idx_snapshots_sandbox_id; -- The migrator session is reused for subsequent migrations: restore its