SQL Server-Transaktionsprotokollsicherungen: Testen Sie, ob das Endprotokoll der letzten bekannten Protokollsicherung folgt

11

Wir verwenden SQL Server mit vollständigem Wiederherstellungsmodus. Bei einer vollständigen Sicherung und einer Reihe von Protokollsicherungen möchten wir überprüfen können, ob die Protokollkette von der letzten vollständigen Sicherung bis zum aktuellen Endprotokoll vollständig ist. (Ohne diese Sicherungen tatsächlich wiederherzustellen. Der Zweck hier besteht darin, die Konsistenz der Sicherungen zu testen.)

Ich weiß bereits, wie dies für die vorhandenen Sicherungen gemacht wird: Mit RESTORE HEADERONLY erhalte ich den FirstLSN und LastLSN jeder Datei, die für aufeinanderfolgende Dateien verglichen werden können, um festzustellen, ob sie kompatibel sind.

Ich weiß jedoch nicht, wie ich überprüfen soll, ob das Endprotokoll der letzten Protokollsicherung folgt.

Wenn ich den FirstLSN des Endprotokolls hätte, könnte ich ihn mit dem LastLSN der letzten Protokollsicherung vergleichen. Aber wie kann ich den FirstLSN des Endprotokolls erhalten?

Ich benötige eine Lösung, die ab SQL Server 2005 funktioniert (idealerweise mit t-sql). Bisher habe ich vergeblich bei Google gesucht. Übrigens. Ich habe dies zuerst auf stackoverflow gepostet. aber migrierte es hierher, da es dort als Off-Topic markiert wurde.

BEARBEITEN

Ich habe die beiden bereitgestellten Lösungen anhand eines kleinen Beispiels ausprobiert (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

Es scheint also, dass der erste um mehrere Größenordnungen abweicht.

Ich habe dann den gleichen Test mit SQL 2008 SP1 (10.00.2531) durchgeführt, wobei beide Abfragen die richtige Antwort ergaben.

Andreas
quelle
Ich habe einige Nachforschungen angestellt, weil es eine interessante Frage ist, aber ich komme nicht sehr weit. Ich bin nicht sicher, ob SQL dies sofort unterstützt.
Katherine Villyard
1
Ich bin mir sicher, dass es eine Möglichkeit gibt, dies zu überprüfen. Vielleicht ist die Verwendung des LSN nicht der richtige Weg, dies zu tun. Ich werde in ein paar Stunden ein Kopfgeld auf die Frage setzen, diese Frage braucht mehr Ansichten.

Antworten:

12

Ich habe mich an meine Kopie von SQL Server 2008 Internals gewandt, und auf die DMV sys.database_recovery_status wurde hingewiesen, um die erste LSN der nächsten Protokollsicherung zu finden. Welche von BOL die Spalte last_log_backup_lsnbietet Ihnen:

Protokollsequenznummer der letzten Protokollsicherung. Dies ist die End-LSN der vorherigen Protokollsicherung und die Start-LSN der nächsten Protokollsicherung.
NULL = Es ist keine Protokollsicherung vorhanden. Die Datenbank ist offline oder die Datenbank wird nicht gestartet.

Um nur zu erwähnen, dass Kalen auch den Punkt anspricht, dass Sie einen NULL-Wert erhalten, wenn sich die Datenbank im EINFACHEN Wiederherstellungsmodus (Autotruncate-Modus) befindet oder wenn keine Protokollsicherung vorhanden ist.

Aber wie kann ich den FirstLSN des Endprotokolls erhalten?

Ohne das Endprotokoll einer Datenbank tatsächlich zu sichern (Sie haben keine Testinstanz, um dies anzuprobieren), könnten Sie logischerweise den Schluss ziehen, dass der in der genannten Spalte zurückgegebene Wert die erste LSN der nächsten Protokollsicherung ist, in Ihrem Fall die Schwanz.

Wenn Sie also Folgendes ausführen, wird der Wert zurückgegeben, nach dem Sie meiner Meinung nach suchen:


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

Diese DMV ist ab SQL 2005 verfügbar.

BEARBEITEN
Wenn Sie den BOL-Link nicht lesen, beachten Sie bitte, dass diese DMV nur Werte an Datenbanken zurückgibt, die online sind oder geöffnet werden, wenn BOL darauf verweist. Wenn ein Fehler auftritt, bei dem Sie eine Endprotokollsicherung einer Datenbank durchführen müssen, können Sie diesen Wert nur anhand des obigen Codes überprüfen, wenn auf die Datenbank zugegriffen werden kann. was bei einem Ausfall wahrscheinlich nicht der Fall wäre.


quelle
Das Ergebnis dieser Abfrage scheint korrekt zu sein.
Andreas
Sieht für mich sicher richtig aus. Das last_log_backup_lsn entspricht dem first_lsn des Endes des Protokolls. Wenn Sie also eine Protokolldatei haben, die mit einem last_lsn wiederhergestellt werden soll, der dem last_log_backup_lsn aus Shawns Code entspricht, wissen Sie, dass Sie eine Sicherung bis zum Endprotokoll haben. (Natürlich ist dies nur im Moment der Abfrage garantiert wahr, im nächsten Moment könnte eine neue Protokollsicherung gestartet werden.)
RLF
@RLF hat einen zusätzlichen Hinweis hinzugefügt, da dies auch dann zutrifft, wenn auf die Datenbank nicht zugegriffen werden kann. Es ist keine wirklich praktikable Lösung, wenn Sie Ihren Disaster Recovery-Plan implementieren müssen. Nur für Tischübungen oder zum Testen Ihres Plans.
6

So etwas wie das Folgende sollte es tun.

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

Verwenden des Konvertierungscodes zur Dezimalstelle aus diesem Artikel .

Der ORDER BY [Current LSN]Aufwand kann durchaus völlig unnötig sein. Ich bin mir nicht sicher. Das Ergebnis dieser Funktion scheint immer in LSN-Reihenfolge zu sein, und ich denke, sie liest das Protokoll nur nacheinander, aber nur für den Fall ...

Martin Smith
quelle
@ MartinSmith: fn_dblogscheint nicht sehr gut dokumentiert zu sein. Ich gehe davon aus, dass die Ergebnisse immer für die aktuelle Datenbank gelten (da WHERE DbName = 'XXX'das Snippet keine enthält ).
Andreas
@Andreas - Ja, es ist nicht dokumentiert. Und ja, es gibt die Informationen aus dem Protokoll der aktuellen Datenbank zurück.
Martin Smith
siehe meine Bearbeitung der ursprünglichen Frage. Die von Ihrem Snippet zurückgegebene Anzahl ist viel größer als die LSNs der letzten Sicherungen derselben Datenbank.
Andreas
@Andreas - Seltsam. Ich habe es nur mit einer einzigen Test-DB versucht und es hat richtig funktioniert. Ich bin mir nicht sicher, wo der Fehler liegt. Auf welcher Version von SQL Server wird dies ausgeführt? Der CONVERTParameter with style 2könnte das Problem sein.
Martin Smith
(Obwohl Shawns Antwort sowieso massiv vorzuziehen scheint)
Martin Smith