Sql-Server

靜態存檔數據庫:SQL Server 無法縮小它並留下約 400G 的未分配空間

  • July 4, 2021

我們的數據庫有問題。這是發生的事情:

所有數據庫都有大約 50% 的未分配空間,並且DBCC SHRINKDATABASE/SHRINKFILE不會回收這些空間。這些是最近清理過的存檔數據庫,應該是只讀的,所以性能不是問題(是的,我完全意識到收縮和聚集索引碎片,我不在乎)。這裡的主要目標是減少所有數據文件以節省 $$ 的儲存空間。同樣,我不關心性能,必須不惜一切代價減少這些數據文件!我說的是 800GB、1.5TB 和 2.1TB 的數據庫。所以沒有什麼普通的或小的。

所以:

  • 收縮數據庫顯示約 50% 的空間浪費
  • 具有強制頁面重組 (NOTRUNCATE) 和強制 1% 可用空間的後收縮數據庫繼續顯示 50% 未分配空間
  • 所以一個 800 GB 的數據庫,在 sp_spaceused 中顯示為具有 ~410 GB 的未分配空間,即使在收縮之後
  • 收縮文件確認數據庫只有 1% 的可用空間
  • 當我們開始使用 SELECT INTO 將表遷移到另一個數據庫時,我們開始注意到原始表佔用了數十萬頁,但遷移後它們佔用的頁數不超過數百頁
  • DBCC 還顯示原始數據庫(在 SELECT INTO 之前)使用了大量的 extent

我對此的分析如下:

  • 收縮沒有釋放未分配的空間
  • SELECT INTO yes 釋放大量空間

我想要一些幫助:

  • 為什麼收縮不起作用
  • 為什麼 SELECT INTO 有效
  • 為什麼原始數據庫浪費了這麼多空間(是的,它在成為存檔之前已經啟用了很長時間的自動增長)

我們已經在研究填充因子、頁面和範圍的使用情況,但我們希望至少能夠解釋這麼多失去的空間以及如何在沒有 SELECT-INTO 的所有 TB 數據的情況下回收它。任何幫助,將不勝感激。

事實證明,這確實是索引 REBUILD 的一個案例。

在創建了一個簡單的維護計劃來重建整個數據庫中的所有內容之後,不管它們的碎片級別或頁面數量(實際上是所有內容),之後甚至 SSMS 都開始“看到”數據文件中新可用的可用空間。收縮文件只是將 800 GB 數據文件減少到 80 GB(嚴重)。很明顯,在收縮過程中索引是碎片化的,所以我在收縮後又執行了一次REBUILD,數據文件從80GB增長到100GB,與最初的大小相比還是不錯的。

注意:如果您想知道為什麼顯著減少,這是一個存檔數據庫,其中過去 X 年的生產數據已經被開發人員大量刪除,但它仍然顯示與生產數據庫相同的總大小(有 100% 的數據)。

Microsoft 的文件承認 REBUILD 和頁面分配之間的關係:

https://docs.microsoft.com/en-us/sql/relational-databases/indexes/reorganize-and-rebuild-indexes?view=sql-server-ver15

我從沒想過維護不善的索引會對磁碟空間分配產生如此巨大的影響。

我們現在正在研究填充因子以及它對數據文件大小的影響程度。

謝謝你們!

這裡有兩件潛在的事情在起作用。Shrink 算法獲取最後一頁並將其移動到第一個空白點,這會產生大量碎片並且還可能創建轉發記錄。更好的主意是使用已經定義了預數據填充的聚集索引在不同的文件組上重建數據庫。

另一個項目可能是 2008 年出現的幽靈清理錯誤。我不知道您正在執行什麼版本,但如果是 2008 年,請確保您完全更新了更新檔。

https://codingsight.com/moving-existing-table-from-primary-filegroup-to-different-filegroup/

引用自:https://dba.stackexchange.com/questions/261553