Socorro, meu banco de dados está corrompido. O que agora?

Um banco de dados corrompido é provavelmente um dos piores pesadelos do DBA. Isso resulta em tempo de inatividade, gritos de gerentes e todos os outros tipos de coisas desagradáveis

Neste artigo, vou explicar algumas das coisas que não devem ser feitas em um banco de dados corrompido e, em seguida, examinarei algumas das coisas que devem ser feitas, alguns dos cenários e as correções para eles.

Como identificar corrupção

A corrupção é normalmente bastante óbvia quando alguém percorre as páginas danificadas. As consultas falham com erros de alta gravidade. Os backups ou tarefas de reindexação falham com erros de alta gravidade. Algumas mensagens que indicam corrupção em um banco de dados são:

SQL Server detected a logical consistency-based I/O error: incorrect checksum (expected: 0xfdff74c9; actual: 0xfdff74cb). It occurred during a read of page (1:69965) in database ID 13 at offset 0x0000002229a000 in file 'D:\Develop\Databases\Broken1.mdf'. Attempt to fetch logical page 1:69965 in database 13 failed. It belongs to allocation unit 72057594049069056 not to 281474980642816.  

O principal problema é que, se as verificações regulares de integridade do banco de dados não estiverem sendo feitas, a corrupção pode ser detectada horas, dias ou até meses após ter ocorrido, ponto em que pode ser difícil de resolver

Não vou cobrir a situação em que o banco de dados está em um estado suspeito. Cobrindo as possíveis razões pelas quais um banco de dados é suspeito, os métodos para descobrir porque é suspeito e os vários meios de consertar isso são um artigo inteiro em si, se não um livro completo.

O que fazer quando o banco de dados está corrompido.

  1. Não entre em pânico
  2. Não desanexe o banco de dados
  3. Não reinicie o SQL
  4. Não execute apenas o reparo.
  5. Execute uma verificação de integridade
  6. Depois, faça uma análise da causa raiz

Não entre em pânico

A coisa mais importante ao lidar com corrupção de banco de dados de qualquer forma é não entrar em pânico. Quaisquer decisões ou ações tomadas devem ser cuidadosamente pensadas e feitas após uma consideração cuidadosa com todos os fatores levados em consideração. É muito fácil piorar a situação com decisões mal pensadas.

Não desanexe o banco de dados

Embora seja possível que a mensagem de corrupção descreva uma condição transitória, essa não é a situação normal. Na grande maioria dos casos, se o SQL detectar corrupção em um banco de dados, isso significa que realmente existem algumas páginas danificadas no banco de dados. Tentar enganar o SQL para não ver isso, desanexando e reanexando o banco de dados, fazendo backup e restaurando o banco de dados, reiniciando o serviço SQL ou reinicializando a máquina, não fará com que a corrupção desapareça.

Se houver corrupção no banco de dados e o SQL detectar essa corrupção ao anexar o banco de dados, a conexão falhará. Existem maneiras de hackear o banco de dados de volta para SQL, mas é muito melhor simplesmente não desanexar o banco de dados em primeiro lugar

Não reinicie o SQL

Semelhante à desanexação, reiniciar o serviço SQL não corrigirá a corrupção se ela estiver presente.

Tal como acontece com a desanexação do banco de dados, reiniciar o serviço pode piorar as coisas. Se o SQL Server encontrar danos ao executar a recuperação de reinicialização em um banco de dados, esse banco de dados será marcado como suspeito, tornando qualquer reparo necessário muito mais difícil de realizar.

Não execute apenas o reparo

Pode ser tentador apenas executar CheckDB com uma das opções de reparo (normalmente permite a perda de dados) e acreditar que isso tornará tudo melhor. Em muitos casos, executar o reparo não é a correção recomendada. Não há garantia de correção de todos os erros e isso pode resultar em perda de dados inaceitável.

A reparação é, na maioria dos casos, o último recurso para consertar a corrupção. Deve ser feito apenas quando nenhuma das alternativas é possível, não feito como a primeira coisa tentada.

