Esse artigo faz parte da revista Clube Delphi Edição 83. Clique aqui para ler todos os artigos desta edição

>

Boa Idéia

Copiando registros de um banco de dados corrompido

 

Recentemente a empresa na qual sou consultor foi contratada pela prefeitura de uma grande capital para prestar treinamento e consultoria em Firebird. O principal trabalho que deveria ser realizado durante a consultoria era o de otimização do banco de dados da instituição.

Para ter uma idéia do tamanho do desafio, o banco tinha aproximadamente 120 milhões de registros armazenados em pouco mais de 30 tabelas, o que gera um arquivo com 19 GB. Como se o volume de informação já não fosse um desafio suficientemente grande, a análise do banco de dados mostrou que o mesmo estava corrompido.

Este artigo descreve o trabalho que foi realizado para que fosse possível copiar as informações do banco de dados corrompido. Antes disso, mostra rapidamente qual o ambiente encontrado e os principais passos que foram tomados antes da cópia dos dados.

 

Avaliação da estrutura

O primeiro passo a ser feito sempre que se deseja melhorar o desempenho de uma aplicação é avaliar o servidor (hardware) em que ela está rodando. Muitas vezes comprar um novo equipamento, ou melhorar o existente, não gera o ganho de desempenho esperado, fazendo com que o gasto não se justifique.

O servidor usado pelo cliente tinha dois processadores, 2 GB de memória RAM, discos rígidos de 10 mil RPMs e sistema operacional Windows 2000 Server. Ou seja, o equipamento era de alta qualidade e havia pouco o que melhorar.

 

Avaliação das configurações do banco de dados

A versão instalada do Firebird era a 1.5, rodando como SuperServer. Embora muitos ainda considerem a versão Classic a ideal, testes realizados demonstraram que a arquitetura SuperServer é bastante estável em servidores de alta qualidade. Esse caso é mais um exemplo.

Avaliamos também a forma de gravação dos dados. O banco de dados estava configurado para usar cache de gravação do tipo write throug (padrão de instalação do Firebird em plataforma Windows), onde cada operação de escrita é imediatamente passada para que o SO a processe. Em outras palavras, a opção Enable Forced Writes estava habilitada, fazendo com que o banco gravasse em disco instantaneamente toda atualização feita nos dados, tornando assim as operações de escrita mais lentas.

Outro ponto avaliado foi o tamanho do cache das páginas de dados e de índices. Constatou-se que o tamanho era de 120 MB, dada a quantidade de memória disponível e também o número de usuários conectados, avaliamos que o tamanho estava apropriado.

O penúltimo ponto analisado foi o tamanho das páginas de dados e de índices. Normalmente indicamos aos clientes páginas de dados com 8 Kb. Entretanto, devido ao tamanho do arquivo FDB, optamos por usar páginas de 16 Kb. A lógica é simples, com páginas maiores teremos menos fragmentos de registros divididos, uma melhor utilização dos índices e operações de I/O mais contínuas. Como a mudança no tamanho exige um backup e um restore, optou-se por fazer essa mudança no final.

Por último foram verificadas as estatísticas das tabelas e índices. Foi verificado que as tabelas mais importantes, aquelas que tinham mais de 20 milhões de registros, estavam fragmentadas, ou seja, não estavam gravadas de maneira sequencial no disco, fazendo com que sejam necessárias várias leituras no disco para obter a informação, causando lentidão.

Uma vez constatada que a mudança no tamanho das páginas de dados e índices e a desfragmentação poderiam melhorar significativamente o desempenho da aplicação, passou-se para a realização de um backup para um posterior restore. Aí começaram os problemas, pois o banco estava corrompido.

 

Banco de dados corrompido

Para um banco de dados de 19 GB e com mais de 120 milhões de registros, a situação encontrada foi considerada bastante tranquila:

·         Dois registros corrompidos, o que significa dizer que dois registros foram perdidos;

·         Duas páginas de dados corrompidas: significa dizer que vários registros foram perdidos, já que uma página de dados armazena n registros (o valor de n varia de tabela para tabela);

·          161 páginas de índices corrompidas: significa que, embora os dados estejam gravados corretamente no banco de dados, uma consulta pode não encontrar as informações caso a parte corrompida do índice esteja apontando justamente para elas (se o índice for usado na consulta, claro).

As análises realizadas revelaram que a corrupção se deu em apenas uma tabela, que armazenava cerca de 21 milhões de registros. Levando em conta a ocupação média dessa tabela (80%) e o número de registros que podem ser gravados numa página de dados dela (101), estimaram-se que poderiam ter sido perdidos aproximadamente 163 registros, o que poderia causar a não emissão de determinados relatórios, ou ainda pior, a emissão de relatórios com dados incompletos (errados).

Foram feitas diversas tentativas com softwares de terceiros para corrigir o banco de dados. Apesar da qualidade dos softwares utilizados, após horas de processamento infelizmente todos falharam. O que fazer nessa situação, uma vez que todos os recursos de correção haviam sido tentados sem sucesso?

 

Resolvendo o problema

A solução encontrada para resolver o problema foi criar um novo banco de dados e migrar os dados (registro a registro) do banco atual para o novo banco, com estrutura idêntica, porém intacto.

A idéia é relativamente simples, desenvolver um programa que, primeiramente, extraia as informações do banco e grave as mesmas em arquivos textos. Posteriormente, após a cópia de todos os registros, transferir os dados armazenados nos arquivos para a nova base de dados.

Após a conclusão do processo de cópia, comparar os dois bancos de dados a fim de verificar se existe correspondência entre o número de registros de cada uma das tabelas (o fluxo do sistema pode ser visto na Figura 1). Tudo muito fácil, se não fosse o enorme volume de informações.

 

Figura 1. Fluxo geral do processo de migração

 

Estimou-se, através de testes de I/O no servidor, que o tempo necessário para a realização de todo o processo era de aproximadamente 70 horas. Devido ao tempo demasiadamente longo, o uso de arquivos textos intermediários foi necessário para evitar que o processo tivesse que ser recomeçado do zero caso alguma falha, como falta de energia, ocorresse durante o processo de extração ou de cópia dos dados.

 

...

Quer ler esse conteúdo completo? Tenha acesso completo