Sql-Server

縮小數據文件的最快方法是什麼?

  • December 31, 2021

我有一個 4 Tb SQL Server 2008 R2 數據庫。我將使用新版本的 SQL Server 2012 將此數據庫移動到新伺服器。(該應用程序不支持 SQL Server > 2012,但這不是我的問題的主題)。

在此之前,我要將幾乎所有對像從 4To 的主數據文件移動到同一文件組上的多個數據文件中,這樣我就可以取回 4Tb 文件上的可用空間。

移動對像後,使用 dbcc 收縮文件(包含 256Mo 塊)需要永遠回收可用空間。

將空間恢復到作業系統的最快方法是什麼?有沒有辦法使用備份還原來縮小文件?

有沒有辦法使用備份還原來縮小文件?

如果這意味著您可以接受離線操作,您是否可以將收縮與移動結合起來,並通過遷移取消將數據移動到文件組中的其他文件中(除非您還有其他理由想要這樣做)在維護視窗期間將數據傳輸到新數據庫:

  1. 編寫目前數據庫的架構腳本。
  2. 使用它在 2012 實例中創建新數據庫,但只是表及其聚集索引。省略外鍵約束(這使得數據複製更少 faf)、非聚集索引(這使得批量數據導入更快)、觸發器(您不希望這些在數據複製步驟中觸發)、視圖(這些可能有索引提示您已跳過創建的引用索引)和過程和函式(與視圖一樣)。
  3. 如果您想要新數據庫中的新文件/文件組結構,請立即安排。
  4. 將數據批量複製到新數據庫。使用 SSIS 或使用連結伺服器設置編寫腳本,而不是更多地執行此操作 - 這樣您就可以輕鬆調整和重複該過程,以防出現問題或在真實事件之前作為測試。
  5. 創建您在步驟 2 中跳過的所有非聚集索引、外鍵約束、觸發器、視圖、過程和函式。如果您在步驟 3 中創建了多文件排列,請注意確保索引正常在你想要的地方。
  6. 測試新數據庫。
  7. 將應用程序切換到使用新數據庫並將舊數據庫放在遙不可及的地方(重命名和/或設為只讀,但不要放棄,以防萬一在早期發現問題時需要回滾)。

您現在應該在 SQL2012 實例中擁有數據庫的完整副本,並且您根本不需要修改 2008 實例的副本(文件之間沒有雜耍數據等),因此它應該更快更安全。由於您沒有以任何方式修改源數據庫,因此您有一個自動回滾計劃(如果出現故障,請不要使用新數據庫,稍後再試)。當您將數據新導入到新數據庫中時,沒有什麼可以縮小的 - 它全部進入目標文件的大小應該是。

我強烈建議您首先在測試環境中使用源數據庫的副本執行此操作,這樣您就可以驗證該過程針對新數據庫執行您的應用程序,以確保在生產中執行此操作之前沒有意外的回歸‡ 。

‡由於可能需要調整索引等的查詢規劃器估計的差異導致性能下降 - 儘管實際上由於 SQL2012 正式支持該應用程序,但希望您的供應商已經處理了任何可能出現的問題,但仍然值得偏執和檢查

**另一個可能不那麼 faf 的選項:**如果使用最新版本的 SSMS 創建 .bacpak 支持早至 2008 年的 SQL 實例,那麼您可以只對源數據庫執行此操作並恢復到 SQL2012 實例。這將有效地完成我上面描述的過程。

DBCC 收縮數據庫

我發現壓縮數據文件的最快方法是首先使用 SHRINK DATABASE 命令查看它從頂部取出的內容。它通常會很快做到這一點——但並非總是如此。在執行此操作時,請注意阻塞鎖。

警告

SHRINKDATABASE 是公正的,會不加選擇地嘗試收縮數據庫中的任何文件。如果您不喜歡這種行為,請不要執行此行為。

DBCC 收縮文件

使用 SHRINKDATABASE 後,您需要使用 SHRINKFILE。在這裡,我發現以小尺寸“分塊”收縮很重要。此外,我使用 T-SQL DELAY 來允許數據庫取回一些資源以根據需要執行其他活動。使用下面的腳本,您需要輸入 1.> 您的數據庫名稱,2.> 文件的邏輯文件名,3.> 以及以 MB 為單位的上限和下限,以 MB 和 4 為單位的數據庫大小上限.> 以 MB 為單位的較低數據庫大小。您會注意到它以 100 MB 的增量縮小,但同樣,您需要找到適合您的大小。警告:更大的增量不一定更快。如果您的下限太低,請不要“太擔心”——它不會/不能縮小超過它。(你必須原諒我的程式碼,它'

--Cut and paste the code that this T-SQL generates and run THAT code against your DB
declare @next int, @last int, @DELAY VARCHAR(255), @SHRINK VARCHAR(1000)
   
   SELECT @DELAY='WAITFOR DELAY ''000:00:01'''
   select @next=102000, @last=50000
   while(@next >=@last)
   begin
   --print @next
   SELECT @SHRINK ='use [<your DB name>] DBCC SHRINKFILE (N''<enter logical file name>'','+convert(varchar(255),@next)+ ')'
   print @shrink
   print @DELAY
   print 'go'
   select @next=@next-100
   end

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