Execute uma verificação de integridade

Para decidir sobre um método de reparar a corrupção, os detalhes de exatamente o que está danificado devem ser conhecidos. A única maneira de obter essas informações é executar CheckDB com a opção All_ErrorMsgs (no 2005 SP3, esta é uma opção padrão em CheckDB e não precisa ser especificada. Ela precisa ser especificada no SQL 2008). Além disso, a opção No_Infomsgs remove todas as informações sobre o número de linhas e o número de páginas da tabela, o que é desnecessário ao lidar com danos.

CheckDB pode demorar um pouco em bancos de dados maiores, mas é necessário deixá-lo ser executado até o fim. Uma estratégia de reparo não deve ser considerada sem conhecer todos os problemas no banco de dados

Causa raiz

Uma vez que a corrupção foi resolvida, o trabalho não acabou. Se a causa raiz da corrupção não for encontrada, pode acontecer novamente. Normalmente, a principal causa de corrupção são problemas com o subsistema de E / S. Outras causas possíveis são drivers de filtro com comportamento inadequado (como um antivírus), intervenção humana ou um bug no SQL.

Próximos passos

As etapas para resolver a corrupção dependem inteiramente dos resultados do CheckDB. Vou passar por alguns dos cenários mais comuns aqui. Este não é um documento abrangente de todas as possíveis corrupções em um banco de dados. 1

Esta lista está em ordem aproximada de gravidade, do problema menos grave ao mais grave. Cada um tem um exemplo de possíveis mensagens de erro que indicam esse problema específico. Em geral, o erro mais grave encontrado pelo CheckDB determina os métodos disponíveis para resolver o problema de corrupção.

Se alguém encontrar um erro que não esteja detalhado aqui, consulte a última seção – Obtendo Ajuda.

Metadados de espaço imprecisos

Inaccurate space metadata

Msg 2508, Level 16, State 3, Line 1
The In-row data RSVD page count for object "Broken1", index ID 0, partition ID 76911687695381, alloc unit ID 76911687695381 (type In-row data) is incorrect. Run DBCC UPDATEUSAGE.

Este erro indica que a página possui um valor incorreto para o espaço reservado. No SQL 2000, era possível que as contagens de linhas e páginas de uma tabela ou índice estivessem incorretas, até mesmo negativas. CheckDB não pegou isso. No SQL 2005, as contagens devem ser mantidas corretamente e o CheckDB dá um aviso quando encontra este cenário

Este não é um problema sério e é trivial de corrigir. Como diz a mensagem, execute DBCC UPDATEUSAGE no banco de dados em questão e os avisos desaparecerão. Isso é comum em bancos de dados atualizados do SQL 2000, pelos motivos mencionados acima, e não deve ocorrer no banco de dados criado no SQL 2005/2008.

Msg 8914, Level 16, State 1, Line 1
Incorrect PFS free space information for page (1:26839) in object ID 181575685, index ID 1, partition ID 293374720802816, alloc unit ID 76911687695381 (type LOB data). Expected value 0_PCT_FULL, actual value 100_PCT_FULL.

Este erro indica que a página PFS (espaço livre da página) que rastreia a quantidade de páginas inteiras tem valores incorretos. Isso, como o erro acima, não é sério. O algoritmo que rastreou isso no SQL 2000 nem sempre foi preciso. Embora seja necessário executar CheckDB com a opção Repair_Allow_Data_Loss, se este for o único erro que existe, ele não excluirá nenhum dado.

Corrupção apenas nos índices não clusterizados

Se todos os erros que checkDB retorna se referem a índices com IDs de 2 ou mais, isso indica que toda a corrupção está dentro dos índices não agrupados. Como os dados em um índice não clusterizado são redundantes, essas corrupções podem ser reparadas sem perda de dados.

Se todos os erros que o CheckDB detecta estiverem nos índices não clusterizados, o nível de reparo recomendado será Repair_Rebuild.

