Houve uma atividade de rede ontem à noite e eles estavam atualizando o switch do servidor. Toda a rede estava inativa e nós, como DBA, nos preparamos desabilitando todos os trabalhos no servidor de banco de dados para replicação e backup, no entanto, durante a atividade, um dos WSFC (cluster de failover do servidor Windows) iniciou o failover e parece que não foi bem-sucedido completamente . Isso resultou em dois nós funcionando com banco de dados e todas as unidades em ambos os servidores, enquanto unidades e serviços SQL deveriam estar em apenas um deles.
Acima resultou em muitas corrupção de banco de dados e eu tive muita dificuldade em tentar limpar a corrupção. Iniciado com banco de dados de dois usuários e, posteriormente, tempdb e msdb também corrompidos. Tive que reiniciar o serviço para tempdb, no entanto, para msdb restaurado do último backup bem-sucedido e tudo parecia voltar aos negócios em execução.
Em seguida, executou o dbcc checkdb em todos os bancos de dados - sistema e banco de dados do usuário. banco de dados do sistema não teve nenhum problema, no entanto, em um dos bancos de dados do usuário (crítico) está tendo o erro abaixo:
Command: DBCC CHECKDB ([User_DB_Critical]) WITH NO_INFOMSGS, ALL_ERRORMSGS, DATA_PURITY, MAXDOP = 2
Msg 8914, Level 16, State 1, Server DB_Cluster_Name, Line 1
Incorrect PFS free space information for page (1:1439286) in object ID 526624919, index ID 0, partition ID 72057594055753728, alloc unit ID 72057594056933376 (type In-row data). Expected value 95_PCT_FULL, actual value 80_PCT_FULL.
Msg 8951, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: table 'Job_Execution_Log_Table' (ID 526624919). Data row does not have a matching index row in the index 'PK289' (ID 2). Possible missing or invalid keys for the index row matching:
Msg 8955, Level 16, State 1, Server DB_Cluster_Name, Line 1
Data row (1:2224:6) identified by (HEAP RID = (1:2224:6)) with index values 'JOB_NAME = 'populate_Tran_details' and START_TIME = '2019-07-03 03:42:00.323' and HEAP RID = (1:2224:6)'.
Msg 8951, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: table 'Job_Execution_Log_Table' (ID 526624919). Data row does not have a matching index row in the index 'PK289' (ID 2). Possible missing or invalid keys for the index row matching:
Msg 8955, Level 16, State 1, Server DB_Cluster_Name, Line 1
Data row (1:1395530:49) identified by (HEAP RID = (1:1395530:49)) with index values 'JOB_NAME = 'populate_Tran_details' and START_TIME = '2019-07-03 03:41:13.480' and HEAP RID = (1:1395530:49)'.
Msg 8951, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: table 'Job_Execution_Log_Table' (ID 526624919). Data row does not have a matching index row in the index 'PK289' (ID 2). Possible missing or invalid keys for the index row matching:
Msg 8955, Level 16, State 1, Server DB_Cluster_Name, Line 1
Data row (1:1439286:43) identified by (HEAP RID = (1:1439286:43)) with index values 'JOB_NAME = 'populate_Tran_details' and START_TIME = '2019-07-03 03:45:00.890' and HEAP RID = (1:1439286:43)'.
Msg 8951, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: table 'Job_Execution_Log_Table' (ID 526624919). Data row does not have a matching index row in the index 'PK289' (ID 2). Possible missing or invalid keys for the index row matching:
Msg 8955, Level 16, State 1, Server DB_Cluster_Name, Line 1
Data row (1:1439286:44) identified by (HEAP RID = (1:1439286:44)) with index values 'JOB_NAME = 'populate_Tran_details' and START_TIME = '2019-07-03 03:48:00.473' and HEAP RID = (1:1439286:44)'.
Msg 8935, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: Object ID 1374679995, index ID 1, partition ID 72057594120962048, alloc unit ID 72057596467675136 (type In-row data). The previous link (1:1685287) on page (1:491016) does not match the previous page (1:1445099) that the parent (1:232830), slot 129 expects for this page.
Msg 8937, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: Object ID 1374679995, index ID 1, partition ID 72057594120962048, alloc unit ID 72057596467675136 (type In-row data). B-tree page (1:491016) has two parent nodes (0:1), slot 0 and (1:1591622), slot 138.
Msg 8977, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: Object ID 1374679995, index ID 17, partition ID 72057594121093120, alloc unit ID 72057596467806208 (type In-row data). Parent node for page (1:692096) was not encountered.
Msg 8979, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: Object ID 1374679995, index ID 17, partition ID 72057594121093120, alloc unit ID 72057596467806208 (type In-row data). Page (1:692097) is missing references from parent (unknown) and previous (page (1:1548068)) nodes. Possible bad root entry in system catalog.
Msg 8978, Level 16, State 1, Server DB_Cluster_Name, Line 1
Table error: Object ID 1374679995, index ID 1, partition ID 72057594120962048, alloc unit ID 72057596467675136 (type In-row data). Page (1:1623651) is missing a reference from previous page (1:491016). Possible chain linkage problem.
CHECKDB found 0 allocation errors and 5 consistency errors in table 'Job_Execution_Log_Table' (object ID 526624919).
CHECKDB found 0 allocation errors and 5 consistency errors in table 'Tran_details_Table' (object ID 1374679995).
CHECKDB found 0 allocation errors and 10 consistency errors in database 'User_DB_Critical'.
repair_allow_data_loss is the minimum repair level for the errors found by DBCC CHECKDB (User_DB_Critical).
Tamanho da mesa:
Sugeri ao meu gerente que seguisse a abordagem abaixo:
- Tente encontrar a linha que foi inserida naquele momento e, se possível, exclua-a das duas tabelas acima.
- Se a etapa 1 não for possível, reconstrua todos os índices na tabela. A reconstrução requer acesso exclusivo à tabela.
- Se a reconstrução não funcionar – precisaremos descartar e recriar o índice. Isso requer acesso exclusivo à mesa.
- Se a etapa 3 não funcionar, teremos que optar pela opção de reconstrução de reparo. Esta opção requer que todo o banco de dados esteja no modo de usuário único – o que significa que ninguém deve acessar o banco de dados enquanto esta operação estiver em andamento.
- Se a etapa 4 não funcionar - precisaremos ir para a opção repair_allow_data_loss, que é demorada e tem potencial para perder dados com problemas de consistência. Isso novamente exige que o banco de dados esteja no modo de usuário único e ninguém deve acessar o banco de dados.
Eu tenho backup completo do banco de dados pouco antes da atividade, no entanto, a atividade foi planejada na manhã de 3 de julho e, devido à emissão de todo o banco de dados, tornou-se manhã 6h30 no momento em que liberamos toda a corrupção do banco de dados e os negócios começaram a funcionar como de costume. Para msdb e um banco de dados de usuário - usei backup anterior apenas para restauração. Eu executei o checkdb após o horário comercial em 3 de julho, o que significa que o banco de dados contém todos os dados do dia inteiro. Portanto, perderemos todos os dados do dia 3 de julho, se fizermos a restauração do backup de 3 de julho antes da atividade, o que não é aceitável para os negócios.
Adicionando um pouco mais de detalhes sobre o backup - Atualmente estou usando o script ola hallengren para fazer o backup e o backup foi executado com sucesso na noite passada. Abaixo estão os parâmetros que estou usando para fazer backup:
sqlcmd -E -S $(ESCAPE_SQUOTE(SRVR)) -d DBA_Maintenance -Q "EXECUTE [dbo].[DatabaseBackup] @Databases = 'USER_DATABASES, -One_Heavy_Database', @Directory = N'DB_Backup_Path', @BackupType = 'FULL', @Verify = 'Y', @CleanupTime = 24, @CheckSum = 'Y', @Compress = 'Y', @LogToTable = 'Y'" -b
Estou usando o sinalizador verificar e soma de verificação para verificar o backup. O backup diferencial é agendado a cada 2 horas e o backup de log está sendo executado a cada 15 minutos (o envio de log está configurado, mas parado por enquanto) e até agora nenhum backup falhou ou relatou qualquer problema.
Na tabela pesada, 3 erros de consistência estão no índice clusterizado e 2 no índice não clusterizado. Para a primeira tabela, ou seja, Job_Execution_Log_Table tem todas as inconsistências no índice não clusterizado.
Preciso de conselhos sobre como fazer isso e qual deve ser o esforço mais eficaz e demorado para corrigir esse problema de consistência.
Atualmente estou acessando o link de Paul Randal e tentando ver se essa seria a melhor aposta.
EDIT: Eu restaurei o backup do servidor primário para o secundário e executei o checkdb e descobri o mesmo erro de consistência que foi relatado no primário. Índice não clusterizado descartado e recriado, 4 erros de consistência desaparecem e apenas um permanece:
Incorrect PFS free space information for page (1:1439286) in object ID 526624919, index ID 0, partition ID 72057594055753728, alloc unit ID 72057594056933376 (type In-row data). Expected value 95_PCT_FULL, actual value 80_PCT_FULL.
Ainda não tocou na tabela grande, pois está tendo problemas no índice clusterizado. E não sei como corrigir esse problema de PFS.
Aprecie seu conselho.
Versão: Microsoft SQL Server 2014 (SP3) (KB4022619) - 12.0.6024.0 (X64) 7 de setembro de 2018 01:37:51 Copyright (c) Microsoft Corporation Enterprise Edition: Licenciamento baseado em núcleo (64 bits) no Windows NT 6.3 ( Build 9600: ) (Hipervisor)
Esta não é uma resposta direta, mas alguma sugestão
Você não falou sobre a restauração do backup por quê?. Você não tem backup limpo. Você não fez backup completo do banco de dados do usuário e do sistema antes da atividade, se não, isso foi um erro.
Se você tiver backups, comece a restaurar a partir do backup no servidor (com nome diferente) e, em paralelo, verifique se você conseguiu com a etapa 1/2/3. Se você falhar com as etapas no final do dia, você terá seu banco de dados pronto e poderá apontar o aplicativo para isso apenas para evitar o "ruído de gerenciamento".
O checkdb sugerido
repair_allow_data_loss
como reparo mínimo e eu raramente executaria isso no banco de dados de produção, sabendo que ele pode excluir o que quiser, removendo as restrições de negócios, dando-me um banco de dados que é basicamente inútil no que diz respeito às regras de negócios. Portanto, se você não tiver backup e todas as etapas acima falharem, use apenas o reparo e, se estiver processando, Deus esteja com você.EIDT: (do chat)
Obrigado por explicar, então o banco de dados está funcionando no momento, mas o checkdb relatou um problema. Você tem que informar a gestão que há corrupção e mais cedo ou mais tarde eles começariam a enfrentar exceção. A razão pela qual eu acho que eles ainda não encontraram isso é porque a página corrompida ainda não foi lida na memória.
O que você deveria fazer
Informe as partes interessadas que há corrupção, mostre-lhes a mensagem.
Comece a restaurar a partir de qualquer backup que você tenha e talvez seja necessário colocar o aplicativo em somente leitura. Veja quanta diferença existe
Você também pode tentar fazer backup do uso atual do banco de dados corrompido
continue_after_error
se ele falhar. É altamente provável que o backup falhe se houver corrupção. Se você conseguir, restaure-ocontinue_after_error
e execute repair_allow_data_loss para ver quantos dados você perderia.Então você identificou 2 tabelas que estão causando problemas. Tente mover os dados dessas 2 tabelas para alguma outra tabela, veja quantos dados você pode mover (crie uma nova tabela como old_table_temp). O que estou dizendo é que se você conseguir mover a maioria dos dados dessas 2 tabelas e se tiver certeza de que isso é afetado pela corrupção, descarte essas tabelas e recrie-as a partir dos dados que você acabou de mover para outra tabela.
Depois de descartar e recriar a tabela e preenchê-la com novos dados, execute checkdb novamente, veja se ela está limpa.
Do backup restaurado, veja se você pode obter os dados excluídos.
Descartar e recriar o índice provavelmente corrigiria o problema se o índice não estiver clusterizado para o índice clusterizado, ele não corrigirá o problema.
EDITAR:
Uau, você tem o envio de logs e espera que o banco de dados esteja no modo somente leitura / espera, se for muito bom, pare imediatamente todos os trabalhos do LS. Se estiver no modo de restauração e você tiver a edição corporativa, crie um instantâneo e execute o checkdb nele. Pegue o tempo de inatividade do aplicativo, vá em frente e execute o checkdb no banco de dados secundário, se ele ficar limpo, coloque-o online e aponte o aplicativo para este banco de dados, você pode se safar com isso e obter zero perda de dados.
Você pode tentar com o NCI e ver se isso resolve alguma coisa, mas eu confiaria no banco de dados secundário e esperaria que a corrupção não fosse propagada.
Eu sei que é muito trabalho, mas isso é o que acredito que lhe daria a menor perda de dados possível.
Boa sorte