9 pontos por GN⁺ 2025-07-28 | 2 comentários | Compartilhar no WhatsApp
  • Introdução a uma abordagem experimental sobre combinações de parâmetros que podem degradar drasticamente o desempenho do Postgres
  • Em vez de otimizar, o texto ajusta ao contrário vários elementos como cache, índices, WAL e I/O
  • Ao manipular de forma extrema shared_buffers, autovacuum e opções relacionadas a WAL, foi alcançada uma queda de TPS de 42.000 vezes
  • Também foram aplicados recursos recentes como io_method e io_workers das novas versões Postgres 18/19 para testar a limitação a uma única thread de I/O
  • O experimento demonstra que é possível provocar degradação extrema de desempenho apenas com o arquivo de configuração do Postgres

Visão geral

Este texto apresenta um experimento que faz o oposto do ajuste de Postgres normalmente voltado a deixá-lo mais rápido: o único objetivo é deixá-lo lento, alterando apenas vários valores de configuração do PostgreSQL para degradar o desempenho até o limite.
O teste foi baseado na carga TPC-C do BenchBase (128 armazéns, 100 conexões, tentativa de até 10.000 transações por segundo para cada uma, Postgres 19devel mais recente, Ryzen 7950x, 32 GB de RAM, SSD de 2 TB, execução por 120 segundos).
Com os valores padrão, o desempenho era de 7082 TPS, e foi observado passo a passo o quanto ele ficava mais lento com cada manipulação de parâmetro.

Reduzindo drasticamente o cache

  • O Postgres usa um cache poderoso (shared_buffers) para reduzir I/O de disco
  • Ao reduzir shared_buffers de 10 GB para 8 MB, o TPS caiu para cerca de 1/7 (1052 TPS)
  • A taxa de cache hit caiu de 99,90% para 70,52%, e foi observado um aumento de mais de 300 vezes nas syscalls de leitura
  • Houve tentativa de reduzir até 128 kB, mas o Postgres só permitiu cerca de 2 MB como mínimo, levando a nova queda para 485 TPS

Aumentando o trabalho em segundo plano (ajuste de autovacuum)

  • Todos os limiares relacionados a autovacuum foram colocados no mínimo, fazendo com que o vacuum rodasse praticamente a cada operação
    • Combinação como autovacuum_vacuum_insert_threshold=1, autovacuum_naptime=1 etc.
    • Mesmo quando não havia trabalho real a fazer, o vacuum se repetia quase a cada 1 segundo
  • Nesse processo, maintenance_work_mem foi reduzido para 128 kB, e todo o logging de autovacuum foi ativado
  • Como resultado, o TPS caiu para 293 (menos de 1/20 do original)
  • Pelos logs em tempo real de autovacuum, foi confirmado que o desempenho piorava devido ao trabalho frequente em segundo plano

Tornando a gravação de WAL (Write-Ahead Log) a pior possível

  • Os parâmetros relacionados a WAL foram ajustados todos para o pior cenário
    • wal_writer_flush_after=0, wal_writer_delay=1, wal_sync_method=open_datasync etc.
    • Checkpoints forçados a cada 30 segundos, com min/max_wal_size=32MB mantidos no mínimo
    • wal_level=logical, wal_log_hints=on e até informações desnecessárias sendo gravadas no WAL
    • Cargas extras como track_wal_io_timing e summarize_wal também foram ativadas
  • Com isso, o TPS caiu para 98 (menos de 1/70 do original)
  • Nos logs, foi observado comportamento anormal, como checkpoints se repetindo a cada poucas centenas de ms

Eliminando o efeito dos índices

  • O uso de índices foi configurado para que todos fossem calculados com custo máximo (random_page_cost=1e300, cpu_index_tuple_cost=1e300), inutilizando-os na prática
  • shared_buffers foi aumentado para 8 MB (por estabilidade), e o TPS despencou para 0,87 (atingindo 7.000 vezes mais lentidão)

Forçando I/O em thread única

  • Uso de recursos mais recentes do Postgres 18+
  • Com io_method=worker e io_workers=1, todo o I/O foi forçado para uma única thread worker
  • O TPS caiu ainda mais, para 0,016 (42.000 vezes mais lento)
  • Em um teste com 100 conexões por 120 segundos, o desempenho ficou tão limitado que apenas 11 transações foram concluídas com sucesso

Conclusão e guia de reprodução

  • Foi demonstrado que, com um total de 32 manipulações de parâmetros, é possível levar um banco de produção a um estado de praticamente "paralisia"
  • É possível maximizar a degradação de desempenho mexendo apenas na configuração de postgresql.conf
  • Quem quiser reproduzir o experimento deve consultar o BenchBase Postgres, o ambiente TPC-C descrito acima e a lista completa de configurações
  • Alguns parâmetros adicionais e outras tentativas de deixá-lo ainda mais lento não foram incluídos

