Restaurar um banco de dados nem sempre é uma tarefa simples. Como existem várias opções disponíveis para se implementar um plano de backup, a restauração de uma banco de dados pode se tornar uma tarefa que nem sempre é fácil, ainda mais se o DBA não conhecer os detalhes do banco, caso que relato neste artigo.
Vou descrever uma situação quando recebi a tarefa de recriar um banco de dados a partir de um CD cujo conteúdo me era desconhecido. Inicialmente foi necessário coletar algumas informações antes de iniciar o processo de restauração e recriação do banco de dados. Após a obtenção destas informações foi possível recriar a base de dados em um outro servidor SQL Server 2000 e torná-las disponível para os usuários.
Recebendo o backup
Para recriar o banco de dados recebi um CD contendo um arquivo com o nome RJ_RELAT_ 02-10-2005.ZIP com 568MB e mais nenhuma informação adicional. Não sabia se dentro deste arquivo ZIP existia um backup do banco de dados ou mesmo arquivos que haviam sido desatachados do servidor de origem. Não sabia sequer se o arquivo tinha sido gerado a partir de alguma outra versão do SQL Server ou de outro servidor de banco de dados.
Descompactei o conteúdo do arquivo ZIP na pasta C:\RJ_RELAT_02-10-2005 e um arquivo de mesmo nome e extensão BAK, com aproximadamente 6GB, foi extraído. Neste ponto comecei a desconfiar que tinha em minhas mãos um arquivo contendo um backup de um banco do SQL Server. Descartei a possibilidade de ser um arquivo de dados ou de transaction log do SQL Server, pois geralmente estes arquivos possuem a extensão MDF e LDF, respectivamente.
Com o arquivo descompactado, resolvi fazer algumas verificações para checar se o arquivo era mesmo um backup de um banco de dados e como poderia restaurá-lo e recriar o banco de dados.
Verificando o backup
A primeira verificação que fiz foi através do uso da instrução RESTORE VERIFYONLY. Conectei-me ao SQL Server que estava sendo executado localmente na minha estação de trabalho, configurei o banco de dados Master para a conexão e enviei a instrução apresentada na Listagem 1 para checar se o arquivo era um backup do SQL Server. O comando RESTORE VERIFYONLY, além de verificar se o arquivo é um backup do SQL Server, ainda checa a consistência deste backup.
/* INFORMAÇÕES SOBRE A CONSISTÊNCIA DO ARQUIVO */
RESTORE VERIFYONLY
FROM DISK = 'C:\RJ_RELAT_02-10-2005\RJ_RELAT_02-10-2005.BAK'
Listagem 1: Verificando a consistência do arquivo
Ao executar a instrução da Listagem 1 pude verificar que uma grande quantidade de informações estava sendo lida do disco rígido da minha estação de trabalho. Isto faz sentido, pois o arquivo ocupava aproximadamente 6GB. O SQL Server precisou fazer uma leitura e verificação dos bytes armazenados. Um fato curioso é que não houve um gasto excessivo de memória e nem de processamento durante a leitura do arquivo, que levou alguns minutos.
Após o término da execução da instrução da Listagem 1, o SQL Server retornou a mensagem “The backup set is valid”, indicando que o arquivo continha ao menos um backup do SQL Server, confirmando a minha suspeita inicial a respeito do conteúdo do arquivo, e que este backup poderia ser restaurado.
Uma vez constatado que o arquivo continha ao menos um backup, o próximo passo foi verificar quantos backups e quais tipos de backups estavam contidos dentro deste arquivo. Para efetuar esta operação utilizei a instrução RESTORE HEADERONLY, indicando como parâmetro a localização do arquivo, como mostrado na Listagem 2.
/* INFORMAÇÕES SOBRE O TIPO DE BACKUP */
RESTORE HEADERONLY
FROM DISK = 'C:\RJ_RELAT_02-10-2005\RJ_RELAT_02-10-2005.BAK'
Listagem 2: Obtendo informações sobre o backup
A instrução da Listagem 2 foi executada rapidamente e o SQL Server retornou uma linha com várias colunas e informações importantes sobre o backup contido neste arquivo. A Tabela 1 mostra as principais colunas e valores retornados pela instrução RESTORE HEADERONLY e os valores destas colunas referentes ao backup contido no arquivo RJ_RELAT-02-10-2005.BAK.
Nome da Coluna |
Significado |
Valor Obtido |
BackupName | Nome do backup | NULL |
BackupType |
Tipo de Backup: 1 – Banco de dados 2 – Transaction Log 4 – Arquivo 5 – Diferencinal Banco de dados 6 – Diferencial de arquivo |
1 |
ExpirationDate |
Data de expiração. Passada esta data o backup não pode ser restaurado. |
NULL |
Position | Posição deste backup no dispositivo. | 1 |
DeviceType |
Tipo do dispositivo: 2 – Disco 5 – Fita 6 – Pipe 7 – Dispositivo virtual |
2 |
ServerName |
Nome do servidor SQL Server no qual este backup foi gerado. |
SERVERSQL02 |
DatabaseName |
Nome do banco de dados no qual este backup foi gerado. |
RELAT |
BackupStartDate | Data de início do backup. | 2005-10-02 03:00:02.000 |
BackupFinishDate | Data de término do backup. | 2005-10-02 03:06:55.000 |
SortOrder |
Número do SortOrder do banco de dados no qual este backup foi gerado. |
52 |
CodePage |
Número do CodePage do banco de dados no qual este backup foi gerado. |
228 |
CompatibilityLevel |
Nível de compatibilidade do banco de dados no qual este backup foi gerado. 60 – SQL Server 6.0 65 – SQL Server 6.5 70 – SQL Server 7.0 80 – SQL Server 2000 |
80 |
MachineName |
Nome do servidor no qual este backup foi gerado. |
SERVERSQL02 |
Collation |
Collation do banco de dados no qual este backup foi gerado. |
SQL_Latin1_General_CP1_CI_AS |
Tabela 1: Descrição e valores das principais colunas retornadas pelo comando RESTORE HEADERONLY
Analisando o resultado da instrução, pude obter várias informações úteis. A primeira delas é que o backup não está protegido por senha e que existe apenas um backup neste arquivo, pois somente uma linha foi retornada.
Descobri, ainda, que o arquivo contém um backup completo do banco de dados RELAT com a Collation SQL_Latin1_General_CP1_CI_AS gerado no dia 02/10/2005, no servidor chamado SERVERSQL02, que possuía uma instalação do SQL Server 2000. Com estas informações, já tinha quase tudo o que precisava para restaurar o banco de dados a partir deste backup.
As últimas informações que ainda precisava para poder restaurar o banco de dados contido neste backup dizem respeito aos arquivos de dados e transaction log deste banco RELAT. Para obter estas informações utilizei a instrução RESTORE FILELISTONLY como mostra a Listagem 3.
/* INFORMAÇÕES SOBRE OS ARQUIVOS CONTIDOS NO BACKUP */
RESTORE FILELISTONLY
FROM DISK = 'C:\RJ_RELAT_02-10-2005\RJ_RELAT_02-10-2005.BAK'
Listagem 3: Obtendo informações sobre os arquivos de dados e de transaction log do backup
O resultado da execução da instrução apresentada na Listagem 3 é mostrado na Figura 1.
Figura 1: Resultado da execução da instrução RESTORE FILELISTONLY
A instrução RESTORE FILELISTONLY retornou seis linhas, indicando o nome dos arquivos lógicos na coluna LogicalName, a localização física dos arquivos no servidor que foi feito o backup na coluna PhysicalName, o tipo de cada arquivo na coluna Type (D indica arquivo de dados e L arquivo de transaction log), o FileGroup a qual cada arquivo pertence na coluna FileGroupName, o tamanho em bytes dos arquivos no momento do backup na coluna Size e o tamanho máximo em bytes que os arquivos poderiam chegar na coluna MaxSize.
A partir dos dados pude notar que este banco de dados possuía três arquivos de dados, cujos nomes lógicos eram Relat, rELAT1 e Relat2, e três arquivos de transaction log, cujos nomes lógicos eram Relat_log, Relat_lo1 e Relat_lo2. Notem que não podemos identificar o tipo de arquivo somente pela sua extensão e que os arquivos de transaction log não pertencem a nenhum FileGroup.
Com os dados retornados pelas instruções RESTORE VERIFYONLY, RESTORE HEADERONLY, e RESTORE FILELISTONLY, eu já tinha informações suficientes para restaurar o backup em um servidor que não possuía o banco de dados RELAT.
Restaurando e recriando o banco de dados
Antes de restaurar o banco de dados, pensei em alguns detalhes. Um deles diz respeito aos usuários deste banco de dados RELAT, que estava prestes a ser recriado. Se algum desses usuários do banco RELAT estivesse associado a algum login do servidor SQL Server onde este backup foi feito, infelizmente não conseguiria restaurá-los, pois os logins são armazenados no banco de dados de sistema chamado Master, e no arquivo de dados que me foi fornecido não havia nenhum backup deste banco. Para evitar este problema, é sempre recomendável que a transferência dos logins seja feita antes da restauração do banco de dados em outro servidor.
A Microsoft colocou alguns artigos no seu web site de suporte que podem ajudar o DBA a fazer esta transferência de logins entre servidores diferentes. A Tabela 2 mostra os principais artigos sobre este assunto e os seus respectivos endereços na internet.
Nome do artigo |
Endereço do artigo (URL) |
HOW TO: Transfer Logins and Passwords Between Instances of SQL Server | http://support.microsoft.com/kb/246133/ |
HOW TO: Resolve Permission Issues When You Move a Database Between Servers That Are Running SQL Server |
http://support.microsoft.com/default.aspx?scid=kb;EN-US;240872 |
PRB: “Troubleshooting Orphaned Users” Topic in Books Online is Incomplete |
http://support.microsoft.com/kb/274188/ |
Tabela 2: Nome e endereços de artigos sobre transferência de logins
Para o nosso exemplo, felizmente o banco de dados RELAT não tinha nenhum usuário, como descobri após a restauração do banco de dados.
Outro detalhe a ser levando em consideração é a Collation. Fiz uma verificação no servidor SQL Server que estava sendo executado localmente em minha estação de trabalho e constatei que a Collation utilizada no meu servidor era a mesma do banco de dados contido no backup. Caso a Collation do backup seja diferente da Collation do servidor que receberá o banco de dados, temos duas opões:
- Alterar a Collation padrão do servidor através da reconstrução do banco de dados de sistema Master. Esta opção é arriscada e pode afetar outros bancos de dados já instalados no servidor.
- Criar um novo banco de dados com o mesmo nome e Collation do banco a ser restaurado. No momento da execução do comando que restaura o banco de dados existe a opção REPLACE que apaga o banco com o mesmo nome e a restaura a partir do backup.
Como no meu caso o servidor já estava configurado com a mesma Collation do backup bastava iniciar o processo de restauração. Esta restauração foi feita em um servidor SQL Server 2000 que estava sendo executado localmente na minha estação de trabalho e que não possuía o banco de dados RELAT. Sendo assim, a restauração do backup deveria recriar o banco.
Para restaurar o banco RELAT foi necessário especificar o nome lógico de cada arquivo de dados e de transaction log do backup, pois desejava armazenar estes arquivos no mesmo diretório no qual extraí o arquivo que continha o backup. Para isso utilizei a opção WITH MOVE da instrução RESTORE DATABASE para cada arquivo contido no backup, como mostra a Listagem 3 que recria o banco de dados a partir do um backup.
/* RECRIANDO O BANCO DE DADOS RELAT A PARTIR DO BACKUP */
RESTORE DATABASE RELAT
FROM DISK = 'C:\RJ_RELAT_02-10-2005\RJ_RELAT_02-10-2005.BAK'
WITH MOVE 'Relat' TO 'C:\RJ_RELAT_02-10-2005\Relat.mdf',
MOVE 'rELAT1' TO 'C:\RJ_RELAT_02-10-2005\Relat1.ndf',
MOVE 'Relat2' TO 'C:\RJ_RELAT_02-10-2005\Relat2.ndf',
MOVE 'Relat_log' TO 'C:\RJ_RELAT_02-10-2005\Relat-log.ndf',
MOVE 'Relat_lo1' TO 'C:\RJ_RELAT_02-10-2005\Relat-log1.ndf',
MOVE 'Relat_lo2' TO 'C:\RJ_RELAT_02-10-2005\Relat-log2.ndf'
Listagem 4: Instrução que recria o banco de dados a partir do backup
Após vários minutos, o banco de dados RELAT foi criado e os arquivos de dados e transaction log foram gerados com o mesmo tamanho que tinham antes do backup ser feito no servidor de origem. A partir deste momento o banco de dados estava on-line e pronto para receber conexões que utilizaram os objetos deste banco de dados.
Conclusão
Vimos uma descrição passo a passo de como levantar informações sobre um backup de um banco de dados e recriar este banco em um outro servidor. As instruções RESTORE VERIFYONLY, RESTORE HEADERONLY e RESTORE FILELISTONLY foram apresentadas seguidas de exemplos. A instrução RESTORE DATABASE foi utilizada para recriar a base de dados e torná-la operacional para os usuários.