From 06cab92ba15acbac4de88237a9dd2b8bac8f3959 Mon Sep 17 00:00:00 2001 From: adm01-debug Date: Mon, 25 May 2026 10:26:11 -0300 Subject: [PATCH] =?UTF-8?q?fix(db):=20aplica=20idle=5F*=5Ftimeout=20e=20lo?= =?UTF-8?q?g=5Fmin=5Fduration=5Fstatement=20(Fase=206=20p=C3=B3s-colapso)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fecha 2 dos 3 itens P0/P1 pendentes do RELATORIO_COLAPSO_2026-05-24: - #3 idle_session_timeout = 0 -> 10min (ALTER DATABASE) idle_in_transaction_session_timeout = 0 -> 60s (ALTER DATABASE) - #10 log_min_duration_statement = -1 -> 2000ms (ALTER ROLE, via supautils) Aplicado via MCP em 2026-05-25 13:00-13:20 UTC. Conexão PostgREST zumbi de 10.9 dias (PID 2376) foi eliminada na hora pelo novo idle_session_timeout. Operações idempotentes - reaplicação pelo pipeline é segura. Restante pendente: #6 Auth Connection Strategy (so via Dashboard). --- ...fase6_idle_timeouts_e_log_slow_queries.sql | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 supabase/migrations/20260525132458_colapso_fase6_idle_timeouts_e_log_slow_queries.sql diff --git a/supabase/migrations/20260525132458_colapso_fase6_idle_timeouts_e_log_slow_queries.sql b/supabase/migrations/20260525132458_colapso_fase6_idle_timeouts_e_log_slow_queries.sql new file mode 100644 index 000000000..d6ad15785 --- /dev/null +++ b/supabase/migrations/20260525132458_colapso_fase6_idle_timeouts_e_log_slow_queries.sql @@ -0,0 +1,90 @@ +-- ============================================================================ +-- Fase 6 (Follow-up Pós-Colapso 2026-05-24) +-- ============================================================================ +-- Fecha 2 dos 3 itens P0/P1 pendentes documentados em: +-- docs/RELATORIO_COLAPSO_2026-05-24.md +-- +-- Achados endereçados: +-- #3 Conexões PostgREST idle persistem por dias (causa raiz #3 do colapso) +-- idle_session_timeout = 0 -> 10 min +-- idle_in_transaction_session_timeout = 0 -> 60 s +-- +-- #10 Queries lentas não eram logadas (forense pós-mortem ficava cego) +-- log_min_duration_statement = -1 -> 2000 ms +-- +-- ---------------------------------------------------------------------------- +-- Contexto da decisão técnica +-- ---------------------------------------------------------------------------- +-- Os ALTER DATABASE abaixo passam normalmente para o role da aplicação. +-- +-- log_min_duration_statement, porém, tem Context: superuser no Postgres. +-- ALTER DATABASE postgres SET log_min_duration_statement = '2000' RETORNA +-- ERROR 42501 (permission denied). A doc oficial do Supabase documenta que +-- a extensão supautils libera essa modificação APENAS no nível de ROLE: +-- +-- https://supabase.com/docs/guides/database/custom-postgres-config +-- #superuser-settings +-- +-- Por isso este parâmetro usa ALTER ROLE em vez de ALTER DATABASE. +-- +-- ---------------------------------------------------------------------------- +-- Aplicado via MCP em 2026-05-25 13:00-13:20 UTC +-- Executor: Abner Silva (TI Promo Brindes) +-- Esta migration registra a mudança no histórico do repo. Como os 3 ALTERs +-- são idempotentes, a reaplicação pelo pipeline é segura. +-- ============================================================================ + +-- ---------------------------------------------------------------------------- +-- Achado #3 - Settings de timeout para conexões idle +-- ---------------------------------------------------------------------------- +-- Aplica a NOVAS conexões. Sessões já abertas mantêm o valor antigo até serem +-- recicladas. Validação imediata da aplicação no banco mostrou: +-- - PID 2376 (PostgREST idle há 10.9 dias) foi eliminado automaticamente +-- - Conexões idle totais: 8 -> 4 +-- - Idle > 1 dia: 1 -> 0 +-- ---------------------------------------------------------------------------- +ALTER DATABASE postgres SET idle_session_timeout = '600000'; -- 10 min em ms +ALTER DATABASE postgres SET idle_in_transaction_session_timeout = '60000'; -- 60 s em ms + +-- ---------------------------------------------------------------------------- +-- Achado #10 - Logar queries com duração > 2 s +-- ---------------------------------------------------------------------------- +-- Persistido em pg_roles.rolconfig. Validação imediata: +-- SELECT rolconfig FROM pg_roles WHERE rolname = 'postgres'; +-- -- retorna ["search_path=...", "log_min_duration_statement=2000"] +-- ---------------------------------------------------------------------------- +ALTER ROLE "postgres" SET "log_min_duration_statement" TO '2000'; -- 2 s em ms + +-- ============================================================================ +-- Validação esperada pós-deploy (rodar manualmente no SQL Editor) +-- ============================================================================ +-- +-- -- Settings persistidos no level DATABASE: +-- SELECT split_part(unnest(setconfig), '=', 1) AS setting, +-- split_part(unnest(setconfig), '=', 2) AS valor +-- FROM pg_db_role_setting +-- WHERE setdatabase = (SELECT oid FROM pg_database WHERE datname='postgres'); +-- -- Esperado: +-- -- idle_session_timeout = 600000 +-- -- idle_in_transaction_session_timeout = 60000 +-- +-- -- Setting persistido no level ROLE: +-- SELECT rolname, rolconfig FROM pg_roles WHERE rolname = 'postgres'; +-- -- rolconfig deve conter "log_min_duration_statement=2000" +-- +-- -- Conexões idle de longa duração (deve ser zero ou muito poucas): +-- SELECT pid, application_name, +-- round(EXTRACT(EPOCH FROM (now() - state_change)) / 60)::int AS idle_min +-- FROM pg_stat_activity +-- WHERE state = 'idle' +-- AND state_change < now() - interval '1 hour' +-- AND backend_type = 'client backend' +-- ORDER BY state_change ASC; +-- +-- ============================================================================ +-- Pendência remanescente do RELATORIO_COLAPSO_2026-05-24 +-- ============================================================================ +-- #6 Auth Connection Strategy: Absolute (10) -> Percentage (15%) +-- Não pode ser feito por SQL. Caminho: Supabase Dashboard -> +-- Authentication -> Settings -> Database Connection Strategy. +-- ============================================================================