原文: sql server 備份與恢複系列二 事務日志概述
1.1 日志檔案與資料檔案一緻性
在上一章備份與恢複裡了解到事務日志的重要性,這篇重點來了解事務日志。 事務日志記錄了資料庫所有的改變,能恢複該資料庫到改變之前的任意狀态。在sql server執行個體每次啟動時都會去檢查資料檔案與日志檔案的一緻性。 包括日志記錄的任何已送出的資料必須展現在資料檔案上,未被标記為已送出的将禁止寫入資料檔案,日志還存儲了收到用戶端復原事務請求,sqlserver出錯如死鎖等,日志産生一個rollback指令。
事務日志是在資料庫建立或改變時與資料庫關聯起來的一個或多個檔案。 任務改變資料庫的操作都會在事務日志中寫入描述這些改變的記錄,包括要改變的頁碼,增加或删除的資料值,事務資訊,起止的日期和時間資訊等。通過dbcc log可以看到如下資訊

sql server裡每個日志記錄都有一個唯一的日志序列号辨別LSN, 同一個事務裡的所有日志記錄是一個連接配接起來的整體,這樣能夠容易的定位一個事務的各個部分,進而實作撤銷undo或重做redo操作。
1.2 優先寫日志
在日志裡有個名詞叫“優先寫日志”。是指:緩存管理器能夠保證日志寫入磁盤優先于相應的資料改變寫入磁盤,這叫優先寫日志。一旦某個資料頁發生改變,相應的日志項的LSN将會被寫入該資料頁的頁頭,緩存管理器能夠保證日志頁以特定的順序寫入磁盤,使得無論故障在何時發生,sqlserver 能清楚知道在系統故障之後應該處理哪些日志塊。如下圖所示
但一個事務日志記錄被寫入到磁盤,實際上被更改的資料可能還未來得及寫入資料頁,對于事務日志寫操作是異步的,資料頁的寫操作也是異步的,但資料頁不需要立即完成,因為日志包含了用來重做這些寫操作的所有資訊。
1.3 日志檔案與重新開機恢複
在sqlserver錯誤日志 error log 裡會報告每個資料庫重新開機恢複的進展,它會告訴我們每一個資料庫有多少事務被前滾,多少事務被復原, 有時被稱為“崩潰”恢複,因為sqlserver崩潰或服務異常停止,需要恢複過程在服務重新開機時運作。 如果sqlserver裡 事務日志與資料檔案一緻,則重新開機服務很快。
1.4 日志檔案redo與undo
如果事務在送出時,sql server服務突然停止,資料還未來得及寫入資料頁(注意不是磁盤),當服務啟動,該事務必須前滾,根據事務日志所訓示的更改來重做事務,這稱為恢複的重做(redo)階段。
如果一個檢查點checkpoint 在事務送出前發生, 它将會把未送出的更改寫入磁盤,随後sql server服務在送出前被停止, 恢複過程将會找出未送出事務對資料的改動,該過程必須撤銷反映在事務日志中的改動,復原所有不完整事務稱為恢複的撤銷(undo)階段。
1.5 改變日志檔案大小
資料庫管理者為了控制檔案在大小,可能有時候要收縮檔案空間可以使用
dbcc shrinkdatabase 或 dbcc shrinkfile 。shrinkdatabase 是收縮指定資料庫中的所有資料檔案和日志檔案大小。shrinkfile 是收縮目前資料庫的指定資料檔案或日志檔案的大小。注意的是不能在備份資料庫時收縮資料庫。 反之,也不能在資料庫執行收縮操作時備份資料庫。收縮一般在資料庫維護時段可以進行。使用dbcc shrinkfile來一個檔案一個檔案地做比較穩妥。-- 驗證檔案是否有足夠的可用空間可供删除
SELECT name ,size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS int)/128.0 AS AvailableSpaceInMB
FROM sys.database_files;
1.6 虛拟日志檔案VLF
在前面“
sql server 日志檔案結構及誤操作資料找回”中講過每個實體日志檔案是分成多個虛拟日志單元,虛拟日志單元沒有固定大小,且數量不固定。可以通過dbcc loginfo來觀察虛拟日志檔案的關鍵屬性。當我們在目前資料庫下運作dbcc loginfo,會為每個VLF傳回一行記錄。
use test
dbcc loginfo
上面是檢視了test庫日志檔案裡的VLF, Fileld是指實體日志檔案ID,這裡test隻有一個日志檔案。 FileSize是檔案大小(byte), StartOffset是指起點偏移(byte)。第一個VLF 是包含頁頭資訊而不是日志記錄,VLF從第二頁開始。Status 表示該VLF是否可被重用,狀态2表示該VLF或者是活動的或者是可恢複的,狀态0表示該VLF是可複用的或者完全沒有被使用過。通過備份事務日志會改變可恢複的VLF到可複用狀态也就是狀态為0.