database file appears corrupt / page ... is of wrong type
As duas mensagens costumam vir juntas: database file appears corrupt (...), depois wrong page type e page 1234 is of wrong type (expected 5, found 0).
O que significa
Um banco Firebird é um arquivo de páginas de tamanho fixo, cada uma com o seu tipo no primeiro byte: dados, índice, ponteiros, blob, inventário de transações e assim por diante. O motor seguiu uma referência para a página 1234 esperando um tipo e encontrou outro. found 0 significa que a página está zerada — típico depois de uma queda de energia, de um disco com defeito, de um reparo do sistema de arquivos ou de uma cópia que deu errado. Outro número geralmente indica que a página contém o conteúdo de uma página diferente.
Quais dados se perdem depende de qual página é:
| Tipo de página (esperado) | O que se perde |
|---|---|
| 5, dados | as linhas dessa página |
| 4, ponteiros | para o motor, as páginas de dados da tabela listadas ali; as próprias páginas estão intactas |
| 7, índice | nada: índices são reconstruídos a partir dos dados |
| 8, blob | os valores BLOB guardados nessa página |
| 3, inventário de transações | veja cannot find tip page |
Primeiro: faça uma cópia e trabalhe só na cópia
Pare o servidor Firebird ou, no mínimo, garanta que nada esteja conectado ao banco. Depois copie o arquivo, junto com o arquivo .delta ao lado dele, se houver (um bloqueio do nbackup), e os arquivos secundários de um banco multiarquivo. Uma cópia feita enquanto o servidor grava no arquivo fica inconsistente, e toda tentativa de reparo altera o arquivo em que é executada. Se o próprio disco está falhando, copie o arquivo para outro disco antes de qualquer coisa.
Depois: tente as ferramentas do próprio Firebird
Elas vêm com toda instalação do Firebird e muitas vezes recuperam o banco inteiro: índices, triggers, usuários e tudo mais. Na cópia:
gfix -v -full -n copia.fdb # valida, só relata
gfix -mend -full -ignore copia.fdb # faz o gbak pular registros danificados
gbak -b -v -ig -g copia.fdb copia.fbk # backup: sem checksums, sem coleta de lixo
gbak -c -v copia.fbk restaurado.fdb # restaura em um banco novo
Acrescente -user SYSDBA -password ... conforme o seu servidor exigir. Se o gbak -b terminar, o banco restaurado é o resultado: confira a quantidade de linhas das tabelas importantes. O gfix -mend descarta os registros que não consegue ler, então compare com o original antes de confiar na cópia restaurada.
Se o gbak ainda falhar: extraia os dados com o fbrescue
O fbrescue é uma ferramenta gratuita e de código aberto (licença MIT) para bancos Firebird 2.5–5.0. Ele lê o arquivo do banco diretamente, sem o motor do Firebird, e exporta todas as linhas que consegue ler. Não para no primeiro registro ou página danificada e nunca grava no arquivo. Baixe o executável para o seu sistema em Releases: Windows, Linux, macOS; não precisa instalar nada.
fbrescue scan copia.fdb # o que está danificado, por tabela
fbrescue export copia.fdb --out resgate --format sql # schema.sql + INSERTs por tabela
Também existem --format csv e --format jsonl. As linhas que não puderam ser lidas ficam listadas em resgate/_errors.jsonl, com a página e o motivo, e o código de saída é 2 quando algo ficou de fora. Para carregar o resultado em um banco novo:
isql -ch UTF8 -i resgate/schema.sql novo.fdb
isql -ch UTF8 -i resgate/CLIENTES.sql novo.fdb # e assim por diante, para cada tabela
Se o texto sair ilegível, o banco provavelmente guarda texto em CHARACTER SET NONE: informe a codificação real, em geral --charset WIN1252 ou --charset ISO8859_1 em programas brasileiros.
Se quiser ajuda, abra uma issue e anexe a saída de fbrescue report copia.fdb: ela descreve o dano sem nenhum dos seus dados, e com os nomes de tabelas e colunas trocados por números. Pode escrever em português.
O fbrescue scan lista todas as páginas que não são o que deveriam ser e, por tabela, quantas páginas de dados e registros ele consegue alcançar. Na exportação:
- páginas de dados que as páginas de ponteiros da tabela já não listam são encontradas lendo o arquivo inteiro (cada página de dados registra a sua tabela e a sua posição nela);
- uma página encontrada no lugar de outra é lida de onde está (a partir do Firebird 3 cada página guarda o próprio número);
- páginas de índice danificadas não importam: a exportação lê só os dados.
Veja também
I/O error during "read" operation— o arquivo termina antes da horacannot find tip page (165)- Todos os erros