web-dev-qa-db-fra.com

Sauvegarde de la transaction SQL Server: Testez si la journalisation de la queue suit la dernière sauvegarde de journal connue

Nous utilisons SQL Server en mode de récupération complète. Compte tenu d'une sauvegarde complète et d'une série de sauvegardes de journal, nous souhaitons pouvoir vérifier si la chaîne de journal est terminée à partir de la dernière sauvegarde complète au journal de la queue en cours. (Sans restaurer ces sauvegardes; le but ici est de tester la cohérence des sauvegardes.)

Je sais déjà comment procéder à cela pour les sauvegardes existantes: Utilisation de la restauration Headeronly, je reçois le fichier FirstLsn et LastLSn de chaque fichier, qui peut être comparé aux fichiers consécutifs, afin de déterminer s'ils sont compatibles.

Cependant, je ne sais pas comment vérifier si le journal de la queue suit la dernière sauvegarde du journal.

Si j'avais le premier journal de la queue, je pouvais le comparer à la LastLsn de la dernière sauvegarde du journal. Mais comment puis-je obtenir le premier journal de la queue?

J'ai besoin d'une solution qui fonctionne à partir de SQL Server 2005 à la hausse (idéalement à l'aide de T-SQL). Jusqu'à présent, j'ai cherché Google en vain. D'ailleurs. J'ai d'abord posté ceci sur Stackoverflow; Mais l'a migré ici puisqu'il a été signalé sur le sujet.

ÉDITER

J'ai essayé les deux solutions fournies sur un petit exemple (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

Donc, il semble que le premier est désactivé par plusieurs ordres de grandeur.

J'ai ensuite fait le même test sur SQL 2008 SP1 (10.00.2531), où les deux requêtes ont donné la bonne réponse.

11
Andreas

Je me suis tourné vers ma copie de Internals SQL Server 2008 et le DMV sys.database_recovery_status a été signalé pour rechercher le premier LSN de la sauvegarde de journal suivante. Qui va en bol la colonne last_log_backup_lsn vous fournit:

Numéro de séquence de journal de la sauvegarde de journal la plus récente. Ceci est le lsn de fin de la sauvegarde du journal précédent et la LSN de départ de la sauvegarde de journal suivante.
NULL = Aucune sauvegarde de journal existe. La base de données est hors ligne ou la base de données ne démarre pas.

Juste pour mentionner que Kalen soulève également le point que vous obtiendrez une valeur null si la base de données est en mode de récupération simple (mode Autotrunate) ou si aucune sauvegarde de journal n'existe.

Mais comment puis-je obtenir le premier journal de la queue?

Sans réellement sauvegarder le journal de la queue d'une base de données (ne pas avoir d'instance de test pour essayer cela), vous pouvez conclure logiquement que la valeur renvoyée dans la colonne mentionnée serait la première LSN de la sauvegarde de journal suivante, dans votre cas. queue.

Donc, l'exécution des éléments suivants retournera la valeur que je crois que vous recherchez:


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

Ce DMV est disponible à partir de SQL 2005.

[~ # ~] Edit [~ # ~ #]
[.____] Sauf si vous lisez le lien BOL, veuillez noter que ce DMV ne renvoie que les valeurs aux bases de données en ligne ou ouvertes sous forme de référence. Si une défaillance survient, cela nécessite que vous preniez une sauvegarde de la queue d'une base de données, vous ne pourrez pas vérifier cette valeur via le code ci-dessus, à moins que la base de données soit accessible; qui dans une défaillance, ce ne serait probablement pas.

12
user507

Quelque chose comme ce qui suit devrait le faire.

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

Utilisation du code de conversion en décimal de cet article .

Le ORDER BY [Current LSN] Peut bien être des frais généraux complètement inutiles. Je ne suis pas sûr. Le résultat de cette fonction semble toujours être dans la commande LSN et je suppose que cela lit simplement le journal séquentiellement, mais juste au cas où ...

6
Martin Smith