Blog

Como recuperar um banco de dados PostgreSQL corrompido?

Caio
23 min de leitura
CTA – Topo

Quando o PostgreSQL começa a recusar consultas, travar a inicialização ou registrar erros em páginas específicas, a dúvida que aparece é sempre a mesma: dá para recuperar banco de dados PostgreSQL corrompido sem perder o que ainda está íntegro? A resposta depende do tipo de falha, do estado do storage e das decisões tomadas nas primeiras horas. Este guia mostra como diagnosticar o problema, conter o ambiente, avaliar o que é recuperável e definir quando vale seguir sozinho ou buscar apoio especializado.

O que significa um banco PostgreSQL corrompido

Um banco de dados PostgreSQL corrompido é aquele em que estruturas internas deixaram de ser lidas ou interpretadas corretamente pelo motor do sistema. Isso pode afetar desde uma única página de 8 KB até o catálogo do sistema, impedindo a inicialização da instância. A corrupção não é um evento binário: ela pode ser silenciosa por semanas e só se manifestar quando uma consulta específica acessa o bloco defeituoso.

Diferente de uma simples perda de conexão ou de uma consulta lenta, a corrupção altera o conteúdo binário dos arquivos que compõem o banco. O PostgreSQL não possui um mecanismo automático de autorreparo para páginas danificadas — quando o checksum falha, o servidor interrompe a operação em vez de tentar corrigir o dado, justamente para evitar a propagação de inconsistências.

Corrupção física x corrupção lógica

Corrupção física ocorre quando o meio de armazenamento não devolve os bytes que foram gravados: setores defeituosos no disco, falha de controladora, degradação de mídia SSD ou problemas em cache de storage. Nesses casos, o arquivo do banco existe, mas parte do seu conteúdo é ilegível no nível do hardware. O PostgreSQL registra erros de leitura de bloco, e o sistema de arquivos pode reportar falhas de I/O.

Corrupção lógica acontece quando o hardware devolve os dados, mas eles não fazem sentido para o PostgreSQL: uma página com checksum inválido, um registro de WAL truncado ou uma tabela com ponteiros quebrados. A causa pode ser um bug de aplicação, uma gravação parcial durante queda de energia ou uma operação administrativa mal executada. A distinção importa porque corrupção lógica pode ser contornada com ferramentas do próprio PostgreSQL, enquanto corrupção física exige intervenção no storage antes de qualquer tentativa de recuperação lógica.

Como o PostgreSQL grava dados: páginas, heap e WAL

O PostgreSQL organiza os dados em arquivos segmentados de até 1 GB, divididos internamente em páginas de 8 KB. Cada tabela e índice ocupa um ou mais desses arquivos, chamados de heap. Quando uma linha é atualizada, a versão antiga permanece no heap até que o processo de vacuum a remova, o que significa que um banco pode conter múltiplas versões físicas do mesmo registro.

Antes de alterar qualquer página do heap, o PostgreSQL grava a intenção da mudança no WAL (Write-Ahead Log), um registro sequencial de todas as operações. Esse mecanismo permite reconstruir o estado do banco após uma queda, desde que os arquivos WAL estejam íntegros. A corrupção do WAL é particularmente grave porque compromete a capacidade de recuperação point-in-time e pode invalidar backups baseados em replicação contínua.

Sinais e mensagens de erro que indicam corrupção

Os sintomas de corrupção no PostgreSQL raramente são genéricos. O servidor costuma emitir mensagens específicas no log, apontando o arquivo, a página e o tipo de falha. Reconhecer esses sinais cedo reduz o risco de agravar o problema com tentativas repetidas de reinicialização ou de reconstrução de índices.

  • Mensagens de invalid page header ou invalid checksum no log
  • Erros de leitura em arquivos específicos do diretório de dados
  • Falha de inicialização com PANIC ou FATAL logo após o start
  • Consultas que retornam erro apenas para determinadas tabelas ou faixas de registros
  • Processos de autovacuum ou análise que abortam repetidamente

Erros de leitura de página e checksum inválido

Quando a verificação de checksum está habilitada na inicialização do cluster, o PostgreSQL calcula um valor de integridade para cada página gravada. Ao ler a página de volta, recalcula esse valor e compara com o original. Uma divergência indica que os dados foram alterados após a gravação — seja por falha de disco, seja por escrita parcial.

