Dia 08/12/2011 choveu muito aqui em sampa,,, tivemos problemas com a elétrica aqui no prédio, ocasionando diversas quedas de energia,,,
Tenho instalado no desktop um SQL Server 2008 R2 Express, onde tenho algumas bases para testes,, até ai nenhuma novidade,,,
Quando cheguei no dia seguinte (09/12/2011) percebi que um sistema que uso para testar algumas bases não estava funcionando,,, a mensagem era simples: “Não consigo acessar o SQL”
Tentei iniciar o serviço do SQL e, claro, não consegui,,, Acessei os eventos do sistema e achei a seguinte mensagem:
Interessante,,, o transaction log do model foi corrompido… isso é legal…
Iniciei o SQL em modo de segurança e rodei um DBCC CHECKDB, não fez diferença…
Como a base Model não é uma das bases mais vitais do SQL e eu não tenho backup dela,,, fui no diretório de Templates e copiei a base de lá para o diretório onde estava a base de “produção”. Iniciei o SQL e ele carregou sem problemas….
Lembrando que, não é porque existem outras bases de sistema por aqui que você pode sobre-escrever a Master ou a MSDB…
Aí vem uma pergunta,,, por que o SQL não subiu com a base em suspect ou offiline? ou qualquer outro aviso? simples… a base Model, por mais simples que seja serve como base para criar o TempDB,,, sem ela,, o SQL não consegue criar o mínimo para o TempDB… eu consegui iniciar o SQL em modo de segurança porque usei a traceflag 3609 onde ele não recriou o tempdb…
Mesmo que saiba o que fazer, é importante treinar para situações complicadas…
É melhor fazer muita tentativa em erro em um ambiente controlado do que no ambiente de produção,,, certo?
Então,,, antes de mais nada… eu sei que você sabe,,, mas não custa nada relembrar,,,
NUNCA FAÇA ISSO EM PRODUÇÃO !!!
Bom,,, com isso em mente,,, vamos começar,,,
1. Vamos criar uma base:
CREATE DATABASE [corrompeu] GO
2. Vamos alterar o modo de recovery da base:
alter database corrompeu set recovery full GO
3. Agora vamos colocar uma tabela:
use corrompeu GO
create table vendas ( vendasID int identity, clienteID int default convert(int, 100000 * RAND()), vendaData datetime default getdate(), vendaTotal money ) GO
4. Adicionamos um índice pra dar gosto…
create clustered index vendaCI on vendas (vendasID) GO
5. Colocamos uns dados,,,
set nocount ON GO
declare @conta INT select @conta = 0 while (@conta < 50000) begin insert into vendas (vendaTotal) values (100*RAND()) select @conta = @conta +1 end GO
7. E vamos fazer uns backups
use master GO
backup database corrompeu to disk = ‘d:\db01\local\corrompeu_1.bak’ with init go
backup log corrompeu to disk = ‘d:\db01\local\corrompeu_2.trn’ go
8. Bom,,, com os backups feitos,,, vamos ver as páginas que foram criadas,,,
dbcc ind (‘corrompeu’,‘vendas’,1) GO
9. Escolha uma página e coloque no lugar do XXXXX
DBCC TRACEON (3604) GO dbcc page(‘corrompeu’,1,XXXXX,3)
Você deve ver alguma coisa do tipo:
A página que eu escolhi foi a 1:493. Meu vendasID vai do registro 24256 até 245000.
Agora começa a ficar legal….
10. Vamos colocar a base offline:
alter database corrompeu set offline GO
11. Agora um simples cálculo…
select 493*8192 GO
Temos o número em decimal da localização da página no arquivo .mdf
12. Com esse número vamos utilizar um editor Hexadecimal para achar a linha dentro do arquivo .mdf.
Dentro do editor de Hexadecimal, abra o arquivo .mdf (neste caso D:\DB01\Corrompeu.mdf).
Clique em “Localizar” e escolha “Ir Para”.
Escolha a opção “DEC”, digite ou cole o resultado do cálculo acima e depois cliente em “HEX”, ele vai converter o valor para Hexadecimal.
clique em “OK”
Altere a linha onde o cursor esta piscando para 00 (zero-zero), ela vai ficar em vermelho.
Salve o arquivo.
13. Agora dentro do SQL vamos voltar com a base online:
alter database corrompeu set online GO
14. Usando o DBCC CHECKDB, vamos ver se a base está realmente corrompida…
Legal,,, temos uma base corrompida…
15. vamos tentar um select na tabela,,, e olha lá o erro,,,
Bom,,, legal… temos uma base corrompida,,, e agora?
Agora fica legal… o objetivo é deixar a base operacional sem perder informação… imagine que essa é sua base de produção e justamente essa tabela é a folha de pagamento,,, olha que legal…
Uma dica: tentei fazer o processo de restore no SQL Server Denali CTP 1 e não consegui restaurar apenas a página, tive que remover ela e reinserir os dados através de outra base, fiz o mesmo processo de restore apenas da página no SQL Server 2008 R2 e funcionou sem problema.
Se alguém precisar de ajuda é só deixar o comentário…
ATUALIZAÇÃO:
Segue o link do SkyDrive com a base, backup e o script desse exemplo:
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional
Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes.The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.