原子性(Atomicity)
一緻性(Consistency)
隔離性(Isolation)
持久性(Durability)
事務日志(Transaction Log)存儲的是對資料庫所做的更改資訊,讓 SQL Server 有機會恢複資料庫。而恢複(Recovery)的過程就是使資料檔案與日志保持一緻的過程。任何在日志中訓示已經送出的資料更改必須出現在資料檔案中,任何未标記為送出的更改不能出現在資料檔案中。
預寫日志(Write-ahead Logging)功能確定在真正發生變化的資料頁寫入磁盤前,始終先在磁盤中寫入日志記錄,使得任務復原成為可能。寫入事務日志(Transaction Log)是同步的,即 SQL Server 必須等它完成。但寫入資料頁可以是異步的,是以可以在緩存中組織需要寫入的資料頁進行批量寫入,以提高寫入性能。
事務日志用于保證 SQL Server 在語句或系統出現故障時的可恢複性,并允許将備份的日志應用到資料庫上。但事務日志并沒有提供很好的可讀性,實際上讀取事務日志通常也不會擷取到太多有用資訊。更推薦的跟蹤記錄機制是使用 SQL Server Profiler 等工具,以篩選和捕獲有用的資訊。
比如,我們使用下面的 SQL 來建立一張簡單的 Table,來嘗試觀察事務日志的變化。
插入一條記錄。
使用 DBCC LOG 命名可以先觀察産生的序列。

使用系統提供的函數 sys.fn_dblog 來檢視目前的事務日志記錄,可以列出很多詳細資訊,這裡隻顯示了幾個常用的列。
事務日志總是連續的并且是順序的,按照 LSN(Log Sequence Number)的順序排列。從查詢的尾部可以檢視 AllocUnitName 操作的資料表名稱。
對應的 Operation 是 LOP_INSERT_ROWS,Context 是 LCX_HEAP,也就是插入資料到堆表。同時發現 Page ID 是 0001:00000078,也就是十進制的 120 号頁面。
可以使用 DBCC PAGE 指令檢視 Page 頁資訊。
可以看出上面的 SQL 語句 Insert 了資料 Id = 1, Name = Dennis Gao, Phone = 88888888。
不管為事務日志定義多少個實體檔案,SQL Server 總是把日志當成連續流(Contiguous Stream)來對待。當 DBCC SHRINKDATABASE 指令确認日志可以縮小多少時,它不是單獨考慮每個日志檔案,而是根據整個日志來确定可壓縮大小。
SQL Server 資料庫的事務日志是通過虛拟日志檔案(VLF:Virtual Log File)來管理的,VLF 的大小由 SQL Server 根據日志的總大小和日志增量大小來決定,不能通過配置指定。如果 VLF 數量變多會導緻資料庫性能下降,是以需要指定合理的日志檔案初始大小和增長步長,防止過多的 VLF 的産生。
SQL Server 會根據如下規則來判斷 VLF 的數量:
日志大小
VLF 數量
Size <= 1MB
将日志檔案大小除以最小 VLF 大小(31KB*8KB)确定個數
1MB < Size <= 64MB
4 個
64MB < Size <= 1GB
8 個
Size > 1GB
16 個
當日志持續增長時,會使用相同的方式确定新添加的 VLF 的數量。日志總是以整個 VLF 為機關增長,而且縮小也隻能到 VLF 的邊界為止。
VLF 可以處于以下 4 種狀态之一。
Active:日志的活動部分,從未送出事務的最小 LSN 開始,結束于最後一個寫入的 LSN。
Recoverable:在最早的活動事務之前的那部分日志。
Reusable:如果日志已經被備份,則不需要最早活動事務之前的 VLF,可重用這些空間。日志截斷或備份會将 Recoverable VLF 轉換成 Reusable VLF。
Unused:未使用的部分。
可以使用下面的 SQL 查詢 VLF 的數量。
可以使用 DBCC LOGINFO 指令進一步觀察 VLF 的相關屬相。
SQL Server 可以配置多個實體日志檔案當做一個序列流來對待。如果管理良好,定期備份或截斷日志,可能永遠都不會使用除第一個檔案之外的其他日志檔案。當需要新的 VLF 時,多個實體檔案中都沒有可用 VLF,則會以循環的方式把新的 VLF 添加到每個實體日志檔案中。
如果 SQL Server 設定了如下情況,則認為沒有維護日志備份:
設定 SIMPLE 恢複模型,資料庫會定期截斷日志。
從未進行過完全資料庫備份。
以上任何一種情況下,SQL Server 會處于自動截斷模式(Auto Truncate Model)中,當資料庫事務日志滿時就會進行截斷。這裡的 "滿" 指的是日志記錄的數量比在系統啟動過程中、在合理的時間内能夠重做的數量多。
判斷資料庫是否在自動截斷模式的最簡單的方法是查詢 sys.database_recovery_status 目錄視圖,如果 last_log_backup_lsn 列為空,則資料庫就是處于自動截斷模式。
可以通過 DBCC SQLPERF 命名來檢視日志檔案大小。
當然,也可以通過系統提供的目錄視圖來檢視。
《人人都是 DBA》系列文章索引:
序号
名稱
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15