為何使用DBCC SHRINKFILE還是無法壓縮資料檔呢?

  • 5609
  • 0
  • 2016-04-23

為何使用DBCC SHRINKFILE還是無法壓縮資料檔呢?

 

緣由 : 在某些狀況下我們需要對過肥的LDF檔案進行壓縮作業,來防止因硬碟容量不足導致SQL

服務無法正常。而我們最常用的方式就是利用DBCC SHRINKFILE來針對LDF檔案進行壓縮

 (http://msdn.microsoft.com/zh-tw/library/ms189493.aspx)

然而我們常常會會在執行完DBCC SHRINKFILE後會發現壓縮的效果並不理想,我們明明已經對LDF做了備份,卻還是無法將LDF的容量壓縮到我們的設定值,這是為什麼呢?

 

首先我們要先了解,雖然我們看到的LDF只是一個檔案,但其實該LDF檔是會分割成很多邏輯片段,一個片段寫完後再寫到下一個片段,我們稱該片段為VLF’s(Virtual Log Files)。有人將LDF形容成是一列火車,而VLF’s就是火車上一節一節的車廂。而我們在ShrinkFile的動作其實就是在移除VLF's

 

 

我們設定LDF檔案成長大小也會關聯VLF’s的數量(如下表)

 

LDF Size

Number of VLF’s

1MB < Size < 64MB

4

64MB < Size < 1GB

8

Size > 1GB

16

參考資料來源 http://blogs.msdn.com/b/sqlserverfaq/archive/2011/06/01/what-are-virtual-log-files-vlf-in-sql-server-video.aspx

 

 

步驟一 :

 

1.如下圖所示,我們先建立一個測試資料庫TestDBLDF一開始為2MB,每次成長則為16MB

2.建立資料表PrimaryTable_Large,每一筆ROW1508 Bytes

3.做一次完整備份(如果新建DB沒先做一次完整備份,該DB會以Recoverysimple方式運作)

4.利用DBCC LOGINFO檢視VLF’s狀況。

 

我們可以看見一開始DB CREATE後產生了4VLF's檔案,我們可以看一下FileSize欄位,其加總後約略就是我們建立DB時定義的2MB大小。

clip_image002

 

  

 

 

步驟二 :

 

1.      我們直接寫入1500筆資料到測試TABLE(2.2MB)

2.      我們由下圖綠色圈選處可以看見LDF依照設定成長了16MB,使用率為18.8%

3.      我們由下圖紅色圈選處可以看見增加了4個新的VLF’s,每一個VLF4MB

4.      我們由下圖藍色圈選處可以看見目前Transaction Log使用了5個的VLF’s(Status欄位狀態為2)

 

clip_image004

 

 

 

  

 

步驟三 :

 

1.      我們先做一次交易紀錄備份作業。

2.      我們由下圖綠色圈選處可以看見LDF使用率下降到8.5%

3.      我們由下圖藍色圈選處可以看見備份後,4VLF’s Status欄位值變更為0,表示該VLF可以Reuse

4.      我們由下圖紅色圈選處可以看見目前Transaction Log在該VLF上。

 

我們都知道LDF是循序寫入,這裡可以觀察FSeqNo欄位,就可以了解VLF排序。

clip_image006

 

 

 

 

 

 

 

 

步驟四 :

 

1.      我們用DBCC SHRINKFILE來將LDF檔壓縮到2MB

2.      由下圖藍色圈選處,我們可以知道目前LDF檔案為6MB左右,使用率為73%左右。

3.      此時VLF's有甚麼變化呢?我們可以看見VLF’s檔案由8個下降為5個。少了34MBVLF。因此我們可以知道壓縮作業就是去刪除VLF's

4.      由紅色圈選處我們可以發現剛剛的第一筆VLF Status欄位由0變成2了,FSeqNo欄位的值也是目前最大值,表示目前Transaction Log已經Reuse VLF了。

 

clip_image008

 

 

 

 

 

步驟五 :

 

1.      再做一次交易紀錄備份。

2.      我們由下圖紅色圈選處可以看見LDF使用率下降到6.8%

3.      我們由下圖藍色圈選處可以看見FSeqNo41VLF在此次備份後Status也由2變成0了,表示該VLF也可以Reuse

 

clip_image010

 

 

 

 

 

 

 

 

步驟六 :

 

1.      經過步驟五再次備份交易紀錄後,我們再做一次DBCC SHRINKFILE(目標2MB)

2.      由下圖藍色圈選處我們可以發現這一次已經成功的將LDF壓縮到2MB了。

3.      VLF's數目也由5個再降到4個。而那4 VLF's大小總和就是2MB

clip_image012

 

結論 : 由這一次實驗我們可以知道DBCC SHRINKFILE就是去移除VLF’s,而我們做完交易紀錄備份後,大多數的VLF's狀態會變更成Reuse,此時該VLF就可以被刪除。而我們常常會發生壓縮下來的空間並不大其原因就是還有VLF無法被刪除,而該VLF卡在中間,導致SHRINK的作業只能刪除到該VLF為止。因此遇見這一種情形您可以稍等一下再做一次交易紀錄備份後,待該VLF檔狀態變成可以Reuse時,再做DBCC SHRINKFILE應該可以有很好的效果了。

 

 

我是ROCK

rockchang@mails.fju.edu.tw