SQL Server 最小日誌記錄

SQL Server之因此記錄事務日誌,首要目的是爲了把失敗或取消的操做還原到最原始的狀態,可是,並非全部的操做都須要徹底記錄事務日誌,好比,在一個空表上放置排他鎖,把大量的數據插入到該空表中。即便插入操做在任意時刻失敗,只須要把清空表,就能夠把表還原,根本不須要記錄插入的詳細數據。在表上放置排他鎖的目的,是爲了阻止其餘人更新該表,當插入失敗時,只須要清空表就還原到最原始的狀態。sql

最小化日誌記錄僅記錄恢復事務所需的信息,而不支持任意時間點恢復,也就是說,在最小化日誌記錄操做時,SQL Server也會記錄事務日誌,可是僅記錄回滾事務所需的有限信息。「有限信息」是指,僅把分配的頁面記錄在事務日誌中,而沒有記錄這些頁面包含的實際數據,所以保持了較小的事務日誌文件的大小。數據庫

一,最小日誌操做

在FULL還原模式下,全部的大容量操做都會徹底記錄事務日誌,在進行大容量數據插入時,最小化日誌記錄更有效率,減小了事務日誌空間在大容量操做時暴增的可能性,可是,若是在最小化日誌記錄生效時數據庫已損壞或丟失,那麼沒法把數據庫恢復到故障點。測試

在最小化日誌記錄期間執行大容量數據插入,雖然數據插入不會記錄在事務日誌中,可是,對於每次爲表分配的區(8個物理地址連續的Page)都會記錄在事務日誌中。不是全部的操做都能實現最小化日誌記錄,最小化日誌操做的類型:優化

  • 大容量導入操做(Bulk Import Operations)包括 BULK INSERT、BCP和 INSERT SELECT
  • SELECT INTO
  • 索引操做:CREATE INDEX、ALTER INDEX REBUILD、DROP INDEX

有意思的是,TRUNCATE 並非最小化日誌記錄操做,在任何還原模式下,TRUNCATE 都完整記錄事務日誌的,並可以還原到任意時間點,不過TRUNCATE記錄日誌的效率更高,採用deferred-drop 機制來記錄日誌。ui

二,觸發最小日誌的條件

測試用例的環境是SQL Server 2017版本,在 SIMPLE或BULK_LOGGED還原模式下作測試。日誌

實際上,要在執行大容量插入時實現最小化日誌記錄,必須知足五個條件:orm

  • 數據庫處於SIMPLE或BULK_LOGGED還原模式
  • 表級鎖定,推薦使用表 hint 顯式上鎖:with(tablock)
  • 不是複製表
  • 不是內存優化表
  • 在知足前四個條件的基礎上,有以下結論:

一個表是否能夠進行最小化日誌記錄還取決於該表是否已創建索引,若是是,則取決於該表是否爲空。server

結論1:表沒有索引,Data Page執行最小化日誌記錄。blog

結論2:表沒有彙集索引,可是有非彙集索引,Data Page執行最小化日誌記錄。索引

  • 當表是空的時,Index Page執行最小化日誌記錄
  • 當表有數據時,Index Page執行完整日誌記錄

對於使用分Batch插入的狀況,當表是空的,對於第一個Batch插入,Data Page和Index Page都執行最小化日誌記錄;從第二個Batch開始,Data Page執行最小化日誌記錄,而Index Page執行完整日誌記錄。

結論3:表有彙集索引

  • 當表有彙集索引,而且是空表時,Data Page和Index Page都執行最小化日誌記錄。
  • 當表有彙集索引,而且有數據時,Data Page和Index Page都執行完整日誌記錄。

對於使用分Batch插入的狀況,當表是空的,對於第一個Batch插入,Data Page和Index Page都執行最小化日誌記錄;從第二個Batch開始,Data Page執行最小化日誌記錄,而Index Page執行完整日誌記錄。

結論4,從表中能夠看出:

  • 索引頁的分配都是Fully Logged,
  • 堆表的數據頁更新都是Min Logged,
  • 只有當表是彙集索引時,數據頁的更新纔是Fully Logged的,實際上,BTree表就是索引自己。

三,索引操做中的最小化日誌

從上節中的結論4中知道,索引頁的分配都是Fully Logged,索引頁的回收(deallocation )也都是Fully Logged。在特定的狀況下,執行CREATE INDEX、ALTER INDEX REBUILD 和 DROP INDEX可以激發數據頁的最小化日誌記錄,索引的重建(REBUILD)至關於先刪除索引,再建立索引。

好比,建立索引至關於向有數據的表中插入數據,索引頁是Full Logged,數據表根據結論4來判斷數據頁是Full Logged或Min Logged。

四,延遲刪除

對於TRUNCATE TABLE,概況來講,是經過回收已分配的數據頁來移除數據,而且只把回收的數據頁記錄在事務日誌中。

DROP TABLE 和 TRUNCATE TABLE 都是完整記錄日誌的操做,不過日誌不是當即建立,而是延遲記錄,這是由延遲刪除(deferred drop)的機制來實現的。當一個表被 drop 或 truncate 時,屬於該表的全部數據頁都會被系統標記爲回收,並把標記爲回收的數據頁和區放置在延遲刪除隊列(deferred-drop queue)中,該數據頁或區實際上並無釋放,只是標記爲回收(deallocation )。延遲刪除機制經過回收表的數據頁,從而模擬drop 或 truncate操做當即完成後的效果,這個過程僅僅產生不多的日誌記錄。

可是延遲刪除的後臺處理程序(deferred-drop background task)每隔幾秒鐘就會執行一次,並以小批量的方式回收放置在延遲刪除隊列(deferred-drop queue)中的全部Page和Extent,從而確保操做不會耗盡內存。回收空間的操做是徹底記錄日誌的,不過,釋放一個充滿數據或索引記錄的頁面,並不會記錄個別數據行的刪除。相反,整個頁面只是在相關的PFS(Page Free Space)分配字節圖中標記爲已取消分配。

從SQL Server 2000 SP3開始,執行表的DROP或TRUNCATE時,只會看到一些正在生成的日誌記錄。若是等待一分鐘左右,而後再次查看事務日誌,您將看到deferred-drop操做已經生成了成千上萬的日誌記錄,每一個日誌記錄都表示回收一個Page或Extent。

 

 

 

 

參考文檔:

Operations that can be minimally logged

Prerequisites for Minimal Logging in Bulk Import

SQL Server: Understanding Minimal Logging Under Bulk-Logged Recovery Model vs. Logging in Truncate Operation

SQL Server: An Examination of Logging in Truncate Table Statement and Its Comparison With Delete Statement

The Myth that DROP and TRUNCATE TABLE are Non-Logged

相關文章
相關標籤/搜索