Sql-Server

完整備份後,系統如何知道從事務日誌備份中恢復哪些事務?

  • October 10, 2018

完全備份不會截斷事務日誌文件。

假設以下場景

  1. 早上 6 點完全備份
  2. 上午 10 點備份 TLog
  3. 下午 1 點完全備份
  4. 下午 6 點備份 TLog
  5. 下一秒立即崩潰(因此不需要尾日誌備份)

恢復步驟:

  • 從第 3 點恢復完整備份(包含截至下午 1 點的數據)
  • 然後,從第 4 步恢復 tlog 備份(包含從上午 10 點到下午 6 點的日誌)

問題

  • 在恢復期間,系統如何知道只有日誌文件的某些部分(下午 1 點後$$ exclude 10AM to 1PM $$) 需要在數據庫上重播嗎?
  • 它是否檢查事務日誌備份中的時間戳以將其與完整備份進行比較?還是檢查 LSN?

附加場景

同樣,在另一種情況下,假設我們在上午 10 點進行完整備份,然後在下午 12 點進行事務日誌備份。事務日誌將包含截至下午 12 點的所有事務(甚至在上午 10 點之前,假設 db 存在於上午 10 點之前並且沒有以前的事務日誌備份)。

現在,當我們恢復完整備份然後應用事務日誌備份時,系統如何知道只有上午 10 點後的日誌中的事務需要重播?由於上午 10 點之前的所有這些都將作為完整備份還原的一部分已經存在。它是通過時間戳還是 LSN 檢查的?

每個還原操作(在某些方面)都依賴於與備份一起儲存在msdb數據庫內部的 LSN。

涵蓋基礎知識

從一些微軟文件:

強調我的)

LSN 在 RESTORE 序列期間內部使用,以跟踪數據已恢復到的時間點。**恢復備份時,數據會恢復到與進行備份的時間點對應的 LSN。**差異和日誌備份將恢復的數據庫推進到較晚的時間,這對應於更高的 LSN。

事務日誌中的每條記錄都由日誌序列號 (LSN) 唯一標識。LSN 是這樣排序的,如果 LSN2 大於 LSN1,則 LSN2 所引用的日誌記錄所描述的更改發生在日誌記錄 LSN 所描述的更改之後。

發生重大事件的日誌記錄的 LSN 可用於建構正確的恢復序列。因為 LSN 是有序的,所以可以比較它們是否相等(即 <、>、=、<=、>=)。這種比較在建構恢復序列時很有用。

參考: 恢復到日誌序列號(Microsoft | Docs | SQL Server)

在閱讀了一些循環之後,您最終將登陸SQL Server 事務日誌體系結構和管理指南的 Microsoft 文件頁面

強調我的)

SQL Server 事務日誌的邏輯操作就像事務日誌是一串日誌記錄一樣。**每個日誌記錄由一個日誌序列號 (LSN) 標識。每條新的日誌記錄都被寫入日誌的邏輯末尾,其 LSN 高於之前記錄的 LSN。**日誌記錄在創建時按順序儲存。每條日誌記錄都包含其所屬事務的 ID。對於每個事務,與事務關聯的所有日誌記錄都使用反向指針單獨連結在一個鏈中,這些指針可以加速事務的回滾。

參考: SQL Server 事務日誌架構和管理指南(Microsoft | Docs | SQL Server)

進入系統

當您msdb使用我為自己的目的創建的腳本查詢數據庫時,您將收到與 FULL、DIFF 和 TLOG 備份一起儲存的相關 LSN 編號的概述。

SELECT  
/* Columns for retrieving information */
  msdb.dbo.backupset.database_name,  
  msdb.dbo.backupset.backup_start_date,  
  msdb.dbo.backupset.backup_finish_date, 
  -- msdb.dbo.backupset.expiration_date, 
  CASE msdb..backupset.type  
      WHEN 'D' THEN 'Full'  
      WHEN 'I' THEN 'Diff'
      WHEN 'L' THEN 'Log'  
  END AS backup_type,  
  -- msdb.dbo.backupset.backup_size / 1024 / 1024 as [backup_size MB],  
  -- msdb.dbo.backupmediafamily.device_type,
  msdb.dbo.backupmediafamily.physical_device_name,
  -- msdb.dbo.backupmediafamily.logical_device_name,
  -- msdb.dbo.backupset.name AS backupset_name, 
  -- msdb.dbo.backupset.description,
  msdb.dbo.backupset.is_copy_only,
  msdb.dbo.backupset.is_snapshot,   
  msdb.dbo.backupset.first_lsn,
  msdb.dbo.backupset.last_lsn,
  msdb.dbo.backupset.database_backup_lsn,
  msdb.dbo.backupset.checkpoint_lsn,
  msdb.dbo.backupset.differential_base_lsn,
  msdb.dbo.backupset.fork_point_lsn,
  msdb.dbo.backupmediaset.name,
  msdb.dbo.backupmediaset.software_name,
  msdb.dbo.backupset.user_name,
  'EOR'

FROM   msdb.dbo.backupmediafamily  
  INNER JOIN msdb.dbo.backupset 
  ON msdb.dbo.backupmediafamily.media_set_id = msdb.dbo.backupset.media_set_id  
  INNER JOIN msdb.dbo.backupmediaset
  on msdb.dbo.backupmediaset.media_set_id = backupmediafamily.media_set_id


/* ----------------------------------------------------------------------------
       Generic WHERE statement to simplify selection of more WHEREs    
-------------------------------------------------------------------------------*/
WHERE 1 = 1
AND     database_name IN ('&lt;name_of_your_database&gt;')