O erro típico aparece no log como invalid page in block seguido do número do arquivo e do bloco. Esse nível de detalhe permite identificar exatamente qual tabela ou índice está afetado, consultando o catálogo pg_class para mapear o arquivo ao objeto. Sem checksum habilitado, a corrupção pode passar despercebida até que uma consulta retorne dados visivelmente errados ou o servidor falhe ao interpretar um cabeçalho de página.

Falhas ao iniciar o servidor e ao acessar tabelas específicas

A falha de inicialização indica que a corrupção atingiu estruturas críticas: catálogos do sistema, arquivos de controle ou o WAL necessário para a recuperação automática. O PostgreSQL tenta aplicar o WAL pendente durante o start; se encontrar um registro ilegível, interrompe o processo e permanece fora do ar. Reiniciar em loop não resolve e pode sobrescrever arquivos que ainda seriam recuperáveis.

Quando o banco inicia, mas uma tabela específica falha, a corrupção está localizada no heap ou no índice daquele objeto. O sintoma clássico é a consulta funcionar para parte dos registros e falhar ao varrer uma determinada faixa de páginas. Nesse cenário, o restante do banco pode estar íntegro, e a recuperação seletiva se torna viável.

Causas mais comuns de corrupção no PostgreSQL

A corrupção raramente tem uma única causa isolada. Em geral, é a combinação de um evento externo com uma configuração ou prática que amplificou o dano. Entender o mecanismo ajuda a decidir se a recuperação pode ser feita no ambiente atual ou se exige mover o storage para um laboratório.

Queda de energia e desligamento abrupto do servidor

Uma queda de energia interrompe gravações no meio do caminho. O WAL existe justamente para lidar com isso, mas a proteção só funciona se o parâmetro fsync estiver ativo e se o sistema de arquivos honrar a chamada de sincronização. Em ambientes com cache de escrita desprotegido — como alguns storages e virtualizadores mal configurados — o PostgreSQL pode acreditar que gravou no disco quando o dado ainda estava em memória volátil.

O risco aumenta quando o desligamento ocorre durante um checkpoint ou uma operação de vacuum. Nesses momentos, o servidor está reescrevendo páginas do heap em lote; uma interrupção pode deixar blocos parcialmente gravados. Se o hardware de storage não tiver bateria ou capacitor de proteção de cache, a janela de corrupção se amplia consideravelmente.

Falhas de disco, storage e sistema de arquivos

Setores defeituosos em HDs mecânicos são uma causa clássica de erro de leitura no PostgreSQL. Em SSDs, a degradação das células NAND pode corromper dados silenciosamente, especialmente em unidades sem proteção contra perda de energia. Em storages corporativos e RAID, uma controladora com defeito ou um rebuild malfeito pode gravar dados inconsistentes em múltiplos discos ao mesmo tempo.

O sistema de arquivos também participa do problema. Sistemas como ext4, XFS, Btrfs e ReFS têm comportamentos diferentes diante de falhas; alguns priorizam performance e adiam a escrita de metadados, o que conflita com a expectativa de durabilidade do PostgreSQL. Problemas de filesystem em NAS podem inclusive colocar o volume em modo somente leitura, como ocorre em falhas de volume de NAS, agravando o cenário para bancos hospedados nesses equipamentos.

Erros de administração e configuração inadequada

Desligar o parâmetro fsync em busca de performance é uma das decisões administrativas mais perigosas para um banco PostgreSQL. Sem fsync, o servidor reporta commit antes de garantir a gravação física, e qualquer queda de energia pode corromper páginas e o próprio WAL. A recomendação de documentação é clara: fsync desativado só é aceitável em ambientes descartáveis, onde a perda total é tolerável.

Outras práticas de risco incluem executar o PostgreSQL sobre sistemas de arquivos com cache agressivo sem as opções de montagem corretas, manipular manualmente arquivos do diretório de dados com o servidor ativo e restaurar backups sobre instâncias em execução. Em ambientes virtualizados, snapshots tirados sem quiescência do banco equivalem a um desligamento abrupto e podem corromper o estado interno do cluster.

Antes de tudo: contenção e preservação do ambiente

