Noções Básicas de Incidentes
8 exemplos para você começar com a resposta a incidentes Postgres - 5 básicos e 3 intermediários.
Pré-requisitos
# Confirm you can reach the primary and have a read-only role for triage
psql "$DATABASE_URL" -c "SELECT version();"
psql "$DATABASE_URL" -c "SELECT pg_is_in_recovery();"- Acesso a
pg_stat_activity,pg_lockse visualizações de replicação. - Uma rotação de plantão com um caminho de escalonamento documentado.
- Runbooks armazenados em git, não em um wiki que ninguém lê durante as interrupções.
Exemplos Básicos
1. Classificação de Severidade
Mapeie o impacto do usuário a um nível de severidade antes de alterar a produção.
| Severidade | Impacto no usuário | Alvo de resposta |
|---|---|---|
| Sev-1 | Perda de dados, interrupção total ou violação de segurança | Chamar imediatamente; sala de guerra |
| Sev-2 | Gravações degradadas ou taxa de erro elevada | Chamar o plantão; corrigir em horas |
| Sev-3 | Consultas lentas, dor de inquilino único | Correção em horário comercial |
| Sev-4 | Cosmético ou apenas interno | Backlog |
- Sev-1 inclui a retenção de slot de replicação WAL preenchendo o disco no primário.
- Sev-2 inclui o esgotamento do pool de conexões causando 503s.
- Reclassifique quando os fatos mudarem; não fixe a severidade na primeira mensagem do pager.
Relacionado: Melhores Práticas de Resposta a Incidentes - higiene de runbook
2. Checklist dos Primeiros 15 Minutos
Execute esta sequência antes do diagnóstico aprofundado.
-- 1. Is the instance accepting connections?
SELECT now() AS ts, pg_is_in_recovery() AS is_replica;
-- 2. Who is connected and what are they waiting on?
SELECT pid, usename, application_name, state, wait_event_type, wait_event,
now() - query_start AS query_age, left(query, 120) AS query_snip
FROM pg_stat_activity
WHERE pid <> pg_backend_pid()
ORDER BY query_start NULLS LAST
LIMIT 30;
-- 3. Blocked sessions?
SELECT blocked.pid AS blocked_pid, blocking.pid AS blocking_pid,
left(blocked.query, 80) AS blocked_q
FROM pg_stat_activity blocked
JOIN pg_stat_activity blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid))
WHERE cardinality(pg_blocking_pids(blocked.pid)) > 0;- Poste o status no canal de incidentes a cada 15 minutos durante Sev-1/2.
- Atribua funções: Comandante do Incidente, Comunicações, Líder Técnico, Scribe.
- Capture timestamps para cada ação; você precisará deles para o post-mortem.
3. Modelo de Comunicação
Mantenha as partes interessadas informadas sem vazar texto de consulta confidencial.
[INC-1234] Sev-2 - Elevated API latency on checkout service
Status: Investigating
Impact: ~15% of checkout requests timing out after 30s
Start: 2026-07-09 14:22 UTC
Actions: Checking connection pool saturation and lock waits on primary
Next update: 14:37 UTC- Link para a página de status, se você tiver uma.
- Não cole senhas de produção, PII ou saída completa de
EXPLAINem canais públicos. - Informe o produto quando você espera a próxima atualização, mesmo que a resposta seja "ainda investigando".
4. Role Segura de Triagem Somente Leitura
Crie uma role que possa diagnosticar sem mutar dados.
CREATE ROLE incident_reader LOGIN PASSWORD 'rotate-after-incident';
GRANT pg_read_all_stats TO incident_reader;
GRANT CONNECT ON DATABASE app TO incident_reader;
GRANT USAGE ON SCHEMA public TO incident_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO incident_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO incident_reader;- Rotacione as credenciais após o encerramento do incidente.
- Prefira réplicas de leitura para consultas de diagnóstico pesadas durante picos de carga.
- Nunca conceda
SUPERUSERpara contas de plantão "apenas para o incidente".
5. Quando Realizar Failover
Failover é uma decisão de negócios, não apenas técnica.
# Patroni example: check cluster state before manual failover
patronictl -c /etc/patroni/patroni.yml list- Faça failover quando o primário for irrecuperável ou a corrupção for confirmada no primário.
- Não faça failover apenas para consultas lentas; corrija a consulta ou mate os bloqueadores primeiro.
- Espere breves erros de conexão durante a troca de DNS ou proxy; avise as equipes de aplicativos.
Relacionado: Emergência de Lag de Replicação - triagem de lag antes da reconstrução
Exemplos Intermediários
6. Captura de Linha do Tempo do Incidente
Notas estruturadas tornam os post-mortems rápidos.
mkdir -p incidents/INC-1234
cat >> incidents/INC-1234/timeline.md <<'EOF'
| Time (UTC) | Actor | Action |
|------------|-------|--------|
| 14:22 | pager | Sev-2 opened, checkout latency |
| 14:25 | dba | pg_stat_activity shows 200 idle in transaction |
EOF- Armazene artefatos em git: consultas executadas, saída de
EXPLAIN, diferenças de configuração. - Redija dados do cliente antes de confirmar.
- Vincule a linha do tempo ao ticket Jira/Linear.
7. Terminação Coordenada de Backend
Termine apenas com política e registro.
-- Find long idle-in-transaction sessions (common incident root cause)
SELECT pid, usename, application_name, state,
now() - xact_start AS xact_age, query
FROM pg_stat_activity
WHERE state = 'idle in transaction'
AND now() - xact_start > interval '5 minutes';
-- Terminate one backend (requires appropriate role)
SELECT pg_terminate_backend(12345);- Exija aprovação de duas pessoas para
pg_terminate_backendem Sev-1, a menos que seja um runbook automatizado. - Registre
pid,application_namee ID do ticket no canal de incidentes. - Após a terminação em massa, observe as tempestades de conexão através do PgBouncer.
8. Passagem para Post-Mortem
Feche o ciclo do incidente com acompanhamentos acionáveis.
## Post-Mortem Required (Sev-1/2)
- Root cause (5 Whys)
- Time to detect / time to mitigate
- What went well
- Action items with owners and due dates
- Runbook updates merged to main- Agende o post-mortem em até cinco dias úteis.
- Cultura sem culpa: foque em sistemas e processos, não em indivíduos.
- Cada item de ação precisa de um responsável; "equipe" não é um responsável.
Relacionado: Triagem de Tempestade de Bloqueio - quando a terminação é a mitigação
Versões da Stack: Esta página foi escrita para PostgreSQL 18.4 (estável 18, manutenção 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x e PostGIS 3.5+.