{"id":564,"date":"2011-03-17T22:26:14","date_gmt":"2011-03-18T00:26:14","guid":{"rendered":"http:\/\/fabriciolima.net\/blog\/?p=564"},"modified":"2016-07-23T23:04:24","modified_gmt":"2016-07-24T02:04:24","slug":"casos-do-dia-a-dia-erro-ao-executar-o-comando-dbcc-checkdb","status":"publish","type":"post","link":"https:\/\/fabriciolima.net\/blog\/2011\/03\/17\/casos-do-dia-a-dia-erro-ao-executar-o-comando-dbcc-checkdb\/","title":{"rendered":"Casos do Dia a Dia: Erro ao executar o comando DBCC CHECKDB"},"content":{"rendered":"<p>Fala Pessoal,<\/p>\n<p>Ontem, ao chegar em meu ambiente de trabalho, verifiquei que minha rotina de CHECKDB de um dos meus servidores havia falhado.<\/p>\n<p>JOB RUN:\u00a0\u00a0 \u00a0&#8216;DBA &#8211; CHECKDB&#8217; was run on 15\/3\/2011 at 21:20:00<br \/>\nDURATION:\u00a0\u00a0 \u00a01 hours, 29 minutes, 17 seconds<br \/>\nSTATUS: \u00a0\u00a0 \u00a0Failed<\/p>\n<p>At\u00e9 a\u00ed estava tudo bem pois ela j\u00e1 havia falhado anteriormente por falta de recursos dispon\u00edveis para execut\u00e1-la. Entretanto, ao verificar minha <a title=\"CheckList DBA\" href=\"https:\/\/www.fabriciolima.net\/blog\/2010\/03\/24\/criando-um-checklist-automatico-do-banco-de-dados\/\" target=\"_blank\">planilha com o checklist di\u00e1rio do DBA<\/a>, na aba CHECKDB, encontrei a seguinte mensagem:<\/p>\n<p>DBCC CHECKDB (Nome_Database) WITH no_infomsgs executed by Nome_Usuario<strong> found 2 errors and repaired 0 errors<\/strong>. Elapsed time: 0 hours 20 minutes 20 seconds.<\/p>\n<p>Agora a casa tinha ca\u00eddo.<\/p>\n<p>Ao abrir o log do SQL Server, verifiquei a seguinte mensagem nas execu\u00e7\u00f5es do comando DBCC CHECKDB dessa database:<\/p>\n<ul>\n<li>Found 2 errors and repaired 0 errors.<\/li>\n<li>*DBCC database corruption<\/li>\n<\/ul>\n<p>Duvido que essa frase no log do SQL Server n\u00e3o te da um frio na barriga tamb\u00e9m: <strong>*DBCC database corruption<\/strong><\/p>\n<p>Olhando o hist\u00f3rico do Job encontrei o seguinte resultado:<\/p>\n<p><strong>Page (1:88888888)<\/strong>, <strong>slot 4<\/strong> in object ID 77777777, index ID 1, partition ID 99999999999999999999,<br \/>\nalloc unit ID 6666666666666666 (type &#8220;In-row data&#8221;). Column &#8220;<strong>Nome_Coluna1<\/strong>&#8221; value is out of range for data type &#8220;decimal&#8221;.<br \/>\nUpdate column to a legal value. [SQLSTATE 42000] (Error 2570)<\/p>\n<p><strong>Page (1:88888888)<\/strong>, <strong>slot 4<\/strong> in object ID 77777777, index ID 1, partition ID 99999999999999999999,<br \/>\nalloc unit ID 6666666666666666 (type &#8220;In-row data&#8221;). Column &#8220;<strong>Nome_Coluna2<\/strong>&#8221; value is out of range for data type &#8220;numeric&#8221;.<br \/>\nUpdate column to a legal value. [SQLSTATE 42000] (Error 2570)<\/p>\n<p>CHECKDB found 0 allocation errors and 2 consistency errors in table &#8216;<strong>Nome_Tabela<\/strong>&#8216; (object ID 99999999). [SQLSTATE 01000] (Error 8990)<br \/>\nCHECKDB found 0 allocation errors and 2 consistency errors in database &#8216;<strong>Nome_Database<\/strong>&#8216;. [SQLSTATE 01000] (Error 8989).\u00a0 The step failed.<\/p>\n<p>Recorri ao google e rapidamente encontrei esse <a title=\"KB Microsoft\" href=\"http:\/\/support.microsoft.com\/kb\/923247\" target=\"_blank\">KB da microsoft<\/a> que utilizei como refer\u00eancia para resolver o problema.<\/p>\n<p>Olhando em outros sites, verifiquei que esse erro era bem comum de ser encontrado em migra\u00e7\u00f5es do SQL Server 2000 para o SQL Server 2005 ou superior, entretanto, esse n\u00e3o era o meu caso pois\u00a0 essa base j\u00e1 estava criada no SQL Server 2005 a anos e o dbcc checkdb \u00e9 executado diariamente nela.<\/p>\n<p>Como a database que deu problema \u00e9 restaurada diariamente em um servidor de teste. Verifiquei que o mesmo erro estava acontecendo na database de teste e fui encontrar uma solu\u00e7\u00e3o.<\/p>\n<p>Pelas mensagens de erro, o problema estava na mesma p\u00e1gina de dados de um mesmo objeto (os n\u00fameros do post s\u00e3o fict\u00edcios):<br \/>\nErro na Coluna 1: Page (1:88888888), slot 4 in object ID 77777777<br \/>\nErro na Coluna 2: Page (1:88888888), slot 4 in object ID 77777777<\/p>\n<p>Seguindo o KB e executando o comando abaixo para verificar os registros da p\u00e1gina com problema:<\/p>\n<p>DBCC TRACEON ( 3604 )<br \/>\nDBCC PAGE ( Nome_Database , 1 , 88888888 , 3 )<\/p>\n<p>Tive o retorno de um grande result set.<\/p>\n<p>Pesquisei no resultado pelo nome das duas colunas retornadas no erro e encontrei um n\u00famero absurdo para uma destas colunas exatamente no slot 4, que foi retornado nos 2 erros.<\/p>\n<p><strong>Slot 4<\/strong> Column 33 Offset 0x10c Length 9<\/p>\n<p>Nome_COluna1 = -1634.41<\/p>\n<p><strong>Slot 4<\/strong> Column 57 Offset 0x1a7 Length 9<\/p>\n<p><strong>Nome_Coluna2 = 89998897014397766.68<\/strong><\/p>\n<p>Sendo que a coluna 2 era do tipo numeric(15,2).<\/p>\n<p>Encontrado o valor com problema, fui tentar fazer um select para encontrar toda a linha:<\/p>\n<p>Essa query retornava um erro:<br \/>\nSELECT *<br \/>\nFROM Tabela<br \/>\nWHERE Nome_Coluna2 = 89998897014397766.68<\/p>\n<p>Todavia, essa era executada com sucesso:<br \/>\nSELECT count(*)<br \/>\nFROM Tabela<br \/>\nWHERE Nome_Coluna2 = 89998897014397766.68<\/p>\n<p>Como o count(*) retornou 1 registro, rodei um update para descobrir todo o conte\u00fado da linha que estava com problema:<br \/>\nupdate Tabela<br \/>\nset Nome_Coluna2 = 9999999999<br \/>\nWHERE Nome_Coluna2 = 89998897014397766.68<\/p>\n<p>Com a query abaixo, verifiquei que os dois valores do slot 4 (-1634.41 e 89998897014397766.68)<strong> <\/strong>pertenciam a mesma linha.<br \/>\nSELECT *<br \/>\nFROM Tabela<br \/>\nWHERE Nome_Coluna2 = 9999999999<\/p>\n<p>Como j\u00e1 tinha acertado o valor absurdo da coluna 2, executei o comando abaixo para testar novamente a consist\u00eancia da tabela:<br \/>\nDBCC CHECKTABLE(&#8216;Nome_Tabela&#8217;)<\/p>\n<p>O comando continuou retornando um erro, entretanto, agora apenas para a coluna 1:<\/p>\n<p>Msg 2570, Level 16, State 3, Line 1<br \/>\n<strong>Page (1:88888888)<\/strong>, <strong>slot 4<\/strong> in object ID 77777777, index ID 1, partition ID 99999999999999999999,alloc unit ID 6666666666666666 (type &#8220;In-row data&#8221;). Column &#8220;<strong>Nome_Coluna1<\/strong>&#8221; value is out of range for data type &#8220;decimal&#8221;.Update column to a legal value.<\/p>\n<p>Fiz um update do valor da coluna1 para o mesmo valor:<\/p>\n<p>update Tabela<br \/>\nset Nome_Coluna1 = -1634.41<br \/>\nWHERE Chave_Tabela = xxxxxx<\/p>\n<p>Executei o comando abaixo para testar novamente e o mesmo n\u00e3o retornou nenhum erro.<br \/>\nDBCC CHECKTABLE(&#8216;Nome_Tabela&#8217;)<\/p>\n<p>Pronto, havia conseguido resolver o problema de consist\u00eancia com a perda de apenas uma coluna de uma linha.<\/p>\n<p>No meu caso real, o registro com problema foi importado de outra fonte durante a noite, ent\u00e3o foi poss\u00edvel exclu\u00ed-lo e import\u00e1-lo novamente.<\/p>\n<p>Caso eu n\u00e3o tivesse essa sorte, como eu descobri o problema em um dia, era s\u00f3 voltar o \u00faltimo backup limpo dessa database e conferir o valor das colunas com problema.<\/p>\n<p>Caso voc\u00ea n\u00e3o tivesse um backup limpo, com a solu\u00e7\u00e3o que realizamos nesse post perder\u00edamos o valor da Coluna2.<\/p>\n<p>N\u00e3o sei com certeza o motivo da gera\u00e7\u00e3o do problema, pois o registro com problema foi inserido dessa forma:<br \/>\nINSERT INTO Tabela<br \/>\nSELECT Colunas FROM Tabela<br \/>\nWHERE &#8230;<\/p>\n<p>Se fosse retornado um valor absurdo no select, seria gerado um erro no insert, ent\u00e3o acredito que o motivo da corrup\u00e7\u00e3o dessa p\u00e1gina de dados foi uma parada que aconteceu no servi\u00e7o do SQL Server no dia anterior por causa de uma press\u00e3o de mem\u00f3ria no servidor.<\/p>\n<p>Conforme j\u00e1 havia escrito em um artigo para a revista Codificando.NET <a title=\"Artigo Codificando Magazine\" href=\"https:\/\/www.fabriciolima.net\/blog\/2010\/11\/03\/quanto-tempo-levaria-para-descobrir-uma-database-corrompida\/\" target=\"_blank\">Quanto tempo levaria para descobrir uma database corrompida?<\/a>, \u00e9 extremamente importante possuir uma rotina de CHECKDB. Nesse caso os registros corrompidos foram poucos, mas poderiam ser muito mais. Se eu n\u00e3o tivesse essa rotina, o problema s\u00f3 seria descoberto quando algum usu\u00e1rio utiliz\u00e1-se o valor dessa coluna, o que poderia demorar dias. Com isso, todos os meus backups estariam corrompidos.<\/p>\n<p>Voc\u00ea ainda pode achar que esse problema \u00e9 raro e se n\u00e3o aconteceu at\u00e9 hoje, nunca vai acontecer com suas databases. Eu criei minha rotina de CHECKDB a mais de um ano e nunca havia retornado nenhum erro na mesma, entretanto, agora retornou.<\/p>\n<p>Fica a dica. Caso j\u00e1 tenha passado por esse problema e queria acrescentar alguma informa\u00e7\u00e3o, deixe um coment\u00e1rio.<\/p>\n<p><b>Gostou dessa dica?<\/b><\/p>\n<p>Cadastre seu e-mail para receber novos Posts e curta minha <a href=\"https:\/\/www.facebook.com\/FabricioLimaSolucoesemBancodeDados\/\" target=\"_blank\">P\u00e1gina no Facebook<\/a> para receber Dicas de Leituras e Eventos sobre SQL Server.<\/p>\n<p>Confira mais experi\u00eancias do Dia a Dia de um DBA no meu <a href=\"https:\/\/www.fabriciolima.net\/cursos-online\/treinamento-tarefas-do-dia-a-dia-de-um-dba-online\/\" target=\"_blank\">Treinamento de Tarefas do Dia a Dia de um DBA<\/a>.<\/p>\n<p>Abra\u00e7os,<\/p>\n<p>Fabr\u00edcio Lima<\/p>\n<p>MCITP \u2013 Database Administrator<\/p>\n<p>Consultor e Instrutor SQL Server<\/p>\n<p>Trabalha com SQL Server desde 2006<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Casos do Dia a Dia: Erro ao executar o comando DBCC CHECKDB<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[6,280],"tags":[249,248,252,251,24,261,260,247,253,257,255,49,33,256,254],"class_list":["post-564","post","type-post","status-publish","format-standard","hentry","category-casos-do-dia-a-dia","category-virtual-pass-br","tag-checklist-do-dba","tag-comando-dbcc-checkdb","tag-corrupcao-de-uma-database","tag-database-corrompida","tag-dbcc-checkdb","tag-dbcc-page","tag-dbcc-traceon","tag-erro-dbcc-checkdb","tag-error-2570","tag-error-8989","tag-error-8990","tag-sql","tag-sql-server","tag-sqlstate-01000","tag-sqlstate-42000"],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/posts\/564","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/comments?post=564"}],"version-history":[{"count":0,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/posts\/564\/revisions"}],"wp:attachment":[{"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/media?parent=564"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/categories?post=564"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/tags?post=564"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}