A primeira decisão após identificar corrupção define o desfecho do caso. Tentativas apressadas de “consertar” — reiniciar o servidor repetidamente, rodar REINDEX ou VACUUM FULL, restaurar por cima do banco atual — frequentemente transformam uma corrupção localizada em perda definitiva. A contenção vem antes do diagnóstico.

Por que parar o servidor e não reiniciar em loop

Manter o PostgreSQL em execução com corrupção ativa permite que processos de background continuem gravando: autovacuum, checkpoints e replicação seguem alterando o heap. Cada gravação adicional pode sobrescrever páginas que ainda continham dados recuperáveis. O primeiro passo técnico é interromper o serviço de forma controlada, preferencialmente com pg_ctl stop em modo fast ou immediate, dependendo do estado do servidor.

Reiniciar em loop é contraproducente por outro motivo: a cada start, o PostgreSQL tenta aplicar WAL pendente. Se o WAL contém registros corrompidos, a tentativa de recuperação automática pode falhar no meio e deixar o cluster em estado inconsistente. Quanto mais reinicializações, maior a chance de corromper também o mecanismo de recuperação que poderia ter sido usado com segurança.

Como preservar o diretório de dados e os arquivos WAL

Antes de qualquer intervenção, o diretório de dados do PostgreSQL deve ser copiado integralmente, byte a byte. A cópia precisa incluir não apenas o diretório base, mas também pg_wal, pg_xact, pg_control e os arquivos de configuração. Uma cópia em nível de sistema de arquivos, com o servidor parado, preserva o estado exato para diagnóstico posterior.

  • Copiar o cluster inteiro com ferramenta que preserve permissões e timestamps
  • Incluir o diretório pg_wal — sem ele, não há recuperação point-in-time
  • Gerar hash dos arquivos críticos para detectar alterações posteriores
  • Não montar o volume original em modo leitura-escrita para “testar”
  • Separar a cópia em mídia diferente do storage original

Em casos de suspeita de falha física no disco, a cópia em nível de sistema de arquivos pode não ser possível ou pode agravar o desgaste da mídia. Nesse cenário, a preservação exige imagem do dispositivo em hardware apropriado, antes de qualquer leitura intensiva. A ordem correta é: estabilizar o storage, gerar imagem, e só então trabalhar sobre a cópia.

Diagnóstico passo a passo do banco corrompido

O diagnóstico segue uma sequência que vai do geral ao específico: primeiro confirma-se a integridade estrutural do cluster, depois identifica-se quais objetos estão afetados e, por fim, rastreia-se a causa raiz nos logs. Pular etapas leva a diagnósticos errados e intervenções no objeto errado.

Verificando a integridade com ferramentas nativas

O PostgreSQL oferece ferramentas de verificação que não alteram dados: pg_controldata lê o arquivo de controle e informa o estado do cluster, incluindo se o último desligamento foi limpo ou se há recuperação pendente. pg_resetwal não é ferramenta de diagnóstico — é de intervenção destrutiva e só deve ser usada como último recurso, nunca como primeiro passo.

Para verificar checksums de páginas, a extensão pg_checksums permite habilitar ou validar checksums com o servidor parado. O comando de verificação varre todos os arquivos do cluster e reporta páginas com checksum inválido, informando o arquivo e o bloco exato. Essa varredura é somente leitura e pode ser executada sobre a cópia preservada, sem risco para o original.

Identificando quais tabelas, índices ou páginas estão afetados

Com o número do arquivo e do bloco em mãos, a consulta ao catálogo pg_class mapeia o arquivo ao objeto correspondente: tabela, índice, sequência ou visão materializada. O relname e o relfilenode permitem localizar exatamente qual relação está corrompida. Em clusters onde o catálogo também está danificado, o mapeamento precisa ser feito manualmente, lendo os cabeçalhos dos arquivos.

Quando o banco inicia parcialmente, a extensão pg_statistic e consultas diretas às tabelas suspeitas ajudam a delimitar a extensão do dano. Uma tabela pode ter apenas uma página corrompida entre centenas; nesse caso, a perda é mínima e a recuperação seletiva é viável. O diagnóstico preciso evita tratar o banco inteiro como perdido quando apenas um índice secundário está danificado.

