SQL Server如何截斷(Truncate)和收縮(Shrink)事務日志


當SQL Server截斷事務日志時,它僅僅是在虛擬日志文件中做個標記,以便不再使用它,然后准備以重用形式來做備份(假如運載在完整或是批量日志恢復模型)。也就是說,在使用簡單恢復模型時,事務日志包括如下的日志記錄:

32139_12643878462zqY[1]

checkpoint發生時,虛擬日志文件1、2不再被使用,因為事務1、2已經被提交了,而且日志記錄也不再需要回滾了。然后SQL Server重用虛擬日志文件1、2,如下圖:

32139_12643878470WmQ[1]

這就是我們所熟知的事務日志截斷。基本上,事務日志的活動區間已經被截斷了,但是事務日志的物理大小不會改變,除非數據庫使用自動收縮的屬性設置。在這種情況下,事務日志就會盡可能的在物理上進行周期性的收縮。

32139_1264387844t54d[1]

為了物理上減小事務日志的大小,收縮事務日志作為已知的方法,你在使用時可以選擇下面選項中的一種:

  • 執行 DBCC SHRINKDATABASE命令
  • 執行 DBCC SHRINKFILE命令
  • 設置數據庫的事務日志自動收縮選項

需要注意的是,事務日志僅僅能收縮到虛擬日志文件的邊界。下面是個例子。

我新建了一個數據庫,它有1MB的事務日志空間,5MB的自動增長空間。運行DBCC LOGINFO顯示如下:

32139_1264387838JQ1H[1]

這里有四個可變大小的虛擬日志文件。然后我輸入一些數據,這會使事務日志 增長到5MB:

32139_1264387839cNTX[1]

在新的5MB事務日志區間里面新建了4個新的虛擬日志文件。每一個新建的虛擬日志文件都是1310720bytes,每7個虛擬日志文件正在使用時(狀態是2)。我現在備份事務日志,因此將會截斷事務日志:

32139_1264387840FFAd[1]

目前僅僅有一個虛擬日志文件在使用(第7行,狀態為2). 假如我現在用下面的命令,試着把日志收縮到2M:

DBCC SHRINKFILE ('AdventureWorks_log', 2)

因為活動日志記錄是虛擬日志文件7,所以SQL Server僅僅刪除虛擬日志文件8。這次事務日志從7MB收縮到4.7MB. SQL Server也在事務日志中新建了假的入口,為了移除2MB點之前的最近活動日志記錄,以便於它包裹到虛擬日志文件2(注意狀態為2的行)。

 32139_1264387841CUkN[1]

假如現在再次備份事務日志的話,事務日志會再次被截斷,現在活動區間就是虛擬日志文件2了。

32139_1264387842trTT[1]

如果我現在再嘗試一次收縮文件的話,SQL Server則會成功的收縮到2MB左右,因為日志的活動區間已經接近2MB了。文件被收縮到最接近於日志登記時的大小。這時DBCC LOGINFO的輸出如下:

32139_1264387843FUmq[1]

事務日志文件大小為2359296bytes(虛擬日志文件大小總量要加上8192字節的頭信息)

所以如果你發現你不能收縮事務日志到一個指定的范圍,運行DBCC LOGINFO,然后檢查虛擬日志文件的范圍,弄清楚每一個日志的大小,你能把文件收縮到什么范圍。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM