SQL Server 的備份檔,這個月又比上個月大了好幾 GB。打開資料庫一看,資料表筆數沒什麼變,那這些空間是哪來的?
很多人第一反應是「資料庫膨脹了」,然後跑去 DBCC SHRINKDATABASE 想把它壓回來。先停手——SHRINK 是 SQL Server 裡最容易幫倒忙的指令之一,後面會講為什麼。先搞懂備份檔為什麼會長大。
完整備份複製的是資料庫裡「已配置的資料頁」加上一小段交易記錄,不是 mdf 檔的實體大小。一個 100 GB 的 mdf,裡面只有 40 GB 的頁真有資料,備份檔大約就是 40 GB 出頭。所以備份檔變大,意思是已配置的頁變多了——或者,根本不是資料庫的問題,是備份檔本身在累積。順這條線,由最常見往下查。
真因一:你每天往同一個檔案疊備份(最常見)
頭號元兇,也最容易被忽略。BACKUP DATABASE 不指定 WITH INIT 時,預設是 NOINIT——把這次備份附加到既有檔案,不是覆蓋。
如果排程固定備份到 D:\Backup\MyDB.bak、每天跑又沒寫 INIT,這個檔案裡其實疊了一份又一份完整備份,當然每天長大。
要確認是不是這個問題,用 RESTORE HEADERONLY 把檔案裡的備份集列出來:
1 | RESTORE HEADERONLY FROM DISK = 'D:\Backup\MyDB.bak'; |
回傳結果每一列是一份備份,看 Position 欄位。如果跑出來是一長串、Position 從 1 排到 30,那答案就在這了——不用再往下查。修法是改用 INIT 覆蓋,或更好的做法:每次用帶時間戳的新檔名。
1 | -- ❌ 不指定就是 NOINIT,一直往同一檔疊 |
真因二:頁密度太低(內部碎片)
如果備份檔不是疊出來的,那才往資料庫裡找。這裡要先澄清一個常見誤解——索引碎片分兩種:
- 外部碎片:頁的邏輯順序和實體順序對不上。它影響查詢效能,但不影響備份大小,因為備份是一頁一頁原樣複製。
- 內部碎片:頁面沒填滿,同樣資料用掉更多頁。這個會讓備份變大,因為已配置的頁變多了。
所以拿 avg_fragmentation_in_percent(外部碎片指標)去解釋備份變大,會找錯方向。要看的是頁密度:
1 | -- 看頁密度:avg_page_space_used_in_percent 偏低 = 內部碎片重 |
頁密度低通常是 fill factor 設太低、或大量隨機寫入造成 page split。用 ALTER INDEX ... REBUILD 配合合理的 fill factor 重建,能把頁填回去。
順帶澄清兩個常被當兇手、其實不是的:RCSI/快照隔離的資料列版本存在 tempdb,而 tempdb 不進使用者資料庫的備份,所以它通常不是備份變大的原因;LOB 欄位異動也是頁層級備份,不會因為改一個欄位就把整個物件重複塞進去。
真因三:資料真的長大了
最樸素的可能:資料就是變多了。查實際各表佔用:
1 | EXEC sp_spaceused; -- 整庫概況 |
如果是這個,那不是「異常」,是該規劃容量和歸檔策略了。
為什麼別 SHRINK
回到開頭那個衝動。DBCC SHRINKDATABASE 會把檔案末端的頁搬到前面的空位,問題是——每搬一頁,就在它所屬的索引製造碎片。跑完一次 shrink,索引碎片可以從接近 0% 直接飆到接近 100%,你做的索引維護全廢。
更糟的是「先重建索引、再 shrink」:REBUILD 剛把索引整理乾淨,shrink 立刻打散,檔案下次又長回來,陷入 shrink→碎片→rebuild→長大→再 shrink 的死循環。
備份檔變大,幾乎沒有一種情況的正解是 shrink 資料庫。對症處理上面三個真因就好。
正確的維護方式
- 備份用
WITH INIT(或每次帶時間戳的新檔名),並加WITH COMPRESSION——壓縮通常能明顯縮小備份檔,是該預設打開的選項。再設保留策略定期清舊檔。 - 索引維護用
ALTER INDEX ... REBUILD(碎片不嚴重時REORGANIZE),別再用DBCC DBREINDEX——那指令 SQL Server 2005 起就標記棄用了。 - 例行
DBCC CHECKDB確認沒有實體損壞、監控成長趨勢設警示,這些是日常該帶上的維護。
收尾
備份檔暴增,照這個順序查最快:先用 RESTORE HEADERONLY 看是不是同一個檔疊了多份備份(最常見),再用 sp_spaceused 看資料是不是真的長大,最後才查頁密度。
SHRINK 不在這個清單裡。它解決的是「檔案實體很大但裡面很空」這種特定情況,代價是把索引打爛——動之前要非常清楚自己在做什麼。下次看到 .bak 又肥一圈,先 RESTORE HEADERONLY 打開看看,那通常就是答案。