CTA – Meio

Lendo os logs do PostgreSQL para localizar a origem

Os logs do servidor registram a sequência de eventos que precedeu a corrupção: erros de I/O, falhas de checkpoint, mensagens de PANIC e alertas de checksum. A leitura cronológica desses registros frequentemente revela se a causa foi um desligamento abrupto, uma falha de disco ou uma operação administrativa específica.

O log também mostra se o problema é recorrente. Múltiplos erros de leitura no mesmo arquivo ao longo de dias indicam falha progressiva de hardware, não um evento isolado. Essa distinção é decisiva: corrupção por evento único pode ser resolvida com recuperação lógica; corrupção por hardware em degradação exige substituir o storage antes de qualquer tentativa de restauração, sob pena de perder também o backup.

Recuperação com backup: o caminho mais seguro

Backup íntegro é o ativo mais valioso em qualquer cenário de corrupção. A recuperação a partir de backup elimina a necessidade de manipular páginas danificadas e devolve o banco a um estado conhecido. A segurança do processo depende de o backup ter sido testado antes — backup que nunca foi restaurado é apenas uma esperança.

Restauração completa e recuperação point-in-time com WAL

A restauração completa parte de um backup físico do cluster, gerado com pg_basebackup ou ferramenta equivalente. Sobre esse backup, o PostgreSQL aplica os arquivos WAL arquivados para avançar até o ponto desejado. A recuperação point-in-time (PITR) permite parar a aplicação do WAL em um instante anterior à corrupção, recuperando transações que ocorreram após o backup sem trazer de volta o dano.

O procedimento exige configurar restore_command para buscar os WAL arquivados e definir recovery_target_time ou recovery_target_xid para o ponto exato. Se o WAL arquivado estiver íntegro, a recuperação é precisa ao nível da transação. A qualidade do resultado depende diretamente da política de arquivamento de WAL que estava ativa antes do incidente.

O que fazer quando o backup também está corrompido ou incompleto

Backup corrompido é um cenário mais comum do que se imagina: fitas ilegíveis, snapshots inconsistentes, replicação que propagou o dano antes de ser detectado. Quando o backup físico falha, ainda é possível recorrer a dumps lógicos antigos, se existirem, ou a réplicas que tenham sido desconectadas antes da corrupção.

A verificação do backup deve ocorrer antes de qualquer tentativa de restauração sobre o ambiente original. Restaurar um backup defeituoso por cima do cluster atual destrói a última cópia do estado corrompido — que, paradoxalmente, pode conter mais dados recuperáveis que o backup. Em casos de storage com falha, a restauração deve ser feita em hardware novo, nunca no mesmo disco degradado.

Recuperação sem backup: o que é possível fazer

Sem backup, a recuperação depende de extrair o máximo de dados íntegros do cluster corrompido. O objetivo deixa de ser restaurar o estado anterior e passa a ser salvar o que ainda é legível. As técnicas disponíveis variam conforme a extensão e a localização do dano.

Isolando e ignorando páginas corrompidas para voltar a subir o banco

O PostgreSQL não oferece uma opção nativa para pular páginas corrompidas durante a leitura. Em alguns casos, é possível usar o parâmetro zero_damaged_pages para substituir páginas ilegíveis por páginas zeradas, permitindo que o servidor inicie e que consultas às demais tabelas funcionem. Os dados da página zerada são perdidos, mas o restante do banco volta a ser acessível.

Essa técnica é destrutiva e deve ser aplicada apenas sobre a cópia preservada, nunca sobre o original. Além disso, zerar páginas do catálogo do sistema pode tornar o banco inutilizável; o recurso é mais seguro quando a corrupção está limitada a tabelas de dados. Cada página zerada representa perda definitiva de até 8 KB de dados — o custo precisa ser avaliado contra o benefício de acessar o restante.

Extraindo dados com pg_dump, COPY e exportação de tabelas

Com o banco no ar, ainda que parcialmente, o pg_dump é a ferramenta de extração mais eficiente. Ele pode ser direcionado a tabelas específicas com a opção -t, ignorando objetos corrompidos e exportando apenas o que está íntegro.

