Sql-Server

恢復不包括 FILESTREAM 數據的數據庫

  • September 24, 2012

上下文

我們正在開發一個底層有一個大型數據庫的系統。它是一個執行在 SQL Server 2008 R2 上的 MS SQL 數據庫。數據庫的總大小約為 12 GB。

其中,大約 8.5 GB 位於單個表中BinaryContent。顧名思義,這是一個表,我們將任何類型的簡單文件作為 BLOB 直接儲存在表中。最近,我們一直在測試使用 FILESTREAM 將所有這些文件從數據庫移到文件系統的可能性。

我們對數據庫進行了必要的修改,沒有任何問題,遷移後我們的系統仍然可以正常工作。該BinaryContent表大致如下所示:

CREATE TABLE [dbo].[BinaryContent](
   [BinaryContentID] [int] IDENTITY(1,1) NOT NULL,
   [FileName] [varchar](50) NOT NULL,
   [BinaryContentRowGUID] [uniqueidentifier] ROWGUIDCOL  NOT NULL
) ON [PRIMARY] FILESTREAM_ON [FileStreamContentFG]
ALTER TABLE [dbo].[BinaryContent] ADD [FileContentBinary] [varbinary](max) FILESTREAM  NULL
ALTER TABLE [dbo].[BinaryContent] ADD  CONSTRAINT [DFBinaryContentRowGUID]  DEFAULT (newsequentialid()) FOR [BinaryContentRowGUID]

所有內容都位於文件組中,但位於單獨文件組中PRIMARY的欄位除外。FileBinaryContent``FileStreamContentFG

場景

從開發人員的角度來看,我們通常希望從生產環境中獲取數據庫的新副本,以便能夠處理最新數據。在這些情況下,我們很少對儲存在BinaryContent(現在使用 FILESTREAM)中的文件感興趣。

我們幾乎可以隨心所欲地工作。我們備份數據庫,沒有這樣的文件流:

BACKUP DATABASE FileStreamDB
FILEGROUP = 'PRIMARY' 
TO DISK = 'c:\backup\FileStreamDB_WithoutFS.bak' WITH INIT

並像這樣恢復它:

RESTORE DATABASE FileStreamDB
FROM DISK = 'c:\backup\FileStreamDB_WithoutFS.bak'

這似乎工作正常,只要我們避免使用該FileBinaryContent欄位的部分,我們的系統就可以正常工作。例如,我們可以毫無問題地執行以下查詢:

SELECT TOP 10 [BinaryContentID],[FileName],[BinaryContentRowGUID]
--,[FileContentBinary]
FROM [dbo].[BinaryContent]

自然,如果我取消註釋上面的行,包括FileContentBinary在查詢中,我會收到一個錯誤:

表“dbo.BinaryContent”的大對象 (LOB) 數據位於無法訪問的離線文件組 (“FileStreamContentFG”) 上。

我們的系統處理內容設置為 的文件null,所以我想做的是這樣的:

UPDATE [dbo].[BinaryContent]
SET [FileContentBinary] = null

但這當然給了我與上面相同的錯誤。在這一點上,我被困住了。

問題

有什麼方法可以還原數據庫而不必從FileStreamContentFG文件組中還原所有內容?通過在上面嘗試將值更新為 null ,或者在文件失去時預設為 null 或其他什麼?

還是我可能以錯誤的方式解決問題?

我天生就是一名開發人員,作為 DBA 沒有太多知識,所以如果我在這裡忽略了一些瑣碎的事情,請原諒。

您嘗試做的事情會使數據庫處於(事務性)不一致狀態,因此這是不可能的。

部分數據庫可用性白皮書是一份有用的參考指南,其中包括一個如何檢查特定表或文件是否線上的範例。如果您的數據訪問是通過儲存過程進行的,那麼您可以相對輕鬆地合併該檢查。

在您的場景中可能值得一看的一種替代方法(但有些笨拙)是隱藏表格並用視圖替換它。

-- NB: SQLCMD script
:ON ERROR EXIT
:setvar DatabaseName "TestRename"
:setvar FilePath "D:\MSSQL\I3\Data\"

SET STATISTICS TIME OFF;
SET STATISTICS IO OFF;
SET NOCOUNT ON;
GO

USE master;
GO

IF EXISTS (SELECT name FROM sys.databases WHERE name = N'$(DatabaseName)')
 DROP DATABASE $(DatabaseName)
GO

CREATE DATABASE $(DatabaseName) 
ON PRIMARY 
 (
 NAME = N' $(DatabaseName)'
 , FILENAME = N'$(FilePath)$(DatabaseName).mdf'
 , SIZE = 5MB
 , MAXSIZE = UNLIMITED
 , FILEGROWTH = 1MB
 ) 
, FILEGROUP [FG1] DEFAULT
 ( 
 NAME = N' $(DatabaseName)_FG1_File1'
 , FILENAME = N'$(FilePath)$(DatabaseName)_FG1_File1.ndf'
 , SIZE = 1MB
 , MAXSIZE = UNLIMITED
 , FILEGROWTH = 1MB 
 ) 
, FILEGROUP [FG2] CONTAINS FILESTREAM
 ( 
 NAME = N'$(DatabaseName)_FG2'
 , FILENAME = N'$(FilePath)Filestream'
 )
LOG ON 
 ( 
 NAME = N'$(DatabaseName)_log'
 , FILENAME = N'$(FilePath)$(DatabaseName)_log.ldf'
 , SIZE = 1MB
 , MAXSIZE = UNLIMITED
 , FILEGROWTH = 1MB
 )
GO

USE $(DatabaseName);
GO

CREATE TABLE [dbo].[BinaryContent](
   [BinaryContentID] [int] IDENTITY(1,1) NOT NULL
   , [FileName] [varchar](50) NOT NULL
   , [BinaryContentRowGUID] [uniqueidentifier] ROWGUIDCOL UNIQUE DEFAULT (NEWSEQUENTIALID()) NOT NULL
 , [FileContentBinary] VARBINARY(max) FILESTREAM  NULL
) ON [PRIMARY] FILESTREAM_ON [FG2]
GO 

-- Insert test rows
INSERT
 dbo.BinaryContent
 (
 [FileName]
 , [FileContentBinary]
 )
VALUES
 (
 CAST(NEWID() AS VARCHAR(36))
 , CAST(REPLICATE(NEWID(), 100) AS VARBINARY)
 );
GO 100

USE master;
GO

-- Take FILESTREAM filegroup offline
ALTER DATABASE $(DatabaseName)
MODIFY FILE (NAME = '$(DatabaseName)_FG2', OFFLINE)
GO

USE $(DatabaseName);
GO

-- Rename table to make way for view
EXEC sp_rename 'dbo.BinaryContent', 'BinaryContentTable', 'OBJECT';
GO

-- Create view to return content from table but with NULL FileContentBinary
CREATE VIEW dbo.BinaryContent
AS

SELECT
 [BinaryContentID]
   , [FileName] 
   , [BinaryContentRowGUID]
 , [FileContentBinary] = NULL
FROM
 [dbo].[BinaryContentTable];
GO

-- Check results as expected
SELECT TOP 10
 *
FROM
 dbo.BinaryContent;
GO

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