Backup del registro delle transazioni di SQL Server: verifica se il registro di coda segue l'ultimo backup del registro noto


11

Stiamo usando SQL Server con la modalità di recupero completo. Dato un backup completo e una serie di backup del registro, vorremmo essere in grado di verificare se la catena di registro è completa dall'ultimo backup completo al registro di coda corrente. (Senza ripristinare effettivamente questi backup; lo scopo qui è testare la coerenza dei backup.)

So già come farlo per i backup esistenti: utilizzando RESTORE HEADERONLY ottengo il FirstLSN e LastLSN di ogni file, che possono essere confrontati per file consecutivi, al fine di determinare se sono compatibili.

Tuttavia, non so come verificare se il registro di coda segue l'ultimo backup del registro.

Se avessi il FirstLSN del registro di coda, potrei confrontarlo con il LastLSN dell'ultimo backup del registro. Ma come posso ottenere il FirstLSN del registro di coda?

Ho bisogno di una soluzione che funzioni da SQL Server 2005 (idealmente usando t-sql). Finora ho cercato Google senza risultati. Btw. L'ho pubblicato per la prima volta su StackOverflow; ma è migrato qui poiché è stato contrassegnato off-topic lì.

MODIFICARE

Ho provato le due soluzioni fornite su un piccolo esempio (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

Quindi sembra che il primo sia spento di diversi ordini di grandezza.

Ho quindi fatto lo stesso test su SQL 2008 SP1 (10.00.2531), in cui entrambe le query hanno prodotto la risposta corretta.


Ho fatto delle ricerche perché è una domanda interessante, ma non sto andando molto lontano. Non sono sicuro che SQL lo supporti immediatamente.
Katherine Villyard,

1
Sono certo che esiste un modo per verificarlo, forse usare l'LSN non è il modo di farlo. Metterò una taglia sulla domanda tra poche ore, questa domanda ha bisogno di più punti di vista ..

Risposte:


12

Mi sono rivolto alla mia copia di SQL Server 2008 Internals e il DMV sys.database_recovery_status è stato indicato per trovare il primo LSN del successivo backup del registro. Quale andando da BOL la colonna last_log_backup_lsnti fornisce:

Numero di sequenza del registro del backup del registro più recente. Questo è l'LSN finale del backup del registro precedente e l'LSN iniziale del backup del registro successivo.
NULL = Non esiste alcun backup del registro. Il database è offline o il database non si avvia.

Solo per menzionare anche che Kalen evidenzia anche che otterrai un valore NULL se il database è in modalità di recupero SEMPLICE (modalità di autotruncate) o se non esiste alcun backup del registro.

Ma come posso ottenere il FirstLSN del registro di coda?

Senza effettivamente eseguire il backup del registro di coda di un database (non avere un'istanza di prova per provare questo) si potrebbe logicamente concludere che il valore restituito nella colonna menzionata sarebbe il primo LSN del prossimo backup del registro, nel tuo caso il coda.

Quindi l'esecuzione di quanto segue restituirà il valore che credo tu stia cercando:


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

Questo DMV è disponibile a partire da SQL 2005.

MODIFICA
A meno che tu non legga il link BOL, tieni presente che questo DMV restituirà i valori solo ai database online o che verranno aperti come riferimenti BOL. Se si verifica un errore che richiede di eseguire un backup del registro di coda di un database, non sarà possibile verificare questo valore tramite il codice sopra a meno che il database non sia accessibile; che in caso di fallimento probabilmente non lo sarebbe.


Il risultato di questa query sembra essere corretto.
Andreas,

Certamente mi sembra corretto. Last_log_backup_lsn è uguale al primo_lsn della coda del registro. Quindi, se hai un file di registro da ripristinare con last_lsn uguale a last_log_backup_lsn dal codice di Shawn, allora sai che hai un backup fino al registro di coda. (Naturalmente questo è garantito solo al momento della query, il momento successivo potrebbe essere avviato un nuovo backup del registro.)
RLF

@RLF ha aggiunto una nota aggiuntiva perché ciò sarebbe vero anche se il database non fosse accessibile. Non è davvero una soluzione praticabile da utilizzare quando è necessario implementare il piano di ripristino di emergenza. Solo per esercizi da tavolo o test del tuo piano.

6

Qualcosa di simile al seguente dovrebbe farlo.

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

Utilizzo del codice di conversione in decimale da questo articolo .

L' ORDER BY [Current LSN]può ben essere in testa completamente inutile. Non ne sono sicuro. Il risultato di questa funzione sembra sempre essere nell'ordine LSN e immagino che legga il registro in sequenza ma nel caso ...


@MartinSmith: fn_dblognon sembra essere ben documentato. Presumo che i suoi risultati siano sempre validi per il database corrente (poiché non è presente WHERE DbName = 'XXX'nello snippet)?
Andreas,

@Andreas - Sì, non è documentato. E sì, restituisce le informazioni dal registro del database corrente.
Martin Smith,

vedi la mia modifica alla domanda originale. Il numero restituito dallo snippet è molto più grande degli LSN dei backup recenti dello stesso DB.
Andreas,

@Andreas - Strano. L'ho provato solo su un singolo DB di test e ha funzionato correttamente. Non sono sicuro di dove sia l'errore. Su quale versione di SQL Server stai eseguendo questo? Il CONVERTparametro with style 2potrebbe essere il problema.
Martin Smith,

(Anche se la risposta di Shawn sembra decisamente preferibile a questa in ogni caso)
Martin Smith,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.