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


fonte
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.

John Sansom
fonte
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 ...

m4rty
fonte