"Não é possível confirmar o índice" ou como extrair dados de um banco de dados parcialmente restaurado (inconsistente)
Alexey Kovyazin, última atualização 30-março-2014
Após corrigir corrupções, é comum ver o erro “Cannot commit index” na etapa de restauração. No Firebird 2.0 e versões posteriores, isso aparece como um aviso e o banco de dados não será colocado on-line; no Firebird 1.0-1.5 e no InterBase, isso ocorre como um erro muito desagradável que interrompe o processo de restauração (é impressionante ver esse erro no final da restauração de um banco de dados de 200 GB).
A razão do erro “Cannot commit index..” é óbvia: a corrupção afeta a integridade referencial do banco de dados, e os registros desaparecem de maneira mágica (do ponto de vista do servidor).
Por exemplo, você tem uma tabela “Customers” e uma tabela associada “Orders” referenciada por chave estrangeira. Sem corrupção, não é possível violar a chave estrangeira e excluir um registro de Customers sem antes excluir todos os pedidos que referenciam determinado cliente. A corrupção afeta o arquivo do banco de dados em nível baixo e elimina registros diretamente. Que surpresa desagradável para o servidor ver links não resolvidos para registros mestres a partir de registros de chave estrangeira.
Aqui preciso adicionar uma dica sobre o processo de restauração: o mecanismo restaura todas as tabelas com índices não ativados (isso torna o preenchimento das tabelas com registros muito mais rápido) e, em seguida, começa a ativar (ou seja, construir) os índices um por um. Isso significa que todos os dados já estão no banco de dados quando o processo de restauração inicia a etapa de criação de índices e você vê o erro “Cannot commit index..”.
Bem, o primeiro desejo quando você vê o erro “Cannot commit index” é remover a restrição de chave estrangeira apropriada para permitir que a restauração termine. A questão é o que faremos com o banco de dados inconsistente, mas restaurado com sucesso: a chave estrangeira removida pode ser uma parte importante da lógica de negócios.
Existem 2 abordagens aqui: recriar os dados ausentes ou descartar os dados inconsistentes. Vamos ver o que isso significa no exemplo Customers-Orders acima.
Recriação de dados ausentes
Então, você decidiu que precisa recriar os Customers ausentes para os Orders inconsistentes. Dessa forma, você precisa determinar os IDs perdidos. Normalmente, uso uma consulta SQL como esta (acho que será fácil adaptá-la ao seu caso):
SELECT O.Customer_ID FROM ORDERS O WHERE NOT EXISTS ( SELECT C.Customer_ID FROM CUSTOMERS C WHERE O.Customer_ID=C.Customer_ID)
Depois disso, você pode inserir manualmente os registros com a lista de chaves primárias ausentes e executar backup/restauração novamente.
Transferência de dados consistentes
Se você acha aceitável perder registros inconsistentes, pode transferir todos os dados do banco de dados parcialmente restaurado para um banco de dados vazio e simplesmente ignorar os registros inconsistentes, usando a seguinte abordagem:
-
Baixe a ferramenta gratuita IBDataPump http://www.clevercomponents.com/demo/datapump/IBPump.zip
-
Crie apenas o banco de dados de metadados a partir do backup do banco de dados reparado (após o IBFirstAID) usando o comando
gbak -c -m -user SYSDBA -pass masterkey Disk:\Path\backup.fbk Disk:\Path\fresh.fdb
-
Execute o IBDataPump e defina o banco de dados parcialmente reparado como Origem e o novo banco de dados vazio como Destino
-
Clique nas próximas abas, clique nos botões apropriados e na 3ª aba clique em “Pump”. Aguarde a conclusão (pode ser um processo longo; para ter uma ideia, você pode verificar a dinâmica de crescimento do tamanho do banco de dados de destino).
-
Como resultado, você terá o banco de dados fresh.fdb com relacionamentos de chaves estrangeiras consistentes - está totalmente ok.
Se o banco de dados tiver um ciclo nas chaves estrangeiras, o IBDataPump avisará e fornecerá uma lista dessas restrições - uma ou mais delas devem ser removidas antes que a transferência esteja disponível.
É claro que houve casos em que a transferência exigiu uma abordagem especial, e se você enfrentar tal situação, entre em contato com nosso suporte.