Sql-Server

將數據庫縮小到其初始大小以下

  • January 25, 2021

我有一個 SQL Server 2005 開發數據庫,它是一個 30GB 的 live 副本。我們刪除了一些 dev 中不需要的數據,這使得使用的數據文件空間減少到 20GB。所以我們有大約 33% 未使用。

我需要回收空間,這將允許我們在伺服器上擁有第二個開發數據庫(基於縮減版本);但是,我無法收回空間,我做了以下事情:

  • 文件的初始大小SMS2_Data為 30GB。
DBCC SHRINKFILE (N'SMS2_Data' , 0, TRUNCATEONLY)

其次是

DBCC SHRINKFILE (N'SMS2_Data' , 19500)

沒有喜悅。我嘗試過進行備份,創建一個初始大小較低的新數據庫,然後恢復,因為初始大小被覆蓋,所以沒有任何樂趣。也試過:

ALTER DATABASE SMS2HazSub MODIFY FILE (NAME = 'SMS2_Data', SIZE = 20000) 

這齣錯了,說:

修改文件失敗。指定大小小於目前大小。

我嘗試了 20800,然後一直上升到 29000(29GB),它仍然不允許我更改它。

已完成收縮,然後將恢復模式從來FULL回更改SIMPLE。沒有喜悅。

我認為這與某些TEXT領域有關。我們在整個系統中大約有 6 個。因此,作為測試,我將它們全部刪除,然後縮小了文件,但仍然沒有任何變化。

剩下的唯一選擇是將數據重新導入另一個數據庫。這是不切實際的,因為它必須在實時數據庫上完成,這會帶來太大的風險。我們半定期地獲取實時數據庫的副本並覆蓋開發/測試。我們有大約 500 張桌子。我想要一種不會有將數據導出到新數據庫的風險的方法。

我嘗試將數據移動到另一個文件,它複製了除 5% 之外的所有數據。這就是導致我嘗試刪除所有文本列的原因。

伺服器處於兼容模式 90,但為 SP2。我現在做了以下 3 次:重新索引所有表、備份數據庫、收縮文件、收縮數據庫。仍然沒有喜悅。

EXECUTE sp_spaceused返回:

database_name   database_size   unallocated space
SMS2Tests       31453.94 MB     13903.16 MB

reserved     data         index_size   unused
16545568 KB  10602264 KB  4254360 KB   1688944 KB

正如一些人已經提到的,您可以創建新數據庫並從舊數據庫“複製”內容。這將是您的最佳選擇。但是我注意到你想經常這樣做。所以你最好的選擇是Redgate Data CompareRedgate Compare。兩者都是Redgate SqlToolbelt包的一部分。

那你幹什麼:

  1. 創建一個初始大小較小的空數據庫。
  2. 使用 Redgate Compare 從舊數據庫中複製數據庫結構、函式等
  3. 使用 Redgate Data Compare 將數據從舊數據庫複製到新數據庫
  4. 您在開發數據庫上工作,然後隨時進行數據比較並定期更新開發數據庫,或者如果您對數據庫進行任何更改,您可以使用 Redgate 比較部署這些更改,然後進行 Redgate 數據比較。

數據比較的好處在於,在您複製這 30gb 的數據(您可以只從一些表開始)之後,它只需要“重新比較”一些更改,而不是整個 30gb 的數據。這意味著它對兩個數據庫的影響要比正常複製它要小得多。

這裡有幾種可能性。

首先,您使用的是 SQL 2005 SP3 或更高版本嗎?有些人報告了以前版本的 SHRINKFILE 問題(請參閱http://www.sqlservercentral.com/Forums/Topic981292-146-6.aspx#bm985164

其次,您能否驗證數據庫設置為模式 90 兼容性,而不是模式 80?這顯然是 SQL 2000 的問題,但在 SQL 2005 中取消了限制。如果您的數據庫仍設置為模式 80 兼容性,這可能仍然是一個問題。

第三,這可能是 LOB 數據(text、ntext、varchar(max))的問題。在此處查看 Paul Randall 的優秀文章

我假設您了解 SHRINKing 的真正作用,並且它會對您的表現產生負面影響:

  • SHRINK 通過將頁面從文件末尾盲目移動到開頭來工作
  • 因此,它可能會嚴重分割索引,從而導致嚴重的性能問題
  • 由於它是一種數據密集型操作,因此收縮可能需要大量時間

我通常建議使用完整的重新索引來跟進收縮(這將回收一些剛剛釋放的空間),但聽起來你甚至無法達到這一點。

如果您在活動監視器中查看縮小的 SPID,它似乎在做任何事情嗎?(IO 和 CPU 計數器變化)還是被阻塞了?我能想到的唯一另一件事是數據庫上是否有其他活動,阻止收縮。確保當時沒有其他活動 spid 正在使用該數據庫。

在此過程中切換到簡單恢復模式也是一個好主意,以防止日誌增長過多。

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