Sql-Server

SQL Server - 僅恢復主文件組但使數據庫聯機

  • March 24, 2021

我試圖找出是否可以通過僅還原主文件組來使 SQL Server 2016 Enterprise 數據庫聯機。我的場景是,我們有一個相當大的 OLTP 數據庫,大約 2TB。大約 25% 的大小是一個“歷史”表,顧名思義,它只是跟踪活動。

每天,這個數據庫(在完全恢復模式下)都會被備份並恢復到其他幾個環境中,在這些環境中它被用於各種,通常不是關鍵的目的。由於數據庫大小,這個恢復過程很慢,而“歷史”表顯然是一個重要的貢獻者。

儘管這個“歷史”表需要存在於這些其他環境中(它被許多儲存過程引用),但它不需要包含任何數據。我們只需要它存在,但它可以是空白的,或者理想情況下,只包含幾千個最近的行(不是必需的)。

我實現這一目標的第一個想法是:

  1. 將“歷史”表移動到輔助文件組(數據庫目前只有一個主文件組)
  2. 僅對主文件組執行備份(這可能是額外的“copy_only”備份)。
  3. 將此備份還原到其他環境。

問題是,在第 3 步之後,我可以使數據庫聯機,但是,我顯然無法引用“歷史”表,因為它屬於尚未恢復的 FG。如果這樣做,我會收到預期的錯誤:

查詢處理器無法為表或視圖“歷史”生成計劃,因為該表位於未聯機的文件組中。

所以我的問題是:

  1. 使用這種(或類似的)方法,我想要實現的目標是否可行?
  2. 在第 3 步之後,有沒有辦法可以“刪除”輔助文件組並在主文件組中重新創建“歷史”表的空白副本?這將允許依賴於它的存在(但不是它的數據)的應用程序/儲存過程起作用。如果不先恢復輔助文件組,這似乎是不可能的。
  3. 有沒有我沒有考慮過的更好的方法?

注意 - 任何 FK 都不會引用“歷史”表,因此不會因為那裡沒有數據而導致數據完整性問題。

我知道有“同步”多個數據庫的替代方法,而不是備份/恢復(複製是一種)。不幸的是,這有點超出我的控制,所以現在,我想專注於備份/恢復方法。當然,我很高興聽到建議。

更新 - 需要明確的是,每個環境都需要數據庫中的其餘數據,但要減去“歷史”表。

由於 JD 已經為您提供了一些關於替代方案的好建議,我將添加您如何具體實現您所要求的內容,如果您仍然認為這是解決您的問題的好方法,您可以使用它。

對於此範例,這是一個包含兩個文件組的數據庫:

USE [master]
GO

CREATE DATABASE [Lab]
ON  PRIMARY 
( NAME = N'Lab', FILENAME = N'C:\Databases\Lab.mdf'), 
FILEGROUP [HISTORY] 
( NAME = N'Lab_History', FILENAME = N'C:\Databases\Lab_History.ndf')
LOG ON 
( NAME = N'Lab_log', FILENAME = N'C:\Databases\Lab_log.ldf')
WITH CATALOG_COLLATION = DATABASE_DEFAULT
GO

現在我們在該數據庫上創建兩個表(每個位於不同的文件組中):

CREATE TABLE Users (ID int, UserName varchar(50))
ON [PRIMARY];

CREATE TABLE History (ID int, UserName varchar(50))
ON [HISTORY]; --Table History resides on a different Filegroup

之後,我們備份我們稍後要恢復的文件組:

--Take a COPY_ONLY backup of the PRIMARY Filegroup
BACKUP DATABASE Lab
FILEGROUP = 'PRIMARY'
TO DISK = 'C:\BackupSQL\Lab_PRIMARY.bak'
WITH COPY_ONLY;

Users您可以刪除 Lab 數據庫並僅使用我們的表恢復文件組:

--Restore the Filegroup Backup
RESTORE DATABASE Lab
FILEGROUP = 'PRIMARY'
FROM DISK = 'C:\BackupSQL\Lab_PRIMARY.bak';

最後,線上擁有一張空History表的技巧:

--Rename the original table
USE Lab;
EXEC sp_rename 'dbo.History', 'History_';

--Recreate an empty History table
CREATE TABLE History (ID int, UserName varchar(50))
ON [PRIMARY]; --Recreates a History table now on the PRIMARY Filegroup

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