Msg 8941, Level 16, State 1, Line 1
Table error: Object ID 181575685, index ID 4, page (3:224866). Test (sorted .offset >= PAGEHEADSIZE) failed. Slot 159, offset 0x1 is invalid.

Msg 8942, Level 16, State 1, Line 1
Table error: Object ID 181575685, index ID 4, page (3:224866). Test (sorted.offset >= max) failed. Slot 0, offset 0x9f overlaps with the prior row.

Esses são apenas exemplos; existem muitos mais erros possíveis.

Nesse caso, a corrupção pode ser completamente reparada eliminando os índices não clusterizados danificados e recriando-os. As reconstruções de índice online (e algumas das reconstruções de índice offline) lêem o índice antigo para criar o novo e, portanto, encontrará a corrupção. Portanto, é necessário descartar completamente o índice antigo e criar um novo.

Isso é principalmente o que CheckDB com a opção repair_rebuild fará, entretanto, o banco de dados deve estar no modo de usuário único para que o reparo seja feito. Portanto, geralmente é melhor reconstruir manualmente os índices, pois o banco de dados pode permanecer online e em uso enquanto os índices afetados são recriados.

Se não houver tempo suficiente disponível para reconstruir o índice afetado e houver um backup limpo com uma cadeia de log ininterrupta, as páginas danificadas podem ser restauradas do backup.

Corrupção nas páginas LOB

Corruption in the LOB pages
Msg 8964, Level 16, State 1, Line 1
Table error: Object ID 181575685, index ID 1, partition ID 72057594145669120, alloc unit ID 72057594087800832 (type LOB data). The off-row data node at page (1:2444050), slot 0, text ID 901891555328 is not referenced.

Isso indica que há páginas LOB (objeto grande) que não são referenciadas por nenhuma linha de dados. Isso pode acontecer se houver corrupção do índice clusterizado ou heap e as páginas danificadas forem desalocadas.

Se esses forem os únicos erros retornados pelo CheckDB, executar o reparo com Allow_Data_Loss simplesmente desalocará essas páginas. Como as linhas de dados às quais os dados LOB pertencem não existem, isso não resultará em mais perda de dados.

Erros de pureza de dados

Data Purity errors
Msg 2570, Sev 16, State 3, Line 17
Page (1:1103587), slot 24 in object ID 34, index ID 1, partition ID 281474978938880, alloc unit ID 281474978938880 (type "In-row data"). Column "modified" value is out of range for data type "datetime". Update column to a legal value.

O erro de pureza dos dados indica que há um valor na coluna que está fora do intervalo aceitável da coluna. Pode ser uma data e hora em que os minutos após a meia-noite excedem 1440, uma string Unicode onde o número de bytes não é um múltiplo de 2, ou um float ou real com um valor de ponto flutuante inválido.

Esses erros não são verificados por padrão em um banco de dados atualizado do SQL 2000 ou inferior. CheckDB deve ser executado com sucesso uma vez, com a opção DATA_PURITY antes

CheckDB não vai consertar isso. Ele não sabe quais valores colocar na coluna para substituir os inválidos. A correção para isso é bastante fácil, mas manual. Os valores ruins devem ser atualizados anualmente para algo significativo. O principal desafio é encontrar as linhas ruins. Este artigo da KB descreve as etapas em detalhes. http://support.microsoft.com/kb/923247

Corrupção no índice clusterizado ou heap

Se houver corrupção nas páginas folha do índice clusterizado ou no heap, isso significa que os dados foram perdidos. As páginas de folha do índice clusterizado são as páginas de dados reais da tabela e, portanto, essa não é uma informação redundante.

Se algum dos erros detectados pelo CheckDB estiver nas páginas de folha do índice clusterizado, o nível de reparo recomendado será Repair_Allow_Data_Loss