A estratégia de extração seletiva exige mapear previamente quais páginas estão corrompidas e quais registros residem nelas. Consultas com ctid — o identificador físico da linha — permitem delimitar a extração em torno do bloco danificado. Em tabelas grandes com corrupção pontual, essa abordagem recupera a quase totalidade dos dados, perdendo apenas as linhas fisicamente localizadas nas páginas ilegíveis.

Reconstruindo índices e validando a consistência após a extração

Índices corrompidos não significam perda de dados: eles podem ser descartados e reconstruídos a partir do heap. O comando REINDEX recria o índice do zero, desde que a tabela subjacente esteja íntegra. Em muitos casos de corrupção aparente, o problema está apenas no índice, e a reconstrução resolve sem perda de registros.

Após a extração e reconstrução, a consistência precisa ser validada. Comparar contagens de linhas, somas de verificação de colunas críticas e amostras de registros entre o banco recuperado e qualquer fonte alternativa disponível ajuda a confirmar que os dados extraídos fazem sentido. A validação é etapa obrigatória antes de colocar o banco recuperado em produção.

Quando a corrupção é física e exige recuperação de storage

Se a causa da corrupção está no disco, no controlador ou no sistema de armazenamento, nenhuma ferramenta do PostgreSQL resolverá o problema de forma duradoura. A recuperação lógica sobre storage defeituoso é como enxugar gelo: cada leitura adicional pode degradar ainda mais a mídia e reduzir o que ainda é recuperável.

Como diferenciar falha lógica de falha no disco ou no storage

Falhas lógicas tendem a ser estáveis: o erro se repete sempre no mesmo bloco, e o restante do banco funciona normalmente. Falhas físicas são progressivas e erráticas: o disco reporta erros de I/O em arquivos diferentes a cada leitura, o sistema de arquivos apresenta mensagens de setor defeituoso e o SMART do disco indica crescimento de setores realocados ou pendentes.

  • Erros de I/O variados e crescentes indicam problema físico
  • Corrupção estável e localizada sugere causa lógica
  • Ruídos mecânicos em HDs apontam falha de hardware imediata
  • Alertas de SMART com setores pendentes exigem ação antes de piorar
  • Quedas de desempenho repentinas e timeouts de leitura acompanham falha física

Em storages corporativos e RAID, a falha pode estar na controladora, no backplane ou em múltiplos discos simultaneamente. O sintoma no PostgreSQL é apenas a ponta visível de um problema mais profundo. Tentar recuperar o banco sem tratar o storage é perder tempo e, principalmente, arriscar a integridade dos dados que ainda existem.

Ambientes virtualizados, RAID e replicação: cuidados específicos

Em ambientes virtualizados, o PostgreSQL roda sobre camadas que nem sempre garantem a durabilidade esperada. Snapshots de hypervisor tirados sem quiescência, discos virtuais com cache de escrita habilitado e storage compartilhado com overcommit são fontes conhecidas de corrupção. A recuperação nesses casos exige avaliar também a integridade do disco virtual e do datastore subjacente.

Em RAID, um rebuild mal sucedido pode gravar dados inconsistentes em todos os discos do array, corrompendo o banco de forma distribuída. A ordem correta é estabilizar o RAID antes de tocar no PostgreSQL — e, se houver discos fora do array, preservá-los individualmente. Em replicação, o risco é a corrupção ter sido propagada para o standby antes de ser detectada; réplicas com atraso controlado podem servir como ponto de recuperação, desde que desconectadas a tempo. Cenários de RAID com disco caindo ilustram como a degradação progressiva pode evoluir para perda total se não houver intervenção precoce.

Como evitar que a corrupção volte a acontecer

A prevenção de corrupção no PostgreSQL combina configuração correta de durabilidade, rotina de backup testado e monitoramento ativo. São três pilares independentes: a falha de um deles não é compensada pelos outros dois.

Configuração de WAL, fsync e parâmetros de durabilidade

O parâmetro fsync deve permanecer ativo em qualquer ambiente que não seja descartável. Complementarmente, synchronous_commit define o nível de garantia de durabilidade por transação; valores como remote_apply em replicação síncrona garantem que o standby também gravou antes do commit ser reportado. O full_page_writes deve ficar ativo para proteger contra escritas parciais de página.

