Solucionando Alta Atividade de WAL e Gerenciando Espaço em Disco de Logs de Arquivo
Aprenda a solucionar e gerenciar a geração excessiva de Write-Ahead Log (WAL) no PostgreSQL. Este guia aborda causas comuns de alta atividade de WAL, como operações em massa e problemas de replicação, e fornece soluções práticas para configurar o arquivamento de WAL, gerenciar slots de replicação e evitar a exaustão do espaço em disco. Leitura essencial para administradores de PostgreSQL focados em estabilidade e utilização eficiente do espaço em disco.
Solucionando Alta Atividade de WAL e Gerenciando Espaço em Disco de Logs de Arquivo
Alta atividade de Write-Ahead Log (WAL) no PostgreSQL não é automaticamente um problema. Um banco de dados movimentado deve gerar WAL. O problema é quando a taxa de WAL surpreende, quando o WAL arquivado nunca é limpo, ou quando pg_wal cresce porque algo está impedindo o PostgreSQL de reciclar segmentos antigos.
A maneira mais rápida de piorar um incidente de WAL é deletar arquivos de pg_wal manualmente. Não faça isso. Trate um disco de WAL cheio como uma situação de recuperação: identifique o que está retendo WAL, crie espaço se puder com segurança, e então corrija o arquivamento falho, o standby atrasado ou o slot abandonado que causou o crescimento.
Entendendo o Write-Ahead Logging (WAL)
O PostgreSQL escreve registros de alteração no WAL antes que as páginas de dados relacionadas sejam gravadas com segurança. Após uma falha, o PostgreSQL reproduz o WAL para que as alterações confirmadas não sejam perdidas. O mesmo fluxo também é usado para replicação em streaming e recuperação point-in-time.
Os arquivos WAL são armazenados em arquivos de segmento de tamanho fixo. Muitas instalações usam segmentos de 16 MB porque esse é o padrão comum, mas o tamanho é escolhido quando o cluster é inicializado. Uma carga de trabalho pesada de gravação pode criar um grande número de segmentos rapidamente. Segmentos antigos são reciclados ou removidos somente após o PostgreSQL não precisar mais deles para recuperação de falhas, checkpoints, arquivamento, replicação ou slots.
Conceitos Chave de WAL:
- Durabilidade: transações confirmadas podem ser recuperadas após uma falha.
- Replicação: os standbys recebem registros WAL do primário.
- Recuperação Point-in-Time (PITR): backups completos mais WAL arquivado permitem recuperar para um ponto escolhido dentro da sua janela de retenção.
- Segmentos WAL: o WAL é armazenado em arquivos de segmento sob
pg_wal.
Causas Comuns de Alta Atividade de WAL
Vários fatores podem contribuir para um volume anormalmente alto de geração de WAL. Identificar a causa raiz é o primeiro passo para uma solução eficaz.
1. Carregamento e Modificações de Dados em Massa
Operações como INSERT, UPDATE, DELETE, TRUNCATE e COPY podem gerar quantidades significativas de WAL. Operações em massa, especialmente em tabelas grandes, naturalmente produzirão mais registros WAL do que pequenas transações individuais.
- Exemplo: Um único comando
COPY FROMpara inserir milhões de linhas pode gerar gigabytes de dados WAL. - Exemplo: Executar uma migração de dados em larga escala ou um script de atualização em lote.
2. Atraso de Replicação e Problemas de Standby
Se seus servidores standby não estão acompanhando o primário (atraso de replicação), os arquivos WAL se acumularão no primário. O servidor primário não pode remover segmentos WAL concluídos até que eles tenham sido confirmados como enviados e processados por todos os standbys conectados (se wal_keep_size ou max_slot_wal_keep_size não estiver configurado, ou se os slots não forem usados corretamente).
- Cenário: Um servidor standby está inativo, desconectado ou enfrentando problemas de desempenho, impedindo-o de consumir registros WAL do primário.
3. Gravações de Página Completa Após Checkpoints
Após um checkpoint, a primeira alteração em uma página de dados pode registrar uma imagem de página completa quando full_page_writes está habilitado. Essa configuração protege a recuperação de páginas corrompidas e normalmente é mantida ativada. Se os checkpoints acontecerem com muita frequência, as imagens de página completa podem aumentar visivelmente o volume de WAL. A correção geralmente é ajustar o comportamento do checkpoint, não desabilitar as proteções de durabilidade.
4. Crescimento Não Gerenciado do Diretório pg_wal
Se o arquivamento WAL estiver habilitado e falhando, o PostgreSQL mantém segmentos WAL que ainda precisam ser arquivados. Se o arquivamento não estiver habilitado, pg_wal ainda deve reciclar segmentos antigos quando não forem mais necessários, a menos que replicação, slots ou pressão de checkpoint os estejam retendo.
5. Slots de Replicação Não Recuperados
Slots de replicação garantem que os segmentos WAL não sejam removidos antes de serem consumidos por um standby específico ou cliente de decodificação lógica. Se um slot é criado, mas o consumidor para ou desconecta sem que o slot seja removido, os segmentos WAL exigidos por esse slot serão retidos, mesmo que o standby não esteja mais ativo.
Gerenciando Espaço em Disco de WAL: Configuração e Soluções
Abordar a alta atividade de WAL requer uma abordagem multifacetada envolvendo monitoramento, ajuste de configuração e procedimentos de manutenção adequados.
1. Habilitar e Monitorar o Arquivamento WAL
O arquivamento WAL é o mecanismo mais crítico para gerenciar espaço em disco e habilitar PITR. Quando o arquivamento está habilitado, os arquivos WAL concluídos são copiados para um local separado (por exemplo, um compartilhamento de arquivos de rede, bucket S3 ou um disco diferente).
Configuração:
Modifique seu arquivo postgresql.conf:
wal_level = replica # Ou logical para replicação lógica
archive_mode = on # Habilitar arquivamento
archive_command = 'cp %p /caminho/para/arquivo/%f'
# Exemplo para S3 usando wal-g ou ferramenta similar:
# archive_command = 'wal-g wal-push %p'
%p: Placeholder para o caminho completo do arquivo WAL a ser arquivado.%f: Placeholder para o nome do arquivo WAL.
Importante: O archive_command deve ser capaz de executar com sucesso. Se retornar um código de saída diferente de zero, o PostgreSQL considerará que o arquivamento falhou, o que pode levar a arquivos WAL não serem removidos. Certifique-se de que o diretório de destino tenha espaço suficiente e que o usuário que executa o PostgreSQL tenha permissões de gravação.
Monitorando o Arquivamento
Use consultas SQL para verificar o status do arquivamento:
SELECT archived_count,
failed_count,
last_archived_wal,
last_archived_time,
last_failed_wal,
last_failed_time
FROM pg_stat_archiver;
Se failed_count continuar aumentando ou last_archived_time estiver antigo enquanto o banco de dados ainda está escrevendo, corrija o destino do arquivamento antes de ajustar os parâmetros de tamanho do WAL.
2. Gerenciando o Tamanho do Diretório pg_wal
Mesmo com o arquivamento habilitado, o diretório pg_wal no primário pode crescer se os segmentos WAL não forem removidos após o arquivamento. Isso acontece se:
- Os standbys não estão acompanhando e o primário está retendo WAL extra para replicação.
- Slots de replicação estão segurando arquivos WAL.
wal_keep_size
Este parâmetro mantém WAL extra no primário para replicação em streaming. Ele substituiu a configuração mais antiga wal_keep_segments no PostgreSQL 13. É útil para standbys que não usam slots, mas não é uma garantia de que um standby muito atrasado possa sempre alcançar.
# postgresql.conf no primário
wal_keep_size = 1024 # Manter 1GB de WAL no disco
Slots de replicação são frequentemente preferidos quando você precisa que o primário retenha WAL para um consumidor específico, mas os slots devem ser monitorados porque podem reter WAL indefinidamente.
max_slot_wal_keep_size (PostgreSQL 13+)
Esta configuração limita quanto WAL um slot de replicação pode reter. É uma proteção contra crescimento ilimitado de um slot quebrado, mas também pode fazer com que um consumidor atrasado perca o WAL necessário e exija reinicialização.
# postgresql.conf no primário
max_slot_wal_keep_size = 2048 # Limitar slots a reter 2GB de WAL
# Considere também: wal_keep_size -- ainda relevante para streaming não baseado em slot
# wal_keep_size = 1024 # Manter 1GB para streaming sem slot
Se um slot ficar muito atrasado e exceder este limite, o PostgreSQL pode remover o WAL necessário no momento do checkpoint. Isso protege o espaço em disco, mas o standby afetado ou o cliente de replicação lógica pode não conseguir mais continuar de sua posição antiga.
Slots de Replicação
Slots de replicação são cruciais para evitar perda de WAL e garantir replicação confiável. No entanto, eles podem causar acúmulo de arquivos WAL se não forem gerenciados corretamente.
- Problema: Um slot de replicação é criado, mas o consumidor (standby ou cliente lógico) desconecta ou falha, e o slot nunca é removido. O servidor primário manterá todos os arquivos WAL que o slot está esperando.
- Solução: Monitore regularmente os slots de replicação e remova aqueles que não estão mais em uso.
-- Listar slots de replicação
SELECT slot_name,
plugin,
slot_type,
active,
restart_lsn,
wal_status,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal
FROM pg_replication_slots
ORDER BY pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) DESC NULLS LAST;
-- Remover um slot não utilizado
SELECT pg_drop_replication_slot('slot_name_to_drop');
Aviso: Remover um slot de replicação fará com que qualquer consumidor conectado perca sua posição. Certifique-se de que o consumidor não é mais necessário ou foi reinicializado adequadamente antes de remover.
3. Ajustando min_wal_size e max_wal_size
Esses parâmetros influenciam a frequência do checkpoint e quanto WAL o PostgreSQL tenta manter para reutilização. Eles não limitam o WAL retido para arquivamento ou replicação.
min_wal_size: incentiva o PostgreSQL a manter pelo menos essa quantidade de WAL para reutilização em vez de removê-lo imediatamente.max_wal_size: o volume de WAL que tende a acionar um checkpoint. Não é um máximo rígido quando o WAL é retido por outros motivos.
# postgresql.conf
min_wal_size = 1GB
max_wal_size = 4GB
Aumentar max_wal_size pode dar ao sistema mais margem durante picos de carga de gravação, mas também significa que mais espaço em disco será ocupado por arquivos WAL pré-alocados.
4. Limpeza Regular de Arquivos WAL Arquivados
O arquivamento WAL, embora essencial para a recuperação, também pode levar a problemas de espaço em disco se os arquivos arquivados nunca forem limpos. Você deve ter uma estratégia para gerenciar a retenção de seus arquivos WAL arquivados.
Estratégia: Implemente um script ou use uma ferramenta dedicada (como
pg_archivecleanup,pgBackRest,wal-g,barman) para remover arquivos WAL antigos do local de arquivamento quando não forem mais necessários para PITR ou replicação.Usando
pg_archivecleanup: Este utilitário pode ser executado no servidor primário para remover arquivos WAL antigos do diretório de arquivamento.pg_archivecleanup /caminho/para/local/de/arquivo 0000000100000037000000AFO segundo argumento é o nome do arquivo WAL mais antigo que ainda precisa ser mantido, não uma idade arbitrária. Na prática, ferramentas de backup como pgBackRest, Barman e WAL-G são mais seguras porque entendem a retenção de backup e o WAL necessário para recuperação.
Importante: Sempre certifique-se de que sua estratégia de limpeza esteja alinhada com seus requisitos de backup e recuperação Point-in-Time (PITR). Você precisa reter arquivos WAL por tempo suficiente para cobrir sua janela de recuperação desejada.
5. Monitorando Espaço em Disco e Taxa de Geração de WAL
O monitoramento proativo é fundamental para evitar a exaustão do espaço em disco.
Monitore o Espaço em Disco: Acompanhe o espaço livre no diretório de dados,
pg_wal, locais de arquivos temporários e destinos de arquivamento.Monitore a Geração de WAL: Use diferenças de LSN ao longo do tempo para estimar a taxa de geração.
SELECT now() AS sample_time, pg_current_wal_lsn() AS current_lsn;Armazene esse valor periodicamente e compare amostras com
pg_wal_lsn_diff(new_lsn, old_lsn). Para uma visão rápida do tamanho atual do diretóriopg_wal:SELECT pg_size_pretty(sum(size)) AS pg_wal_size FROM pg_ls_waldir();
Etapas de Solução de Problemas para Discos Cheios
Se o seu disco já está cheio devido à atividade de WAL, uma ação imediata é necessária:
- Identifique a Causa: Verifique
pg_stat_archiverpara falhas de arquivamento. Examinepg_replication_slotspara slots não utilizados ou problemáticos. Verifique o atraso de replicação nos standbys. - Libere Espaço Sem Danificar a Recuperação:
- Não delete arquivos de
pg_walmanualmente. - Se o destino do arquivamento estiver cheio, remova WAL arquivado antigo somente quando estiver fora da sua janela de retenção de backup.
- Se possível, adicione armazenamento ou mova o destino do arquivamento, então deixe o PostgreSQL arquivar e reciclar normalmente.
- Não delete arquivos de
- Aborde a Causa Raiz:
- Corrija o Arquivamento: Certifique-se de que
archive_commandestá correto e o destino tem espaço. - Gerencie Slots: Remova quaisquer slots de replicação não utilizados.
- Corrija a Replicação: Aborde problemas que causam atraso no standby.
- Aumente o Espaço em Disco: Adicione mais armazenamento temporária ou permanentemente.
- Corrija o Arquivamento: Certifique-se de que
- Empurre o Arquivador: Após corrigir o comando de arquivamento ou destino, o PostgreSQL deve tentar novamente. Um reload pode ser suficiente para mudanças de configuração; uma reinicialização completa deve ser o último recurso durante um incidente de disco.
Um Modelo Mental Mais Seguro
Quando pg_wal está crescendo, faça três perguntas em ordem:
- O PostgreSQL está gerando mais WAL do que o normal porque a carga de trabalho mudou?
- O PostgreSQL está incapaz de arquivar WAL?
- O PostgreSQL está sendo instruído a reter WAL para replicação ou um slot?
Essas respostas apontam para diferentes correções. Gravações em massa podem precisar de agendamento, loteamento ou ajuste de checkpoint. Falhas de arquivamento precisam de correções de armazenamento e comando. Retenção de slot precisa de recuperação do consumidor, limpeza do slot ou um limite de retenção. Adivinhar max_wal_size raramente resolve o problema real por si só.