Server: Msg 8976, Level 16, State 1, Line 2
Table error: Object ID 181575685, index ID 1, partition ID 76911687695381, alloc unit ID 76911687695381 (type In-row data). Page (1:22417) was not seen in the scan although its parent (1:479) and previous (1:715544) refer to it. Server: Msg 8939, Level 16, State 1, Line 2
Table error: Object ID 181575685, index ID 0, page (1:168576). Test (m_freeData >= PAGEHEADSIZE && m_freeData <= (UINT)PAGESIZE - m_slotCnt * sizeof (Slot)) failed. Values are 44 and 8028.

Esses são apenas exemplos; existem muitos mais erros possíveis. O que se deve notar é que o ID do índice mencionado é 0 ou 1. Se algum dos erros retornados pelo CheckDB tiver um ID do índice 0 ou 1, significa que há danos às tabelas base.

Esse tipo de dano é reparável, mas repará-lo envolve o descarte de linhas ou páginas inteiras. Se CheckDB excluir dados para corrigir a corrupção, ele não verificará as chaves estrangeiras e não disparará gatilhos. As linhas ou páginas serão simplesmente desalocadas. Isso pode resultar em violações de integridade de dados (registros filho sem um pai) e pode resultar em inconsistências lógicas do banco de dados (linhas de índice não clusterizadas ou páginas LOB que não fazem mais referência a uma linha). Como tal, o reparo não é a rota recomendada.

Se houver um backup limpo, a restauração do backup geralmente é o método recomendado para corrigir esses erros. Se o banco de dados estiver em recuperação total e houver uma cadeia de log ininterrupta desde o backup do banco de dados limpo, então é possível fazer backup do final do log de transações e restaurar todo o banco de dados ou apenas as páginas danificadas, sem perda de dados em todos.

Se não houver um backup limpo, é necessário executar CheckDB com a opção Repair_allow_data_loss. Isso requer que o banco de dados esteja no modo de usuário único durante o reparo.

Pode ser possível determinar o que CheckDB excluirá, para um índice clusterizado. Veja esta postagem do blog – http://sqlskills.com/BLOGS/PAUL/post/CHECKDB-From-Every-Angle-Using-DBCC-PAGE-to-find-what-repair-will-delete.aspx

Corrupção nos Metadados

Corruption in the Metadata
Msg 3853, Level 16, State 1, Line 1
Attribute (object_id=181575685) of row (object_id=181575685,column_id=1) in sys.columns does not have a matching row (object_id=181575685) in sys.objects.

Esse tipo de erro geralmente aparece em um banco de dados atualizado do SQL 2000, onde alguém fez atualizações diretas nas tabelas do sistema.

Não há chaves estrangeiras impostas entre as tabelas do sistema em qualquer versão do SQL, então era possível no SQL 2000 excluir uma linha de sysobjects (por exemplo, uma tabela) e deixar as linhas em syscolumns e sysindexes que fazem referência à linha excluída.

No SQL 2000, o CheckDB não fazia uma verificação do catálogo do sistema, então esse tipo de problema geralmente passava completamente despercebido. No SQL 2005, CheckDB faz verificações de consistência do catálogo do sistema e, portanto, esses erros podem aparecer.

Consertar isso não é trivial. O CheckDB não os reparará, pois a única correção é excluir os registros das tabelas do sistema, o que pode causar grande perda de dados. Se houver um backup do banco de dados anterior ao upgrade para o SQL 2005 e o upgrade for muito recente, esse backup pode ser restaurado no SQL 2000, as tabelas do sistema corrigidas no SQL 2000 e o banco de dados atualizado novamente.

Se não houver backup do SQL 2000 ou se a atualização foi há muito tempo e a perda de dados é inaceitável, há duas soluções possíveis. Primeiro, edite as tabelas do sistema no SQL 2005, que é um processo complexo e muito arriscado, pois as tabelas do sistema não são documentadas e são muito mais complexas do que eram nas versões anteriores. Consulte esta postagem do blog para obter detalhes – http://www.sqlskills.com/BLOGS/PAUL/post/TechEd-Demo-Using-the-SQL-2005-Dedicated-Admin-Connection-to-fix-Msg-8992-corrupt -system-tables.aspx