這將使您了解儲存在備份文件中的 LSN。msdb不包含備份中所有 LSN 的完整列表,而僅包含對手動還原數據庫至關重要的主要 LSN :

  • msdb.dbo.backupset.first_lsn
  • msdb.dbo.backupset.last_lsn
  • msdb.dbo.backupset.database_backup_lsn
  • msdb.dbo.backupset.checkpoint_lsn
  • msdb.dbo.backupset.differential_base_lsn
  • msdb.dbo.backupset.fork_point_lsn

這些列的描述可以在該backupset表的官方 Microsoft 文件中找到。

我的 StackExchange 數據庫的範例輸出

database_name  backup_start_date  backup_finish_date                           backup_type physical_device_name                                                    is_copy_only   is_snapshot  first_lsn            last_lsn            database_backup_lsn  checkpoint_lsn     differential_base_lsn  fork_point_lsn  name  software_name       user_name                  (No column name)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
StackExchange  2018-09-15         16:15:01.000        2018-09-15 16:15:01.000  Log         C:\SQL\Backup\StackExchange\LOG\StackExchange_LOG_20180915_161501.trn   0              0             286000001068100001  286000001068400001  286000001016900037  286000001063000002  NULL                  NULL            NULL  Microsoft SQL Server  NT SERVICE\SQLSERVERAGENT  EOR
StackExchange  2018-09-15         17:15:01.000        2018-09-15 17:15:01.000  Log         C:\SQL\Backup\StackExchange\LOG\StackExchange_LOG_20180915_171501.trn   0              0             286000001068400001  286000001068700001  286000001016900037  286000001063000002  NULL                  NULL            NULL  Microsoft SQL Server  NT SERVICE\SQLSERVERAGENT  EOR
StackExchange  2018-09-15         18:15:01.000        2018-09-15 18:15:01.000  Log         C:\SQL\Backup\StackExchange\LOG\StackExchange_LOG_20180915_181501.trn   0              0             286000001068700001  286000001069000001  286000001016900037  286000001063000002  NULL                  NULL            NULL  Microsoft SQL Server  NT SERVICE\SQLSERVERAGENT  EOR
StackExchange  2018-09-15         19:15:01.000        2018-09-15 19:15:01.000  Log         C:\SQL\Backup\StackExchange\LOG\StackExchange_LOG_20180915_191501.trn   0              0             286000001069000001  286000001069300001  286000001016900037  286000001063000002  NULL                  NULL            NULL  Microsoft SQL Server  NT SERVICE\SQLSERVERAGENT  EOR
StackExchange  2018-09-15         20:15:01.000        2018-09-15 20:15:01.000  Log         C:\SQL\Backup\StackExchange\LOG\StackExchange_LOG_20180915_201501.trn   0              0             286000001069300001  286000001069600001  286000001016900037  286000001063000002  NULL                  NULL            NULL  Microsoft SQL Server  NT SERVICE\SQLSERVERAGENT  EOR
StackExchange  2018-09-15         21:15:01.000        2018-09-15 21:15:01.000  Log         C:\SQL\Backup\StackExchange\LOG\StackExchange_LOG_20180915_211501.trn   0              0             286000001069600001  286000001070800001  286000001016900037  286000001070100001  NULL                  NULL            NULL  Microsoft SQL Server  NT SERVICE\SQLSERVERAGENT  EOR
StackExchange  2018-09-15         22:15:01.000        2018-09-15 22:15:01.000  Log         C:\SQL\Backup\StackExchange\LOG\StackExchange_LOG_20180915_221501.trn   0              0             286000001070800001  286000001071100001  286000001016900037  286000001070100001  NULL                  NULL            NULL  Microsoft SQL Server  NT SERVICE\SQLSERVERAGENT  EOR
StackExchange  2018-09-15         22:30:06.000        2018-09-15 22:30:06.000  Full        C:\SQL\Backup\StackExchange\FULL\StackExchange_FULL_20180915_223006.bak 0              0             286000001071600037  286000001073300001  286000001016900037  286000001071600037  NULL                  NULL            NULL  Microsoft SQL Server  NT SERVICE\SQLSERVERAGENT  EOR

確切的 LSN 儲存在備份文件本身中,並且可以使用 3-rd 方工具進行檢索。

回答您的問題

…對於簡訊服務

當您開始恢復過程時,會在後台執行一些語句,這會導致 GUI 向您提供 FULL、DIFF 和 TLOG 備份的概述,這些備份是使您的數據庫恢復到一致狀態所需的。根據前面提到的文件,實際RESTORE DATABASE ...並將隨後確定需要相應備份文件的哪些部分才能使數據庫恢復到一致狀態。RESTORE LOG ...

…對於 Transact-SQL

當您必須手動恢復數據庫時,您將不得不查看msdb數據庫(可能在我的腳本的幫助下)以確定需要哪些文件才能使數據庫恢復到一致狀態。根據前面提到的文件,實際RESTORE DATABASE ...並將隨後確定需要相應備份文件的哪些部分才能使數據庫恢復到一致狀態。RESTORE LOG ...

概括

神奇之處在於 LSN 儲存在由 Microsoft 編碼的備份文件和還原過程中。

您可以獲得許可證,以允許您插入各種 API,從而允許您從備份文件中讀取更多資訊。為此,您必須聯繫 Microsoft 代表。

在恢復期間,系統如何知道只有日誌文件的某些部分(下午 1 點後

$$ exclude 10AM to 1PM $$) 需要重播嗎?

每個還原操作都將數據庫留在某個 LSN。還原日誌備份時,任何 LSN 小於要還原數據庫的 LSN 的日誌記錄都會被跳​​過。

引用自:https://dba.stackexchange.com/questions/219758