O wal_level precisa ser suficiente para a estratégia de backup adotada: replica para backups físicos e logical para replicação lógica. O arquivamento de WAL com archive_command é o que habilita a recuperação point-in-time; sem arquivamento, o backup físico só restaura até o instante do backup, e tudo o que veio depois se perde.

Rotina de backup, verificação e testes de restauração

Backup sem teste de restauração é um risco não gerenciado. A rotina mínima inclui backup físico periódico com pg_basebackup, arquivamento contínuo de WAL e um teste mensal de restauração em ambiente separado. O teste valida não apenas o backup, mas também o procedimento: tempo de restauração, integridade dos WAL arquivados e funcionalidade do restore_command.

  1. Backup físico completo em intervalo compatível com o RPO aceitável
  2. Arquivamento contínuo de WAL para permitir PITR
  3. Dump lógico periódico como camada adicional de segurança
  4. Teste de restauração mensal em ambiente isolado
  5. Validação de checksum do backup após a geração

A retenção de backups precisa considerar o tempo de detecção de corrupção. Se uma corrupção silenciosa levou 30 dias para ser notada, backups de apenas 7 dias já nasceram corrompidos. A janela de retenção deve ser maior que o pior cenário de detecção tardia.

Monitoramento de integridade e proteção do servidor

O monitoramento ativo detecta sinais precoces de corrupção antes que ela se torne crítica. Verificações periódicas com pg_checksums em modo validação, monitoramento de SMART nos discos e alertas para erros de I/O no log do PostgreSQL compõem a linha de defesa. A detecção precoce permite acionar o backup antes que a corrupção se espalhe.

A proteção do servidor inclui no-break com desligamento automático controlado, storage com proteção de cache contra perda de energia e configuração correta de montagem do sistema de arquivos. Em ambientes críticos, a replicação com atraso controlado funciona como seguro adicional: se a corrupção for detectada antes de alcançar a réplica atrasada, a recuperação é imediata.

O que define o custo de uma recuperação de banco de dados

O custo de uma recuperação de PostgreSQL corrompido não é tabelado: ele depende da complexidade técnica do caso, da urgência e da estrutura necessária para executar o trabalho com segurança. Compreender esses fatores ajuda a avaliar propostas e a distinguir serviço técnico sério de promessa vazia.

Fatores que influenciam o esforço e o prazo do serviço

O primeiro fator é a natureza da corrupção: lógica ou física. Corrupção lógica localizada pode ser resolvida em horas com ferramentas nativas; corrupção física exige recuperação de storage em ambiente controlado, com imagem do dispositivo e possível troca de componentes. O segundo fator é a existência e a qualidade do backup — um backup íntegro reduz drasticamente o esforço, enquanto a ausência total impõe extração seletiva página a página.

  • Extensão da corrupção: uma página ou o catálogo inteiro
  • Existência, idade e integridade de backups e WAL arquivados
  • Necessidade de recuperação física do storage antes da lógica
  • Complexidade do ambiente: virtualização, RAID, replicação
  • Urgência de retomada e janela de indisponibilidade tolerável

O prazo também varia conforme o volume de dados e a necessidade de validação. Bancos de centenas de gigabytes exigem varreduras longas e múltiplas passadas de verificação. A validação de consistência após a extração — comparando contagens, somas e amostras — adiciona tempo, mas é o que separa uma recuperação confiável de uma entrega precipitada.

Como escolher um laboratório ou especialista em PostgreSQL

A escolha de um especialista deve se basear em critérios técnicos verificáveis, não em promessas de sucesso garantido. Nenhum profissional sério promete 100% de recuperação; o resultado depende do diagnóstico do caso concreto. Desconfie de quem oferece garantia absoluta sem examinar o ambiente.

Pergunte sobre o procedimento de preservação: o especialista faz imagem do storage antes de qualquer intervenção? Trabalha sobre cópia ou sobre o original? Tem estrutura para lidar com falha física, ou apenas com corrupção lógica? Em casos que envolvem storage corporativo, a experiência com recuperação de storage corporativo é um diferencial relevante, assim como familiaridade com os sistemas de arquivos e controladoras envolvidos. A transparência sobre o que é possível e o que não é — antes de iniciar o serviço — é o melhor indicador de competência técnica.

CTA – Final