[SQL SERVER][Memo]了解檔案和資料庫壓縮
前幾天晚上朋友在FB上對我說DBCC SHRINKFILE真好用,當下我聽到覺得有種壯士一去不復返念頭,
我花了一些時間和朋友解釋DBCC SHARINKFILE所帶來的風險,並且自己也整理記錄一下。
SQL Server中你可以透過 DBCC SHRINKFILE和DBCC SHRINKDATABASE 壓縮檔案大小。
壓縮目前資料庫之指定資料或記錄檔的大小,或藉由將資料從指定檔案移到同一檔案群組中的其他檔案的方式來清除檔案 (讓檔案可以從資料庫中移除)。檔案可以壓縮成小於當初建立時所指定的大小。
這會將檔案大小下限重設為新值。
MSDN有提到這麼一段:
如果指定了 target_size,DBCC SHRINKFILE 會嘗試將檔案壓縮成指定的大小。
檔案將釋出之部分所用的頁面,重新放置到檔案保留部分的可用空間中。
例如,如果有 10 MB 的資料檔,將 target_size 設為 8 的 DBCC SHRINKFILE 作業會使檔案最後 2 MB 所用的所有頁面,
都重新配置到檔案前 8 MB 的任何未配置頁面中。
DBCC SHRINKFILE 不會將檔案壓縮到小於將資料儲存在檔案中所需要的大小。
例如,如果使用了 10 MB 資料檔中的 7 MB,將 target_size 設為 6 的 DBCC SHRINKFILE 陳述式,
只會將檔案壓縮成 7 MB,而不是 6 MB。
注意:
當你使用DBCC SHRINKFILE 後,SQL Server會調整物理空間配置,並將新文件移動到新位置,
然後依照 target_size 嘗試釋放空間,而這一連串的動作,在某些情況下會導致資料庫檔案損毀(如果使用頻率過高),
並且對資料庫效能造成一定的影響(請勿啟用自動壓縮)。
而我最常見的就是DBA使用 DBCC SHRINKFILE壓縮交易記錄檔,
但我強烈建議定期備份交易記錄檔(每10分鐘)來達到循環使用交易記錄檔空間(因為交易記錄是循環使用的檔案。圖1),
而不是經常壓縮交易記錄檔,因為這對效能上有一定衝擊(SQL Server會等待交易記錄檔有足夠空間才寫入硬碟),
我舉一個簡單例子,假設你的交易記錄檔maxsize =50 GB、filegrowth=100MB,
直到某一天交易記錄檔暴了(假設是每日批次轉檔程式造成),所以你可能會定期執行壓縮交易記錄檔( target_size=500 MB),
但每日批次轉檔程式假設總共會耗用2 GB紀錄空間,
這時你的交易記錄檔會增加許多虛擬記錄檔(因為 filegrowth增加量太小),
所以當SQL Server 執行CheckPoint時,發現交易記錄檔空間不夠,
就會通知OS挖一塊新空間來使用(依照filegrowth 設定大小),而這一連串的處理過程都會花費Server資源,
定期壓縮交易記錄檔,不僅對SQL Server 沒有任何幫助,
也有可能會導致你的應用程式錯誤(可能在等待擴充較大或過多交易記錄檔)。
對於交易記錄檔比較建議依系統使用最終量建立相對大小,避免不必要的空間擴充處理動作。
再來就是 filegrowth的設定值避免過小,因為過多不必要虛擬記錄檔將會降低執行效能。
圖1(擷取MSDN)。
壓縮指定資料庫中的資料和記錄檔大小。
由於 DBCC SHRINKDATABASE 是基於檔案系統的,所以其實是執行DBCC SHRINKFILE(包含Filegroup),
這裡需注意 target_percent 參數,是指壓縮資料庫之後,資料庫檔案所要保留的可用空間百分比,
這部份大家可以參考MSDN上所提的例子(我覺得很清楚),
最後!當你執行DBCC SHRINKDATABASE如果空間沒壓縮成功的話,
還請不要說 SQL Server 有Bug了喔。
參考