Резервне копіювання журналу транзакцій на SQL Server: перевірити, чи відповідає журнал хвоста за останнім відомим резервним копієм журналу


11

Ми використовуємо SQL Server у повному режимі відновлення. З огляду на повне резервне копіювання та серію резервних копій журналу, ми хотіли б мати можливість перевірити, чи є ланцюг журналів завершеним від останнього повного резервного копіювання до поточного журналу хвоста. (Без фактичного відновлення цих резервних копій; мета тут - перевірити узгодженість резервних копій.)

Я вже знаю, як це зробити для існуючих резервних копій: за допомогою RESTORE HEADERONLY я отримую FirstLSN та LastLSN кожного файлу, який можна порівняти для послідовних файлів, щоб визначити, чи сумісні вони.

Однак я не знаю, як перевірити, чи відповідає журнал хвоста за останньою резервною копією журналу.

Якби у мене був FirstLSN хвостового журналу, я міг би порівняти його з LastLSN останньої резервної копії журналу. Але як я можу отримати FirstLSN хвостового журналу?

Мені потрібно рішення, яке працює від SQL Server 2005 вгору (в ідеалі використовуючи t-sql). Поки що я шукав Google безрезультатно. Btw. Я вперше опублікував це на stackoverflow; але перенесли його сюди, оскільки там було позначено поза темою.

EDIT

Я спробував два надані рішення на невеликому прикладі (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

Отож, схоже, перший вимикається на кілька порядків.

Потім я зробив той самий тест на SQL 2008 SP1 (10.00.2531), де обидва запитання дали правильну відповідь.


Я займався деякими дослідженнями, тому що це цікаве питання, але я не заходжу дуже далеко. Я не впевнений, що SQL це підтримує нестандартно.
Кетрін Вільярд

1
Я впевнений, що є спосіб перевірити це, можливо, використання LSN - це не спосіб зробити це. Я поцікавлюся питанням через кілька годин, це питання потребує більше переглядів ..

Відповіді:


12

Я звернувся до своєї копії SQL Server 2008 Internals і DMV sys.database_recovery_status був вказаний, щоб знайти перший LSN наступного резервного копіювання журналу. Що рухається BOL, стовпець last_log_backup_lsnнадає вам:

Послідовний номер журналу останньої резервної копії журналу. Це кінцевий LSN попереднього резервного копіювання журналу та початковий LSN наступного резервного копіювання журналу.
NULL = Немає резервної копії журналу. База даних офлайн або база даних не запуститься.

Зазначимо також, що Kalen також доводить до того, що ви отримаєте значення NULL, якщо база даних перебуває в простому режимі відновлення (режим автозапуску) або якщо не існує резервної копії журналу.

Але як я можу отримати FirstLSN хвостового журналу?

Не фактично створюючи резервну копію хвостового журналу бази даних (у вас немає тестового примірника, щоб це спробувати), ви могли логічно зробити висновок, що значення, що повертається у згаданому стовпці, буде першим LSN наступного резервного копіювання журналу, у вашому випадку хвіст.

Тож виконання наступного поверне значення, на який я вважаю, що ви шукаєте:


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

Цей DMV доступний починаючи з SQL 2005.

EDIT
Якщо ви не прочитали посилання BOL, зауважте, що цей DMV повертає значення лише в базах даних, які є в Інтернеті, або відкриті як посилання на BOL. Якщо виникла помилка, яка вимагає взяти резервну копію журналу хвостів бази даних, ви не зможете перевірити це значення за допомогою наведеного вище коду, якщо база даних не буде доступною; чого в невдачі, мабуть, не було б.


Результат цього запиту видається правильним.
Андреас

Безумовно, мені правильно виглядає. Last_log_backup_lsn дорівнює first_lsn хвоста журналу. Отже, якщо у вас є файл журналу, який слід відновити з last_lsn, рівним last_log_backup_lsn з коду Шона, то ви знаєте, що у вас є резервна копія аж до хвостового журналу. (Звичайно, це справді гарантоване лише на момент запиту, наступного моменту можна буде запустити нове резервне копіювання журналу.)
RLF

@RLF додав додаткову примітку, оскільки це також було б правдою, якщо база даних не буде доступною. Це не дійсно життєздатне рішення, яке потрібно використовувати, коли потрібно реалізувати план відновлення після аварій. Чисто для настільних вправ або тестування свого плану.

6

Щось подібне повинно це зробити.

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

Використання коду перетворення для десяткової від цієї статті .

ORDER BY [Current LSN]Цілком може бути абсолютно непотрібним над головою. Я не впевнений. Результат цієї функції завжди здається в порядку LSN, і я думаю, що він просто читає журнал послідовно, але про всяк випадок ...


@MartinSmith: fn_dblogце, здається, не дуже добре документоване. Я припускаю, що його результати завжди відповідають справжній базі даних (оскільки її немає WHERE DbName = 'XXX'в фрагменті)?
Андреас

@Andreas - Так, це недокументовано. І так, вона повертає інформацію з журналу поточної бази даних.
Мартін Сміт

дивіться мою редакцію до оригінального питання. Кількість, повернута вашим фрагментом, набагато більша, ніж LSN останніх резервних копій тієї ж БД.
Андреас

@Andreas - Дивно. Я спробував це лише на одному тестовому БД, і він працював правильно. Не впевнений, де помилка. На якій версії SQL Server це запущено? Параметр CONVERTstyle 2може бути проблемою.
Мартін Сміт

(Хоча відповідь Шона все-таки здається значно кращою для цієї)
Мартін Сміт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.