DBCC SHRINKDATABASE無法壓縮資料庫

日前將一個正式資料庫還原至測試機上,但因為測試機不需要實際資料,因此我就Truncate所有Table後再壓縮資料庫來減少測試機器的硬碟佔用空間。

我是採用DBCC SHRINKDATABASE來壓縮整顆資料庫,但當我執行完後卻發現資料庫並沒有變小,因此就先拜Google大神跟官方文件。在官方文件中看到了這一段。

資料庫的大小不得小於設定的資料庫大小下限。 最初建立資料庫時,您會指定大小下限。
或者,大小下限也可以是最後一次使用檔案大小變更作業明確設定的大小。
像是 DBCC SHRINKFILE 或 ALTER DATABASE 作業都是檔案大小變更作業的範例。

所以整個意思就是用DBCC SHRINKDATABASE無法將資料庫壓縮到小於他的初始值,但可以透過DBCC SHRINKFILE 或 ALTER DATABASE 來做。

因此本篇就簡易的Lab一下遇見的問題。

下圖中我建立一個資料庫叫DB,然後預設的mdf檔案大小設定為20MB(紅色圈選處)。 

 

接著我建立一個Table叫Tb然後塞入4096筆資料讓mdf預設只有20MB的資料庫自動成長。

 

我檢視一下Tb這一張資料表的磁碟空間使用,下圖中可以看見該資料表用了32MB左右。

 

接下來我們檢視一下該資料庫的mdf及ldf的檔案狀況,下圖中可以看見mdf長到了84MB然後使用了35MB左右,ldf長到了74MB然後使用了35MB左右。

 

我先刪除Tb中所有的資料後Checkpoint一下,然後檢視一下mdf使用空間狀態,發現已經從35MB降到了3MB。

 

接下來我用DBCC SHRINKDATABASE來將該資料庫壓縮至可用空間保留為5%的狀態,84MB的5%+現有3MB則資料庫應會壓縮到10MB內。

 

壓縮後發現mdf還是20MB並沒有下降。

 

在發生問題初期時我查了一些系統Table,如database_files或master_files都沒有紀錄資料庫mdf的初始大小是多少,但是SQL卻可以準確的壓縮至初始大小。因此問了SQL PASS的朋友後發現原來初始大小是紀錄在該mdf的檔頭裡,在下圖中我們用DBCC PAGE去看一下檔頭,可以發現MinSize記錄了2560(Page)=20MB。

 

我們採用官方文件的建議,改用DBCC SHRINKFILE來壓縮mdf看看是否能將mdf成功壓縮。下圖中我執行DBCC SHRINKFILE指令來將mdf壓縮至5MB。

 

完成上一步驟後再檢視一下mdf空間狀態,可以發現該mdf大小以降為5MB了。

 

下圖中我們用DBCC PAGE去看一下檔頭,可以發現MinSize變成了640(Page)=5MB。

日後大家如果遇到資料庫明明很空但是DBCC SHRINKDATABASE卻壓不下來時就可以看看是不是這一個問題造成的囉。

參考資料來源: DBCC SHRINKDATABASE

 

我是ROCK

rockchang@mails.fju.edu.tw