Backups de log de transações do SQL Server: teste se o log de cauda segue o último backup de log conhecido

11

Estamos usando o SQL Server com o modo de recuperação completa. Dado um backup completo e uma série de backups de log, gostaríamos de poder verificar se a cadeia de logs está completa desde o último backup completo até o log de cauda atual. (Sem realmente restaurar esses backups; o objetivo aqui é testar a consistência dos backups.)

Eu já sei como fazer isso para os backups existentes: usando RESTORE HEADERONLY, obtenho o FirstLSN e LastLSN de todos os arquivos, que podem ser comparados com arquivos consecutivos, para determinar se são compatíveis.

No entanto, não sei como verificar se o log de cauda segue o último backup de log.

Se eu tivesse o FirstLSN do log de cauda, ​​poderia compará-lo ao LastLSN do último backup de log. Mas como posso obter o FirstLSN do registro de cauda?

Preciso de uma solução que funcione a partir do SQL Server 2005 (idealmente usando t-sql). Até agora, pesquisei no Google sem sucesso. Btw. A primeira vez que publiquei isso no stackoverflow; mas migrou para aqui, pois foi sinalizado como fora de tópico.

EDITAR

Tentei as duas soluções fornecidas em um pequeno exemplo (SQL Server 2005, 9.0.5057):

BACKUP DATABASE TestDb TO DISK = 'C:\temp\backup test\Full.bak' 

-- fire some update queries

BACKUP LOG TestDb TO DISK =  'C:\temp\backup test\Log1.bak' 

-- fire both queries from the provided answers: 
-- Martin Smith's answer yields: 838886656088920652852608
-- Shawn Melton's answer yields: 46000000267600001

RESTORE HEADERONLY FROM DISK = 'C:\temp\backup test\Log1.bak'  
-- yields: 46000000267600001

Então parece que o primeiro está desligado por várias ordens de magnitude.

Fiz o mesmo teste no SQL 2008 SP1 (10.00.2531), em que ambas as consultas renderam a resposta correta.

Andreas
fonte
Venho pesquisando porque é uma pergunta interessante, mas não estou indo muito longe. Não tenho certeza se o SQL suporta isso imediatamente.
Katherine Villyard
1
Estou certo de que existe uma maneira de verificar isso, talvez usando o LSN não seja o caminho. Vou colocar uma recompensa sobre a questão em poucas horas, esta questão precisa de mais vistas ..

Respostas:

12

Virei para minha cópia do SQL Server 2008 Internals e o DMV sys.database_recovery_status foi indicado para encontrar o primeiro LSN do próximo backup de log. Na coluna BOL, a coluna last_log_backup_lsnfornece:

Número de sequência do log do backup de log mais recente. Esse é o LSN final do backup de log anterior e o LSN inicial do próximo backup de log.
NULL = Não existe backup de log. O banco de dados está offline ou o banco de dados não será iniciado.

Apenas para mencionar também que o Kalen também menciona que você obterá um valor NULL se o banco de dados estiver no modo de recuperação SIMPLES (modo de truncamento automático) ou se não houver backup de log.

Mas como posso obter o FirstLSN do registro de cauda?

Sem realmente fazer o backup do log de cauda de um banco de dados (não tenha uma instância de teste para testar isso), você poderia concluir logicamente que o valor retornado na coluna mencionada seria o primeiro LSN do próximo backup de log, no seu caso o rabo.

Portanto, a execução do seguinte retornará o valor que acredito estar procurando:


SELECT 
   last_log_backup_lsn
FROM 
   sys.database_recovery_status
WHERE 
   databse_id = DB_ID('MyDb')

Este DMV está disponível a partir do SQL 2005.

EDITAR
A menos que você leia o link BOL, observe que este DMV retornará apenas valores para bancos de dados que estão online ou abertos como BOL faz referência a ele. Se ocorrer uma falha que exija que você faça um backup do log de cauda de um banco de dados, não poderá verificar esse valor através do código acima, a menos que o banco de dados esteja acessível; que em um fracasso provavelmente não seria.


fonte
O resultado desta consulta parece estar correto.
Andreas
Certamente parece correto para mim. O last_log_backup_lsn é igual ao first_lsn da cauda do log. Portanto, se você tiver um arquivo de log a ser restaurado com um last_lsn igual ao last_log_backup_lsn do código de Shawn, você saberá que possui um backup até o final do registro. (É claro que isso só é garantido no momento da consulta, no próximo momento em que um novo backup de log possa ser iniciado.) #
27513 RLF
O @RLF adicionou uma observação adicional porque isso também seria verdadeiro se o banco de dados não estiver acessível. Não é realmente uma solução viável a ser usada quando é necessário implementar seu plano de recuperação de desastres. Puramente para exercícios de mesa ou para testar seu plano.
6

Algo como o seguinte deve fazê-lo.

WITH LSN_CTE
AS
(
SELECT TOP 1
       LEFT( LogRecords.[Current LSN], 8 )          AS Part1,
       SUBSTRING( LogRecords.[Current LSN], 10, 8 ) AS Part2,
       RIGHT( LogRecords.[Current LSN], 4 )         AS Part3
FROM   sys.fn_dblog(NULL,NULL) AS LogRecords
ORDER BY [Current LSN]
)
SELECT CAST( CAST( CONVERT( varbinary, Part1, 2 ) AS int ) AS varchar ) +
       RIGHT( '0000000000' + CAST( CAST( CONVERT( varbinary, Part2, 2 ) AS int ) AS varchar ), 10 ) +
       RIGHT( '00000'      + CAST( CAST( CONVERT( varbinary, Part3, 2 ) AS int ) AS varchar ), 5 ) AS [Converted LSN]
FROM   LSN_CTE

Usando o código de conversão para decimal deste artigo .

A ORDER BY [Current LSN]sobrecarga pode ser completamente desnecessária. Não tenho certeza. O resultado dessa função sempre parece estar na ordem do LSN e acho que apenas lê o log sequencialmente, mas apenas no caso ...

Martin Smith
fonte
@ MartinSmith: fn_dblognão parece estar muito bem documentado. Presumo que seus resultados sempre sejam válidos para o banco de dados atual (já que não há WHERE DbName = 'XXX'no snippet)?
Andreas
@ Andréas - Sim, não é documentado. E sim, ele retorna as informações do log do banco de dados atual.
Martin Smith
veja minha edição da pergunta original. O número retornado pelo seu snippet é muito maior que os LSNs dos backups recentes do mesmo banco de dados.
Andreas
@Andreas - Strange. Eu tentei apenas em um único banco de dados de teste e funcionou corretamente. Não tenho certeza onde está o erro. Em qual versão do SQL Server você está executando isso? O CONVERTparâmetro with style 2pode ser o problema.
Martin Smith
(Resposta da Embora Shawn parece maciçamente preferível a esta um de qualquer maneira)
Martin Smith