-
-
Notifications
You must be signed in to change notification settings - Fork 134
fix(ops): make Capgo-EU reclaim SQL Editor safe #2733
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,26 +1,28 @@ | ||||||||||||||||||||||||||
| -- Capgo-EU Phase A reclaim (run manually in a maintenance window). | ||||||||||||||||||||||||||
| -- REQUIRED: psql for VACUUM (cannot run inside a transaction / SQL-editor tx). | ||||||||||||||||||||||||||
| -- Prefer ~/.pgpass / PGPASSFILE instead of putting the password on the CLI. | ||||||||||||||||||||||||||
| -- Capgo-EU Phase A reclaim — safe for Supabase SQL Editor. | ||||||||||||||||||||||||||
| -- Paste this whole file into SQL Editor and run. | ||||||||||||||||||||||||||
| -- | ||||||||||||||||||||||||||
| -- Schema source of truth: migration 20260722154010_app_versions_manifest_present_idx. | ||||||||||||||||||||||||||
| -- Optional non-blocking prebuild before that migration deploys: | ||||||||||||||||||||||||||
| -- psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f scripts/ops/reclaim_supabase_swap_index.sql | ||||||||||||||||||||||||||
| -- Prerequisites (deploy first, or this script fails the preflight): | ||||||||||||||||||||||||||
| -- - 20260722082019_fix_supabase_swap_memory | ||||||||||||||||||||||||||
| -- - 20260722154010_app_versions_manifest_present_idx | ||||||||||||||||||||||||||
| -- | ||||||||||||||||||||||||||
| -- Example: | ||||||||||||||||||||||||||
| -- psql "postgresql://postgres@HOST:5432/postgres?sslmode=require" -v ON_ERROR_STOP=1 -f scripts/ops/reclaim_supabase_swap.sql | ||||||||||||||||||||||||||
| -- Safe order: truncate -> archives -> null manifests -> audit trim. | ||||||||||||||||||||||||||
| -- Re-run the FULL script until cleanup notices report deleted/updated = 0 | ||||||||||||||||||||||||||
| -- (functions always emit a notice, including zero totals). | ||||||||||||||||||||||||||
| -- Re-run until Notices show deleted/updated = 0 (functions always raise a notice). | ||||||||||||||||||||||||||
| -- VACUUM is NOT here: SQL Editor wraps work in a transaction and rejects VACUUM. | ||||||||||||||||||||||||||
| -- Optional later via psql: scripts/ops/reclaim_supabase_swap_vacuum.sql | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| SET lock_timeout = '5s'; | ||||||||||||||||||||||||||
| SET statement_timeout = '180s'; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| -- --------------------------------------------------------------------------- | ||||||||||||||||||||||||||
| -- 0) Baseline sizes + require a valid candidate index | ||||||||||||||||||||||||||
| -- 0) Preflight + baseline sizes | ||||||||||||||||||||||||||
| -- --------------------------------------------------------------------------- | ||||||||||||||||||||||||||
| SELECT pg_size_pretty(pg_database_size(current_database())::bigint) AS db_size; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| DO $$ | ||||||||||||||||||||||||||
| BEGIN | ||||||||||||||||||||||||||
| IF to_regprocedure('public.null_migrated_app_version_manifests()') IS NULL | ||||||||||||||||||||||||||
| OR to_regprocedure('public.cleanup_net_http_response()') IS NULL THEN | ||||||||||||||||||||||||||
| RAISE EXCEPTION | ||||||||||||||||||||||||||
| 'Missing reclaim functions. Deploy migration 20260722082019_fix_supabase_swap_memory first.'; | ||||||||||||||||||||||||||
| END IF; | ||||||||||||||||||||||||||
|
Comment on lines
+20
to
+24
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win Make the preflight match the functions this script invokes. The check omits 🔧 Proposed fix IF to_regprocedure('public.null_migrated_app_version_manifests()') IS NULL
+ OR to_regprocedure('public.cleanup_queue_messages()') IS NULL
+ OR to_regprocedure('public.cleanup_old_audit_logs()') IS NULL
OR to_regprocedure('public.cleanup_net_http_response()') IS NULL THEN📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| IF NOT EXISTS ( | ||||||||||||||||||||||||||
| SELECT 1 | ||||||||||||||||||||||||||
| FROM pg_catalog.pg_class AS idx | ||||||||||||||||||||||||||
|
|
@@ -32,9 +34,12 @@ BEGIN | |||||||||||||||||||||||||
| AND i.indisvalid | ||||||||||||||||||||||||||
| ) THEN | ||||||||||||||||||||||||||
| RAISE EXCEPTION | ||||||||||||||||||||||||||
| 'Missing or invalid app_versions_manifest_present_idx. Deploy migration 20260722154010 (or run scripts/ops/reclaim_supabase_swap_index.sql alone first if the index is invalid/missing).'; | ||||||||||||||||||||||||||
| 'Missing or invalid app_versions_manifest_present_idx. Deploy migration 20260722154010 first.'; | ||||||||||||||||||||||||||
| END IF; | ||||||||||||||||||||||||||
| END $$; | ||||||||||||||||||||||||||
| END | ||||||||||||||||||||||||||
| $$; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| SELECT pg_size_pretty(pg_database_size(current_database())::bigint) AS db_size; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| SELECT | ||||||||||||||||||||||||||
| relname, | ||||||||||||||||||||||||||
|
|
@@ -54,45 +59,25 @@ WHERE (schemaname, relname) IN ( | |||||||||||||||||||||||||
| ORDER BY pg_total_relation_size(format('%I.%I', schemaname, relname)::regclass) DESC; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| -- --------------------------------------------------------------------------- | ||||||||||||||||||||||||||
| -- 1) Truncate pg_net response bloat | ||||||||||||||||||||||||||
| -- 1) Truncate pg_net response bloat (biggest immediate win) | ||||||||||||||||||||||||||
| -- --------------------------------------------------------------------------- | ||||||||||||||||||||||||||
| TRUNCATE TABLE net._http_response; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| -- --------------------------------------------------------------------------- | ||||||||||||||||||||||||||
| -- 2) Purge pgmq archives/stuck messages. | ||||||||||||||||||||||||||
| -- Re-run the FULL script until archived_deleted=0 and stuck_deleted=0. | ||||||||||||||||||||||||||
| -- 2) Purge pgmq archives/stuck messages (batched; re-run until notice = 0) | ||||||||||||||||||||||||||
| -- --------------------------------------------------------------------------- | ||||||||||||||||||||||||||
| SELECT public.cleanup_queue_messages(); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| VACUUM (VERBOSE) pgmq.a_on_version_update; | ||||||||||||||||||||||||||
| VACUUM (VERBOSE) pgmq.a_on_manifest_create; | ||||||||||||||||||||||||||
| VACUUM (VERBOSE) pgmq.a_webhook_dispatcher; | ||||||||||||||||||||||||||
| VACUUM (VERBOSE) pgmq.a_on_channel_update; | ||||||||||||||||||||||||||
| VACUUM (VERBOSE) pgmq.q_on_version_update; | ||||||||||||||||||||||||||
| VACUUM (VERBOSE) pgmq.q_on_manifest_create; | ||||||||||||||||||||||||||
| VACUUM (VERBOSE) pgmq.q_webhook_dispatcher; | ||||||||||||||||||||||||||
| VACUUM (VERBOSE) pgmq.q_on_channel_update; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| -- --------------------------------------------------------------------------- | ||||||||||||||||||||||||||
| -- 3) Null fully migrated app_versions.manifest arrays (s3_path + file_hash). | ||||||||||||||||||||||||||
| -- Re-run the FULL script until updated=0. | ||||||||||||||||||||||||||
| -- 3) Null fully migrated app_versions.manifest arrays (re-run until notice = 0) | ||||||||||||||||||||||||||
| -- --------------------------------------------------------------------------- | ||||||||||||||||||||||||||
| SELECT public.null_migrated_app_version_manifests(); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| VACUUM (ANALYZE, VERBOSE) public.app_versions; | ||||||||||||||||||||||||||
| -- Optional TOAST compaction after updated=0: | ||||||||||||||||||||||||||
| -- VACUUM (FULL, VERBOSE) public.app_versions; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| -- --------------------------------------------------------------------------- | ||||||||||||||||||||||||||
| -- 4) Trim audit_logs older than 30 days. | ||||||||||||||||||||||||||
| -- Re-run the FULL script until deleted=0. | ||||||||||||||||||||||||||
| -- 4) Trim audit_logs older than 30 days (re-run until notice = 0) | ||||||||||||||||||||||||||
| -- --------------------------------------------------------------------------- | ||||||||||||||||||||||||||
| SELECT public.cleanup_old_audit_logs(); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| VACUUM (ANALYZE, VERBOSE) public.audit_logs; | ||||||||||||||||||||||||||
| -- Optional TOAST compaction after deleted=0: | ||||||||||||||||||||||||||
| -- VACUUM (FULL, VERBOSE) public.audit_logs; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| -- --------------------------------------------------------------------------- | ||||||||||||||||||||||||||
| -- 5) Final sizes | ||||||||||||||||||||||||||
| -- --------------------------------------------------------------------------- | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| -- Capgo-EU immediate reclaim — safe for Supabase SQL Editor. | ||
| -- Single statement. Run alone. No migration required. | ||
| -- Frees net._http_response bloat (~5GB on Capgo-EU when empty/stale). | ||
|
|
||
| TRUNCATE TABLE net._http_response; | ||
|
Comment on lines
+1
to
+5
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🔵 Trivial Bound lock acquisition for the standalone TRUNCATE. Unlike 🤖 Prompt for AI AgentsThere was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: On a busy database, this standalone path can wait indefinitely behind an active query or pg_net worker and leave the SQL Editor run hanging. Adding the same lock and statement time bounds as the full reclaim path, or requiring them in the operator session, would keep this emergency script bounded. Prompt for AI agents |
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,22 @@ | ||||||||||||||||||||||||||||||||
| -- Optional Capgo-EU reclaim VACUUM — psql only (NOT SQL Editor). | ||||||||||||||||||||||||||||||||
| -- Run after scripts/ops/reclaim_supabase_swap.sql when deleted/updated notices are 0. | ||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Cleanup functions are capped per invocation, so a non-zero SQL Editor pass commits dead tuples before the next pass; waiting for notices to reach 0 lets bloat accumulate during a reclaim. The runbook should run this psql file after every reclaim pass, then rerun the full reclaim script until the notices are 0. (Based on your team's feedback about rerunning the full reclaim script after cleanup batches.) Prompt for AI agents
Suggested change
|
||||||||||||||||||||||||||||||||
| -- | ||||||||||||||||||||||||||||||||
| -- Example: | ||||||||||||||||||||||||||||||||
| -- psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f scripts/ops/reclaim_supabase_swap_vacuum.sql | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| VACUUM (VERBOSE) pgmq.a_on_version_update; | ||||||||||||||||||||||||||||||||
| VACUUM (VERBOSE) pgmq.a_on_manifest_create; | ||||||||||||||||||||||||||||||||
| VACUUM (VERBOSE) pgmq.a_webhook_dispatcher; | ||||||||||||||||||||||||||||||||
| VACUUM (VERBOSE) pgmq.a_on_channel_update; | ||||||||||||||||||||||||||||||||
| VACUUM (VERBOSE) pgmq.q_on_version_update; | ||||||||||||||||||||||||||||||||
| VACUUM (VERBOSE) pgmq.q_on_manifest_create; | ||||||||||||||||||||||||||||||||
| VACUUM (VERBOSE) pgmq.q_webhook_dispatcher; | ||||||||||||||||||||||||||||||||
| VACUUM (VERBOSE) pgmq.q_on_channel_update; | ||||||||||||||||||||||||||||||||
|
Comment on lines
+7
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: The reclaim step cleans every Prompt for AI agents
Suggested change
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| VACUUM (ANALYZE, VERBOSE) public.app_versions; | ||||||||||||||||||||||||||||||||
| -- Optional TOAST compaction after dual-storage nulling is done: | ||||||||||||||||||||||||||||||||
| -- VACUUM (FULL, VERBOSE) public.app_versions; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| VACUUM (ANALYZE, VERBOSE) public.audit_logs; | ||||||||||||||||||||||||||||||||
| -- Optional TOAST compaction after audit trim is done: | ||||||||||||||||||||||||||||||||
| -- VACUUM (FULL, VERBOSE) public.audit_logs; | ||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,6 +1,5 @@ | ||||||||||||||||||||||||
| -- Post-deploy / post-reclaim verification for Capgo-EU swap pressure. | ||||||||||||||||||||||||
| -- REQUIRED: psql (uses \gexec). Example: | ||||||||||||||||||||||||
| -- psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f scripts/ops/verify_supabase_swap.sql | ||||||||||||||||||||||||
| -- Capgo-EU post-reclaim verification — safe for Supabase SQL Editor. | ||||||||||||||||||||||||
| -- Paste into SQL Editor and run (no psql meta-commands). | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| SELECT pg_size_pretty(pg_database_size(current_database())::bigint) AS db_size; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -52,6 +51,10 @@ FROM ( | |||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
| ) AS eligible; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| SELECT count(*)::bigint AS non_null_manifest_versions | ||||||||||||||||||||||||
| FROM public.app_versions | ||||||||||||||||||||||||
| WHERE manifest IS NOT NULL; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
Comment on lines
+54
to
+57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Running this verification now scans every non-null manifest to produce an exact count, which can add substantial load or time out in SQL Editor on the production-sized (Based on your team's feedback about bounded verification queries.) . Prompt for AI agents
Suggested change
|
||||||||||||||||||||||||
| SELECT | ||||||||||||||||||||||||
| name, | ||||||||||||||||||||||||
| enabled, | ||||||||||||||||||||||||
|
|
@@ -70,7 +73,15 @@ WHERE name IN ( | |||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
| ORDER BY name; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| SELECT indexname | ||||||||||||||||||||||||
| SELECT indexname, | ||||||||||||||||||||||||
| ( | ||||||||||||||||||||||||
| SELECT i.indisvalid | ||||||||||||||||||||||||
| FROM pg_catalog.pg_class AS idx | ||||||||||||||||||||||||
| JOIN pg_catalog.pg_namespace AS ns ON ns.oid = idx.relnamespace | ||||||||||||||||||||||||
| JOIN pg_catalog.pg_index AS i ON i.indexrelid = idx.oid | ||||||||||||||||||||||||
| WHERE ns.nspname = 'public' | ||||||||||||||||||||||||
| AND idx.relname = 'app_versions_manifest_present_idx' | ||||||||||||||||||||||||
| ) AS indisvalid | ||||||||||||||||||||||||
| FROM pg_indexes | ||||||||||||||||||||||||
| WHERE schemaname = 'public' | ||||||||||||||||||||||||
| AND indexname = 'app_versions_manifest_present_idx'; | ||||||||||||||||||||||||
|
|
@@ -82,33 +93,44 @@ SELECT EXISTS ( | |||||||||||||||||||||||
| LIMIT 1 | ||||||||||||||||||||||||
| ) AS has_audit_logs_older_than_30d; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| SELECT format( | ||||||||||||||||||||||||
| $fmt$SELECT %L AS queue_name, | ||||||||||||||||||||||||
| EXISTS ( | ||||||||||||||||||||||||
| SELECT 1 | ||||||||||||||||||||||||
| FROM pgmq.%I | ||||||||||||||||||||||||
| WHERE archived_at < now() - interval '2 days' | ||||||||||||||||||||||||
| LIMIT 1 | ||||||||||||||||||||||||
| ) AS has_rows_older_than_2d;$fmt$, | ||||||||||||||||||||||||
| queue_name, | ||||||||||||||||||||||||
| 'a_' || pg_catalog.lower(queue_name) | ||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
| FROM pgmq.list_queues() | ||||||||||||||||||||||||
| \gexec | ||||||||||||||||||||||||
| -- Fixed Capgo-EU queue set (no psql \gexec). | ||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Queue verification now reports only four queues, so the SQL Editor run can show a clean result while other deployed pgmq queues still contain rows that Prompt for AI agents |
||||||||||||||||||||||||
| SELECT 'a_on_manifest_create' AS queue_name, | ||||||||||||||||||||||||
| EXISTS ( | ||||||||||||||||||||||||
| SELECT 1 FROM pgmq.a_on_manifest_create | ||||||||||||||||||||||||
| WHERE archived_at < now() - interval '2 days' LIMIT 1 | ||||||||||||||||||||||||
| ) AS has_rows_older_than_2d | ||||||||||||||||||||||||
| UNION ALL SELECT 'a_on_version_update', | ||||||||||||||||||||||||
| EXISTS ( | ||||||||||||||||||||||||
| SELECT 1 FROM pgmq.a_on_version_update | ||||||||||||||||||||||||
| WHERE archived_at < now() - interval '2 days' LIMIT 1 | ||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
| UNION ALL SELECT 'a_webhook_dispatcher', | ||||||||||||||||||||||||
| EXISTS ( | ||||||||||||||||||||||||
| SELECT 1 FROM pgmq.a_webhook_dispatcher | ||||||||||||||||||||||||
| WHERE archived_at < now() - interval '2 days' LIMIT 1 | ||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
| UNION ALL SELECT 'a_on_channel_update', | ||||||||||||||||||||||||
| EXISTS ( | ||||||||||||||||||||||||
| SELECT 1 FROM pgmq.a_on_channel_update | ||||||||||||||||||||||||
| WHERE archived_at < now() - interval '2 days' LIMIT 1 | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| SELECT format( | ||||||||||||||||||||||||
| $fmt$SELECT %L AS queue_name, | ||||||||||||||||||||||||
| EXISTS ( | ||||||||||||||||||||||||
| SELECT 1 | ||||||||||||||||||||||||
| FROM pgmq.%I | ||||||||||||||||||||||||
| WHERE read_ct > 5 | ||||||||||||||||||||||||
| LIMIT 1 | ||||||||||||||||||||||||
| ) AS has_stuck_read_ct_gt_5;$fmt$, | ||||||||||||||||||||||||
| queue_name, | ||||||||||||||||||||||||
| 'q_' || pg_catalog.lower(queue_name) | ||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
| FROM pgmq.list_queues() | ||||||||||||||||||||||||
| \gexec | ||||||||||||||||||||||||
| SELECT 'q_on_manifest_create' AS queue_name, | ||||||||||||||||||||||||
| EXISTS ( | ||||||||||||||||||||||||
| SELECT 1 FROM pgmq.q_on_manifest_create WHERE read_ct > 5 LIMIT 1 | ||||||||||||||||||||||||
| ) AS has_stuck_read_ct_gt_5 | ||||||||||||||||||||||||
| UNION ALL SELECT 'q_on_version_update', | ||||||||||||||||||||||||
| EXISTS ( | ||||||||||||||||||||||||
| SELECT 1 FROM pgmq.q_on_version_update WHERE read_ct > 5 LIMIT 1 | ||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
| UNION ALL SELECT 'q_webhook_dispatcher', | ||||||||||||||||||||||||
| EXISTS ( | ||||||||||||||||||||||||
| SELECT 1 FROM pgmq.q_webhook_dispatcher WHERE read_ct > 5 LIMIT 1 | ||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
| UNION ALL SELECT 'q_on_channel_update', | ||||||||||||||||||||||||
| EXISTS ( | ||||||||||||||||||||||||
| SELECT 1 FROM pgmq.q_on_channel_update WHERE read_ct > 5 LIMIT 1 | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| SELECT | ||||||||||||||||||||||||
| 'index hit rate' AS name, | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3: A successful run can leak the new 180-second timeout into a reused SQL Editor session, causing later unrelated queries to fail after 180 seconds.
SET LOCAL statement_timeout = '180s'would constrain the limit to this pasted transaction instead of changing the session.Prompt for AI agents