Reparando páginas inconsistentes no banco de dados


8

Temos um banco de dados SQL 2000. O servidor travou devido a uma falha no array RAID. Agora, quando executamos o DBCC CHECKDB, obtemos um erro indicando que há 27 erros de consistência em 9 páginas.

Quando executamos o DBCC PAGE nessas páginas, obtemos o seguinte:

Msg 8939, Level 16, State 106, Line 1
Table error: Object ID 1397580017, index ID 2, page (1:8404521). Test (m_freeCnt == freeCnt) failed. Values are 2 and 19.
Msg 8939, Level 16, State 108, Line 1
Table error: Object ID 1397580017, index ID 2, page (1:8404521). Test (emptySlotCnt == 0) failed. Values are 1 and 0.

Como o índice indicado não é agrupado em cluster e é criado por uma constante constante que inclui 2 colunas, tentamos descartar e recriar o índice. Isso resultou no seguinte erro:

CREATE UNIQUE INDEX terminated because a duplicate key was found for index ID 2. Most significant primary key is '3280'. 
The statement has been terminated. 

No entanto em execução

Select var_id,result_on
from tests
group by var_id,result_on
having count(*)>1

retorna 0 linhas.

Aqui está o que estamos planejando fazer:

  • Restaure uma cópia de falha anterior ao servidor do banco de dados e execute DBCC CHECKDB
  • Se isso retornar limpo, restaure novamente sem recuperação
  • Aplique todos os backups TLOG subseqüentes
  • Interrompa o aplicativo de produção, faça um backup do log de cauda e aplique-o também
  • Solte o DB do prod e renomeie o DB recentemente restaurado para torná-lo
  • Iniciar aplicativo prod

Alguém poderia fazer furos nessa abordagem? Talvez, sugira uma abordagem diferente? O que precisamos é de um tempo de inatividade mínimo.

SQL 2000 DB Size 94 GB A tabela que possui páginas corrompidas possui 460 milhões + linhas de dados

Obrigado pela ajuda.

Raj


11
Eu gosto da sua abordagem. Faz sentido para mim. Talvez manter o banco de dados danificado ao longo do lado, como o seguro ...
— user24161

Além disso, quando as coisas se acalmarem, o seu plano 2008 ou 2008 atualização :-)
— user24161

(isto é, atualização de 2005 ou 2008)
— user24161

+1 para ter um plano de recuperação válido e muito apropriado
— Andrew

Respostas:


2

Sua solução de recuperação é a maneira de continuar o livro didático. Supondo que você tenha backups apropriados e que você possa fazer backup do log de transações do banco de dados corrompido, sua estratégia é o livro de texto a ser implementado.

Antes de prosseguir, você já considerou a possibilidade de recriar apenas a tabela afetada?

Às vezes, você pode criar uma cópia exata da tabela afetada executando uma

select *
into NewTableFromOld
from DamagedTable

Em seguida, basta soltar / trocar a tabela danificada pela nova, lembrando-se de adicionar restrições e índices apropriados.


Obrigado pela resposta. Sua abordagem parece boa, mas a preocupação é que, considerando que a tabela possui 461 milhões de linhas de dados, qual seria o impacto na produção quando eu seleciono *? Isso não seria um bloqueio e afetaria o desempenho?

Não, se você usar a dica de consulta with (nolock) no. No entanto, convém validar que nada mudou entre a tabela de origem e destino enquanto você tirava a cópia. Provavelmente, isso seria necessário durante a criação da tabela, se você não impedisse o aplicativo de fazer alterações. Haverá sobrecarga de desempenho do disco em uma operação como essa.
— John Sansom

Pessoalmente, eu tentaria essa abordagem primeiro, você pode fazê-lo com a opção nolock para teste, você pode verificar o tempo necessário também. Se funcionar como deveria, eu colocaria o banco de dados no modo de usuário único enquanto o fazia novamente, para garantir que nenhuma alteração ocorra enquanto o processo estiver em execução. O tempo de inatividade será muito menor durante essa abordagem, se funcionar.
— baldy

Se você fizer isso, recomendo criar a tabela primeiro (criando um script para fora da tabela original). Em seguida, use "INSERT INTO newTable SELECT" vs "SELECT INTO". Você pode encontrar problemas de desempenho com um "SELECT INTO".
— SQL3D 14/01

0

Eu tentaria aumentar os dados para arquivar primeiro e depois voltar para uma nova tabela. SELECT INTO não é apropriado (IMO) para esse número de registros ...

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.