Eu tenho uma situação que não é fácil de descobrir e pensei em perguntar neste fórum se outras pessoas poderiam ter sugestões.
Estou executando o SQL Server 2008 R2 Standard SP3 no Windows Server 2008R2 Enterprise.
Um banco de dados precisava de manutenção e, após o fato, precisei restaurar em outro servidor. Eu tenho um backup de banco de dados completo feito com COPY_ONLY mais um conjunto de 4 backups de tlog.
- antes de começar, crie tlogbackup1
- mudar
FULL
paraBULK_LOGGED
o modelo de recuperação - adicionar novo grupo de arquivos
- adicionar arquivo ao novo grupo de arquivos
- definir newfilegroup como padrão
- selecione na tabela (no novo grupo de arquivos)
- descartar tabela original
- excluir arquivo original
- excluir grupo de arquivos original
- alterar o nome da nova tabela para corresponder à tabela original
- altere o nome do arquivo do novo grupo de arquivos para corresponder ao grupo de arquivos original
- alterar o nome do arquivo no catálogo para corresponder ao nome do arquivo original
- altere o nome do arquivo no nível do sistema operacional para corresponder ao nome do arquivo original
- defina o grupo de arquivos padrão como o original
- trazer banco de dados online
- mudar
BULK_LOGGED
paraFULL
o modelo de recuperação - Depois que todas as etapas forem concluídas, crie tlogbackup2
A restauração de todos os backups deve usar WITH MOVE, devido a alterações na letra da unidade no servidor de restauração.
Etapas de recuperação:
RESTORE database SomeDB FROM DISK = 'D:\REPRO\SomeDB.bak'
WITH
MOVE 'SystemData' TO 'D:\SQLDATA\SomeDB.mdf'
,MOVE 'SystemDataPDS' TO 'D:\SqlData\SomeDB.ndf'
,MOVE 'SystemData_log' TO 'D:\SQLLogs\SomeDB.LDF'
,NORECOVERY
,stats = 1
RESTORE LOG SomeDB FROM DISK = 'D:\REPRO\tlogbackup1.trn'
WITH
MOVE 'SystemData' TO 'D:\SQLDATA\SomeDB.mdf'
,MOVE 'SystemDataPDS' TO 'D:\SqlData\SomeDB.ndf'
,MOVE 'SystemData_log' TO 'D:\SQLLogs\SomeDB.LDF'
,NORECOVERY
,stats = 1
RESTORE LOG SomeDB FROM DISK = 'D:\REPRO\tlogbackup2.trn'
WITH
MOVE 'SystemData' TO 'D:\SQLDATA\SomeDB.mdf'
,MOVE 'SystemDataPDS' TO 'D:\SqlData\SomeDB.ndf'
,MOVE 'SystemData_log' TO 'D:\SQLLogs\SomeDB.LDF'
,NORECOVERY
,stats = 1
A restauração final do tlog chega a 100% e falha com o erro 3456:
368 páginas processadas para o banco de dados 'SomeDB', arquivo 'SystemData' no arquivo 1.
7656520 páginas processadas para o banco de dados 'SomeDB', arquivo 'SystemDataPDS' no arquivo 1.
172430 páginas processadas para o banco de dados 'SomeDB', arquivo 'SystemData_log' no arquivo 1.
Msg 3456, Nível 16, Estado 1, Linha 1
Não foi possível refazer o registro de log (210388:123648:232), para ID da transação (0:1016710921), na página (4:8088), banco de dados 'SomeDB' (ID do banco de dados 6) . Página: LSN = (0:0:1), digite = 11. Log: OpCode = 4, contexto 11, PrevPageLSN: (210388:122007:1). Restaure a partir de um backup do banco de dados ou repare o banco de dados. Msg 3013, Nível 16, Estado 1, Linha 1 RESTORE LOG está terminando de forma anormal.
Apenas para verificar se o backup completo do banco de dados estava ok, restaurei, executei CHECKDB
e não houve erros.
Todos os comentários são bem-vindos.
Desde já, obrigado,
Ned Otter
Para entender por que o erro 3456 seria lançado, precisamos dar um pequeno passo para trás e entender como o SQL Server lida com esse canto da recuperação.
Quando o SQL Server está refazendo uma operação, e esse refazer é uma modificação de página, ele faz uma verificação rápida. No cabeçalho da página, por fim, haverá um
PageLSN
, que é uma indicação do último LSN que modificou essa página, registrado pela página. Pense assim, a página mantém o registro do último LSN que fez modificações nela. Este é o arquivoPageLSN
.Sempre que há uma operação de modificação de página registrada, esse registro de log inclui alguns LSNs. Ou seja, o LSN do registro de log (pense ... LSN atual ) e, em seguida, ele tem o que é chamado de LSN da página anterior (
PrevPageLSN
daqui para frente). Portanto, quando modificamos uma página, um dos dados inseridos no registro de log é o que a página indica como sendo o último LSN antes de você ter modificado a página .Pense assim... Seu carro precisa ser reparado. O mecânico John trabalha em seu carro, e no compartimento do motor há uma pequena etiqueta e o mecânico John escreve "John trabalhou neste carro por último". Então, da próxima vez que você levar seu carro a outra oficina, o Mecânico Mark olha no compartimento do motor e vê que o Mecânico John trabalhou neste carro por último. Em sua folha de dados, ele escreve essas informações. Mesma ideia com o SQL Server.
Isso pode ser um pouco confuso, então dê uma olhada nesta imagem abaixo em modificações de página sequenciais e como
PageLSN
ePrevPageLSN
se relacionam:Vamos voltar, pois tudo isso entra em jogo quando você precisa refazer uma operação em uma página (restaurações, recuperação, HA, etc.). Quando o SQL Server precisa refazer uma operação de página, ele faz uma verificação de sanidade para ver se o
PageLSN
na página corresponde aoPrevPageLSN
que o registro de log inclui. Se isso não for igual, você verá o erro 3456 ser lançado.PageLSN é igual a PrevPageLSN ? Não??? Pare e aumente o erro 3456...
Vamos analisar sua mensagem de erro, que inclui como:
Coloquei em negrito os dois dados que possuem uma desigualdade causando o erro. Você pode ver que nosso
PageLSN
é 0:0:1 (isso foi encontrado no cabeçalho da página) e nossoPrevPageLSN
é 210388:122007:1 (isso foi encontrado nos dados do registro de log que estava tentando ser refeito). Obviamente, eles não são iguais, portanto, err3456.Portanto, para descobrir o porquê desse evento, seria necessário descobrir por que há uma disparidade aqui. Realmente precisamos rastrear o ciclo de vida da página 4:8088 e ver onde está a desconexão. Infelizmente, sem mais informações ou solução de problemas prática, não há muito mais que eu possa fazer além de fornecer o histórico dessa operação de recuperação e o que causa o erro.