日前將一個正式資料庫還原至測試機上,但因為測試機不需要實際資料,因此我就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卻壓不下來時就可以看看是不是這一個問題造成的囉。
我是ROCK
rockchang@mails.fju.edu.tw