Noções Básicas de Cenários de Falha
7 exemplos para você começar a modelar cenários de falha - 5 básicos e 2 intermediários.
Pré-requisitos
- Banco de dados de laboratório PostgreSQL 18.4.
- Acesso de leitura a padrões de consulta semelhantes aos de produção (
EXPLAIN,pg_stat_statements).
Exemplos Básicos
1. Fan-Out Infla Agregados
Uma junção de muitos para muitos contada como um para muitos dobra a receita em painéis.
-- Ruim: a junção de tags multiplica as linhas de pedido
SELECT o.order_id, SUM(oi.amount) AS total
FROM orders o
JOIN order_items oi ON oi.order_id = o.order_id
JOIN order_tags ot ON ot.order_id = o.order_id
GROUP BY o.order_id;
-- Cada item de linha repetido por tag- Falha de modelagem: a consulta assume 1:1 entre pedidos e tags.
- Sintoma: totais financeiros excedem o processador de pagamento por um fator consistente.
- Correção: agregar itens de linha em uma subconsulta antes de juntar as tags.
Relacionado: Explosão de Junção Fan-Out - depuração de cardinalidade
2. Linhas Órfãs Sem Chaves Estrangeiras
O aplicativo exclui pais; os filhos permanecem para sempre.
CREATE TABLE comments (
comment_id bigint PRIMARY KEY,
post_id bigint NOT NULL -- nenhuma cláusula REFERENCES
);
DELETE FROM posts WHERE post_id = 99;
-- comments com post_id = 99 ainda existem- FK ausente permite linhas órfãs quando bugs do aplicativo ou SQL de administrador pulam a limpeza.
- Sintoma: a interface do usuário mostra comentários em posts excluídos ou links quebrados.
- Correção: adicionar FK com a ação
ON DELETEapropriada.
Relacionado: Chaves Estrangeiras Ausentes - imposição de integridade
3. Valor Enum Bloqueado Sob Carga
Adicionar um valor enum durante o tráfego mantém um bloqueio ACCESS EXCLUSIVE brevemente.
CREATE TYPE order_status AS ENUM ('draft', 'placed');
-- Migração posterior sob carga:
ALTER TYPE order_status ADD VALUE 'shipped';
-- Bloqueio breve; aplicativos enfileiram no caminho crítico- Migrações de Enum são eventos DDL - dolorosas em colunas de
statuscom QPS alto. - Sintoma: pico de latência p99 durante a implantação; rollbacks complicados.
- Correção:
text+CHECKou estratégia de enum expandir-contrair.
Relacionado: Dor na Migração de Enum - alterações seguras de enum
4. Timestamp Sem Fuso Horário Deriva
O horário local armazenado quebra quando o horário de verão muda ou os usuários viajam.
CREATE TABLE meetings (
meeting_id bigint PRIMARY KEY,
starts_at timestamp WITHOUT TIME ZONE -- instante ambíguo
);
INSERT INTO meetings VALUES (1, '2026-03-08 02:30:00');
-- Qual fuso horário? Lacuna de horário de verão? Desconhecido.timestamp without time zonenão armazena deslocamento - aplicativos globais agendam reuniões incorretamente.- Sintoma: calendário com uma hora de atraso duas vezes por ano; tickets de suporte se concentram em torno do horário de verão.
- Correção:
timestamptzarmazenado em UTC.
Relacionado: Bugs de Timestamp Sem Fuso Horário - incidentes de horário de verão
5. Detectar Órfãos com LEFT JOIN
Consulta padrão de qualidade de dados para imposição de FK ausente.
SELECT c.comment_id, c.post_id
FROM comments c
LEFT JOIN posts p ON p.post_id = c.post_id
WHERE p.post_id IS NULL;- Resultado não vazio significa integridade referencial quebrada.
- Executar após migrações que removem FKs "temporariamente".
- Adicionar ao trabalho noturno de qualidade de dados.
Exemplos Intermediários
6. EXPLAIN Revela Explosão Cartesiana
A estimativa de linha salta após adicionar uma junção inocente.
EXPLAIN (ANALYZE, BUFFERS)
SELECT COUNT(*) FROM orders o
JOIN order_items oi ON oi.order_id = o.order_id
JOIN order_promotions op ON op.order_id = o.order_id;- Compare a contagem real de linhas com a expectativa ingênua de
orders * items * promotions. - Loop aninhado em um conjunto intermediário inflado sinaliza um bug de modelagem ou ordem de junção.
- Corrigir o esquema (tabelas de junção) ou reescrever a consulta com subconsultas.
Relacionado: Explosão de Junção Fan-Out - padrões de reescrita
7. Pós-Mortem para Regra de Lint
Transforme o incidente em prevenção automatizada.
-- Verificação pseudo-regra de lint: tabelas que terminam em _id devem ter metadados FK
SELECT c.conrelid::regclass AS table_name, c.conname
FROM pg_constraint c
WHERE c.contype = 'f';- Documente a classe de falha no runbook: "FK ausente em colunas
*_id". - CI analisa o SQL de migração em busca de
REFERENCESem novas colunas em forma de FK. - O checklist de revisão de esquema referencia as páginas de cenário de falha.
Relacionado: Melhores Práticas de Cenários de Falha - integração de lint
Versões da pilha: 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+.