A outra solução é gerar scripts de todos os objetos do banco de dados e exportar todos os dados. Crie um novo banco de dados, recrie os objetos e recarregue os dados.

A segunda opção geralmente é a recomendada.

Corrupção Irreparável

CheckDB não pode reparar tudo. Quaisquer erros como esses são irreparáveis ​​e a única maneira de resolvê-los é restaurar um backup do banco de dados que não esteja corrompido. Se houver uma cadeia de log completa e ininterrupta desse backup até o momento atual, o final do log pode ser copiado e o banco de dados pode ser restaurado sem qualquer perda de dados.

Se não houver um backup limpo, a única opção restante é gerar scripts dos objetos do banco de dados e exportar os dados acessíveis. É bastante provável, devido à corrupção, que nem todos os dados estarão acessíveis e, muito provavelmente, nem todos os objetos executarão o script sem erros.

Tabelas de sistema danificadas

Damaged system tables

Msg 7985, Level 16, State 2, Line 1
System table pre-checks: Object ID 4. Could not read and latch page (1:358) with latch type SH.
Check statement terminated due to unrepairable error.
Msg 8921, Level 16, State 1, Line 1
Check terminated. A failure was detected while collecting facts. Possibly tempdb out of space or a system table is inconsistent.

CheckDB depende de algumas das tabelas críticas do sistema para obter uma visão do que deve estar no banco de dados. Se as próprias tabelas estiverem danificadas, o CheckDB não poderá saber como o banco de dados deve se parecer e nem mesmo poderá analisá-lo, muito menos repará-lo.

Páginas de alocação danificadas

Damaged allocation pages
Msg 8946, Level 16, State 12, Line 1
Table error: Allocation page (1:2264640) has invalid PFS_PAGE page header values. Type is 0. Check type, alloc unit ID and page ID on the page.
Msg 8998, Level 16, State 2, Line 1
Page errors on the GAM, SGAM, or PFS pages prevent allocation integrity checks in database ID 13 pages from (1:2264640) to (1:2272727)

Nesse caso, uma ou mais páginas de alocação de banco de dados estão danificadas. As páginas de alocação são usadas para marcar quais páginas e extensões no banco de dados estão alocadas e quais são gratuitas. CheckDB não reparará danos nas páginas de alocação, pois é extremamente difícil descobrir, sem essas páginas, quais extensões estão alocadas e quais não. Descartar a página de alocação não é uma opção, pois isso descartaria até 4 GB de dados.

Obtendo ajuda

Se você não tiver certeza do que fazer, peça ajuda. Se você se deparar com uma mensagem corrompida que não entende e que não está descrita aqui, peça ajuda. Se você não tiver certeza da melhor maneira de se recuperar, peça ajuda.

A ajuda pode vir de várias formas. Se houver um DBA sênior, pergunte a eles. Se você tiver um mentor, pergunte a ele. Pergunte em um fórum; os fóruns aqui, os grupos de notícias ou fóruns da Microsoft ou outro fórum, se preferir. Esteja ciente de que nem todos os conselhos dados nos fóruns são bons conselhos. Na verdade, algumas sugestões perigosas são postadas de vez em quando.

Finalmente, considere ligar para o pessoal de suporte ao cliente da Microsoft. Eles cobrarão, mas sabem como lidar com a corrupção e, se for um banco de dados crítico do sistema que está inativo, o custo do suporte pode ser muito menor do que o custo do tempo de inatividade durante a busca por uma solução.

Conclusão

Neste artigo, dei algumas sugestões sobre como lidar com a corrupção e, mais importante, como não lidar com a corrupção. Espero que as pessoas tenham um melhor entendimento dos métodos disponíveis para corrigir esses problemas e da importância de bons backups.

Fonte: https://www.sqlservercentral.com/articles/help-my-database-is-corrupt-now-what

Seja o primeiro a comentar

Faça um comentário

Seu e-mail não será publicado.


*