Lista resumida de parâmetros

  • shared_buffers = 8MB
  • thresholds/scale_factor relacionados a autovacuum = minimizados para 0~1
  • custos, memória e logs relacionados a vacuum: mínimo & máximo
  • sync/flush/log/nível relacionados a WAL: mantidos no modo mais lento
  • random_page_cost, cpu_index_tuple_cost ligados a índice: definidos como 1e300
  • io_method = worker, io_workers = 1
  • Para outros valores detalhados, consultar a lista no corpo do texto

Encerramento

  • É possível provocar degradação severa de desempenho apenas com o arquivo postgresql.conf
  • Na prática, vale a pena usar essa combinação ao contrário como referência para melhoria eficiente de desempenho
  • O texto termina mencionando a interrupção do experimento por causa de dor nas costas do autor

2 comentários

 
GN⁺ 2025-07-28
Opiniões no Hacker News
  • Apresenta uma forma de usar tudo como se fosse KVS NoSQL SQL em uma única tabela, como nas primeiras versões do TRIRIGA, esquecendo completamente coisas como índices, várias tabelas, transações, relacionamentos entre entidades e integridade referencial
  • Isso é tão divertido que eu adoraria ver até uma série contínua de livros sobre "como estragar ainda mais o trabalho"; dá para aprender e, por contraste, encontrar formas melhores de fazer as coisas. Em estilo O’Reilly, a capa poderia vir com um animal de fantasia mal desenhado (por exemplo, um unicórnio com cabeças dos dois lados falando no AirPods, dando dinheiro para golpistas, fazendo PowerPoint, comendo demais e usando drogas)
    • Houve até um caso real em que esse tipo de estratégia foi usado na Segunda Guerra Mundial: para aumentar a sobrevivência dos pilotos, meteorologistas primeiro identificaram as condições que causavam mais mortes e depois planejaram as missões para evitá-las. Link de referência: Suppose I wanted to kill a lot of pilots
    • Em aulas de escrita criativa, também fazíamos exercícios de ler e analisar textos mal escritos, ou reescrever de propósito um bom texto de forma ruim; foi o exercício de escrita que mais me ajudou
    • Também vale ver o site de paródia ORLYBooks
  • Seria realmente ótimo ter um sandbox de ambiente de produção para experimentar ferramentas de observabilidade, com um sistema estilo SaaS de tamanho razoável, simulação de uso, e uma pilha postgres/rabbit mais ou menos comum para testar na prática a qualidade de ferramentas ou estratégias de depuração
  • Essa ideia é genial de verdade; se você quer ficar bom em otimização, faz sentido primeiro destruir tudo de propósito como ponto de partida ou grupo de controle. Vale se perguntar se você realmente trata bancos de dados ou sistemas de forma científica, ou se só está seguindo práticas no automático
    • Eu sempre faço isso quando começo a usar um novo serviço de nuvem: primeiro tento gastar o mais rápido possível até o Series A, e só depois parto para a otimização de custos na nuvem
  • O livro The Defence of Duffer's Drift é um exemplo inicial desse gênero: na primeira história, as táticas de pelotão são um desastre e ele perde quase todo mundo; nas histórias seguintes, as condições táticas vão mudando e os resultados melhoram aos poucos. Livros táticos mais recentes, como Musicians of Mars 2, seguem a mesma abordagem. A primeira história do Team Badger é muito parecida com Duffer's Drift, mas adaptada conforme localização, equipamento e tecnologia. Os PDFs relacionados podem ser vistos em The Defence of Duffer's Drift e Musicians of Mars 2. Achei marcante como, depois da derrota humilhante, o comandante do Team Badger revisita por que foi derrotado de forma tão catastrófica apesar da confiança e da preparação
    • Em um contexto parecido, há filmes como Groundhog Day e especialmente Edge of Tomorrow, além de uma homenagem moderna publicada recentemente em um blog militar britânico: Defence Baltic Bridge Dreams
  • A menção a deadlock foi interessante; fiquei curioso se também haverá uma parte sobre ajustar configurações de nível de isolamento de transações
  • Fiquei feliz com a menção a B Sanderson
  • Parece uma mistura de Hyperbole and a Half com admin de banco de dados; fiquei de bom humor lendo e ainda aprendi algumas coisas
  • O estilo de escrita e a forma de desenvolver as ideias foram excelentes; foi uma leitura divertida
 
sonic0987 2025-07-29

Excelente. Gosto muito desse tipo de abordagem.