Esta é uma área que gosto muito, apesar que não gostaria de passar por uma situação desta em produção… hehehe
![Susto](https://blogdozouza.wordpress.com/wp-content/uploads/2012/01/susto.jpg?w=474)
Encontrei este Post no Blog do Erickson Ricci, segue abaixo conforme o autor escreveu (todo o mérito é do autor, que esta de parabéns pelo excelente material)…
Neste post farei a análise de um banco de dados corrompido. O banco de dados corrompido que irei utilizar foi disponibilizado num grupo de estudos para a certificação MCM no qual estou participando. O grupo foi iniciado pelo MVP Jason Strate ( blog | @StrateSQL ) e quem quiser mais informações pode acessar este post dele: http://www.jasonstrate.com/2011/12/sql-mcm-study-group/.
Vocês poderão baixar o banco de dados corrompido aqui.
Vamos começar a análise então. Antes de mais nada, precisamos deixar nosso banco de dados disponível em nossa instância. A maneira mais simples de fazer isto é anexar (attach) a base, seja pela interface gráfica ou via comando, desta forma:
CREATE DATABASE [CorruptDB1] ON
( FILENAME = N'C:\temp\CorruptDBs\CorruptDB1\DBFiles\CorruptDB1.mdf' ),
( FILENAME = N'C:\temp\CorruptDBs\CorruptDB1\DBFiles\CorruptDB1_log.ldf' )
FOR ATTACH;
GO
Substitua o caminho “C:\temp\CorruptDBs\…” para o local onde você escolher descompactar os arquivos.
Uma vez que o banco de dados estiver anexado, vamos rodar um DBCC CHECKDB para ver qual o estado do nosso banco.
DBCC CHECKDB(CorruptDB1)
WITH ALL_ERRORMSGS, NO_INFOMSGS
Foi utilizado as opções ALL_ERRORMSGS e NO_INFOMSGS para exibir como resultado somente mensagens de erro e ignorar mensagens informativas. Se desejar mais informações sobre o comando DBCC CHECKDB, clique aqui. O resultado que temos é o seguinte:
Msg 8939, Level 16, State 98, Line 1
Table error: Object ID 99, index ID 0, partition ID 0, alloc unit ID 6488064 (type System allocation data),
page (1:7). Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed. Values are 12716041 and -4.
CHECKDB found 1 allocation errors and 0 consistency errors in table ‘(Object ID 99)’ (object ID 99).
CHECKDB found 1 allocation errors and 0 consistency errors in database ‘CorruptDB1′.
Há algo errado com nosso banco de dados. E agora, que ação devemos tomar?
O comando CHECKDB possui duas opções chamadas REPAIR_ALLOW_DATA_LOSS e REPAIR_REBUILD. A primeira impressão é “…ótimo, o DBCC CHECKDB vai resolver meu problema de corrupção!”.
A primeira opção “tenta” reparar o problema de corrupção e pode ocasionar perda de dados. Já a segunda opção “tenta” executar reparos que não possibilitem perda de dados. Como não queremos perder nenhum dado da base, vamos executar a segunda opção primeiro. Vou alterar o acesso do banco de dados para SINGLE_USER e vou executar estas opções.
ALTER DATABASE CorruptDB1 SET SINGLE_USER
WITH ROLLBACK IMMEDIATE;
GO
DBCC CHECKDB(CorruptDB1, REPAIR_REBUILD)
WITH ALL_ERRORMSGS, NO_INFOMSGS
E temos o seguinte resultado:
Msg 8939, Level 16, State 98, Line 1
Table error: Object ID 99, index ID 0, partition ID 0, alloc unit ID 6488064 (type System allocation data), page (1:7). Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed. Values are 12584969 and -4.
The repair level on the DBCC statement caused this repair to be bypassed.
CHECKDB found 1 allocation errors and 0 consistency errors in table ‘(Object ID 99)’ (object ID 99).
CHECKDB found 1 allocation errors and 0 consistency errors in database ‘CorruptDB1′.
Hummm… Nada resolvido. Ainda tivemos o erro 8939. Vamos forçar a barra e tentar o reparo com possível perda de dados.
DBCC CHECKDB(CorruptDB1, REPAIR_ALLOW_DATA_LOSS)
WITH ALL_ERRORMSGS, NO_INFOMSGS
E o resultado:
Msg 8939, Level 16, State 98, Line 1
Table error: Object ID 99, index ID 0, partition ID 0, alloc unit ID 6488064 (type System allocation data), page (1:7). Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed. Values are 12584969 and -4.
The repair level on the DBCC statement caused this repair to be bypassed.
CHECKDB found 1 allocation errors and 0 consistency errors in table ‘(Object ID 99)’ (object ID 99).
CHECKDB found 1 allocation errors and 0 consistency errors in database ‘CorruptDB1′.
Novamente, nada feito. Pelo nível de corrupção do banco de dados, o comando DBCC CHECKDB não consegue reparar este problema. Vamos ter que fazer uma análise um pouco mais profunda e por a mão na massa para resolver o problema.
Nós vamos encontrar a explicação deste erro aqui. Em linhas gerais, ele nos informa que foi realizada uma validação numa determinada página, e esta validação falhou por uma corrupção no cabeçalho (Header) da página. Interessante não?!
Analisando a mensagem completa de erro que nos foi dada, podemos observar que ela nos informa qual é a página que está com problema: “…page (1:7). Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed. …”. Fica a dica: LEIA TODA A MENSAGEM DE ERRO!!! Achei que isto deveria ficar em destaque pois é muito comum ver as pessoas sem saber o que fazer e a mensagem de erro te dá dicas valiosas sobre o que aconteceu. Nem sempre é assim, mas na maioria das vezes é válido. Vamos dar uma olhada nesta página:
DBCC TRACEON(3604)
GO
DBCC PAGE('CorruptDB1', 1, 7, 3)
Quer saber mais sobre o Trace Flag 3604 e sobre o comando DBCC PAGE, acesse aqui e aqui.
O resultado completo que temos é o seguinte:
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
Msg 8939, Level 16, State 98, Line 1
Table error: Object ID 99, index ID 0, partition ID 0, alloc unit ID 6488064 (type System allocation data), page (1:7). Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed. Values are 12584969 and -4.PAGE: (1:7)BUFFER:BUF @0x000000008EFA8F40bpage = 0x000000008E17E000 bhash = 0×0000000000000000 bpageno = (1:7)
bdbid = 17 breferences = 0 bcputicks = 0
bsampleCount = 0 bUse1 = 50557 bstat = 0xc00809
blog = 0×21212159 bnext = 0×0000000000000000PAGE HEADER:Page @0x000000008E17E000m_pageId = (1:7) m_headerVersion = 0 m_type = 0
m_typeFlagBits = 0×0 m_level = 0 m_flagBits = 0×200
m_objId (AllocUnitId.idObj) = 99 m_indexId (AllocUnitId.idInd) = 0 Metadata: AllocUnitId = 6488064
Metadata: PartitionId = 0 Metadata: IndexId = 0 Metadata: ObjectId = 99
m_prevPage = (0:0) m_nextPage = (0:0) pminlen = 90
m_slotCnt = 2 m_freeCnt = 6 m_freeData = 8182
m_reservedCnt = 0 m_lsn = (0:0:1) m_xactReserved = 0
m_xdesId = (0:0) m_ghostRecCnt = 0 m_tornBits = 105713478Allocation StatusGAM (1:2) = ALLOCATED SGAM (1:3) = NOT ALLOCATED PFS (1:1) = 0×44 ALLOCATED 100_PCT_FULL
DIFF (1:6) = CHANGED ML (1:7) = NOT MIN_LOGGED
Msg 2514, Level 16, State 5, Line 1
A DBCC PAGE error has occurred: Invalid page type – dump style 3 not possible.
Obviamente houve erros no resultado. Mas o que chama a atenção são os pontos que destaquei em negrito. Se dermos uma olhada no Internals (um modo “carinhoso” de chamar o livro Microsoft SQL Server 2008 Internals), veremos no capítulo 3, página 147, parágrafo 2 ( :-O Não, eu não decorei isto, fui ver no livro… ^.^ ) as explicações sobre as páginas de alocação de dados, em resumo, assim:
- Page 0 – File Header
- Page 1 – PFS Page Free Space
- Page 2 – GAM Global Allocation Map
- Page 3 – SGAM Shared Global Allocation Map
- Page 4 e Page 5 – não são utilizadas
- Page 6 – DCM Differential Changed Map
- Page 7 – BCM Bulk Changed Map
Isto nos leva à conclusão de que a página que temos corrompida neste banco de dados é a página BCM, Bulk Changed Map. Não vou entrar neste momento no detalhe das páginas de controle, ficando apenas por dizer que é uma das páginas de controle de alocação de dados do SQL Server.
Ótimo! Agora sabemos o que fazer. Podemos então fazer o restore desta página e tudo resolvido. Será?!
Vamos tentar.
USE MASTER;
GO
RESTORE DATABASE CorruptDB1
PAGE = '1:7'
FROM DISK = 'C:\temp\CorruptDBs\CorruptDB1\Bak\CorruptDB1.bak'
WITH RECOVERY
Vamos utilizar o comando RESTORE para restaurar somente a nossa página corompida. O resultado que temos é:
Msg 3111, Level 16, State 1, Line 2
Page (1:7) is a control page which cannot be restored in isolation. To repair this page, the entire file must be restored.
Msg 3013, Level 16, State 1, Line 2
RESTORE DATABASE is terminating abnormally.
Ops! O SQL Server não nos permite restaurar isoladamente páginas de controle… E nos informa que para resolução do problema temos de restaurar o arquivo completo.
Solução para o problema e evitar perda de dados. Faça um backup de log (Tail Log Backups) e aplica um restore do banco de dados e depois aplique os logs na sequência, se houver, e por último aplique o último backup de log gerado (tail log). Depois de seguir estes passos, execute novamente o comando DBCC CHECKDB para ter certeza de que seu problema foi resolvido.
Esta foi a solução que foi encontrada para este problema de corrupção.
Veja também:
Integridade do Banco de Dados
Possible Index Corruption. Diagnosticando o problema
Corruption demo databases and scripts
Corrigindo Erro de Suspect Database (novo)
Corrompendo um Banco SQL (novo)
Corrupção de Dados direto das trincheiras (novo)
Ver páginas corrompidas (SQL Server)
Verificação de Página e Restore de Bases no SQL Server
Recriando as databases de sistema
Automatizando a verificação de integridade de seus bancos de dados
Como Restaurar o Master, Model e MSDB
Entendendo e Melhorando seus backups (SQL Server)
Restaurando um Database Suspect – SQL Server
Databases em modo Suspect e Pendente Recovery
Creating, detaching, re-attaching, and fixing a SUSPECT database