Sql-Server

截斷表後從大型數據庫的主文件組回收磁碟空間(收縮除外)

  • August 16, 2017

我們有一個 8 TB SQL Server 2014 SP1 數據庫,有一個主文件組,分佈在不同驅動器上的多個文件中。這是具有多個輔助節點(一些非同步)的 AlwaysOn AG 的一部分。

這個數據庫中的一個舊表是 6TB,我們截斷了它。現在要回收這個磁碟空間,我們可以選擇DBCC ShrinkDatabaseShrinkFile

我們不關心通常的縮減問題,如碎片,或數據庫再次增長等,因為我們現在只專注於重新獲得磁碟空間。

但是這些收縮操作真的很慢,並且正在尋找一種更快的方法來做到這一點。

首先,這些是不是很慢,因為更改必須同步到同步輔助節點?

第二,有沒有辦法讓收縮更快?

我們考慮了其他幾個選項:

  • 創建另一個數據庫並將所有(舊的除外)表移至其中…但可能需要全部設置 AG。
  • 創建另一個文件組並將所有(舊表除外)表移至其中…但舊表位於主文件組上,無法刪除,對嗎?

在刪除或截斷大表後,你們在業內使用過哪種方法來“縮小”數據庫?

我已閱讀如何在需要時收縮正確但沒有答案能滿足我的問題.. 除了縮小之外還有其他選擇嗎?我可以將表移出主文件組並將其刪除嗎?

社區維基回答

執行如此大的數據庫文件的收縮操作需要一些時間。老實說,您應該考慮執行該DBCC命令,並讓它盡可能長時間地執行,在您負擔得起的日子和時間。讓它做它的事情。

如果收縮操作在完成之前停止,它不會回滾更改,因此即使它在一天執行 2 小時,另一天執行 4 小時,依此類推,直到週末或可以讓它執行一整天的時間直到它能夠快速完成。

執行腳本以在每次執行之前和之後檢查數據庫可用空間。

這樣就不會導出到新的數據庫結構或其他任何東西,你可以讓它自己做。做更多的研究,但在聽起來相似的情況下,我過去曾參與過(數據載入器做錯事的巨大數據倉庫 - 使用實際的數據庫作為臨時表而不是臨時數據庫),它發生了,就是它曾是。我找到了問題,重新訓練了數據載入器,然後進行了清理。之後,我致力於處理碎片等問題,其中空間比性能更重要。

由於提到的問題,我們總是將文件縮小為更小的塊。以我的經驗,收縮最初的速度非常慢,我猜是因為 SQL Server 必須在收縮之前從文件末尾移動頁面。但是隨著你的進步,它會變得越來越快。

當我必須收縮數據庫文件時,我通常會在文件組中添加一個新文件(初始大小 = 剩餘數據的大小),用於DBCC SHRINKFILE (N'<old_file>' , EMPTYFILE)將剩餘數據移動到新文件中,並在完成後刪除舊文件。

對於 PRIMARY 文件組,它有點複雜,因為有一些 sys 表無法移動,但是當 DBCC 向您顯示與此相關的錯誤時,它通常已將所有其他內容移動到新文件中,因此您可以將原始主文件縮小到例如 20 MB 並為其禁用自動增長。

關於AG:我們不使用它,所以我不能說性能。

如果可能/允許,您可以在執行 SHINKFILE 之前將恢復模式設置為 SIMPLE(稍後將其設置為 FULL / BULK,然後進行新的完整備份)。

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