Contexto
Estamos desenvolvendo um sistema com um banco de dados grande na parte inferior. É um banco de dados MS SQL executado no SQL Server 2008 R2. O tamanho total do banco de dados é de cerca de 12 GB.
Destes, aproximadamente 8,5 GB estão em uma única tabela BinaryContent
. Como o nome sugere, trata-se de uma tabela onde armazenamos arquivos simples, de qualquer tipo, diretamente na tabela como um BLOB. Recentemente, testamos a possibilidade de mover todos esses arquivos do banco de dados para o sistema de arquivos usando o FILESTREAM.
Fizemos as modificações necessárias em nosso banco de dados sem problemas, e nosso sistema continua funcionando bem após a migração. A BinaryContent
tabela fica mais ou menos assim:
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]
Com tudo residindo no PRIMARY
grupo de arquivos, exceto o campo FileBinaryContent
que está em um grupo de arquivos separado FileStreamContentFG
.
Cenário
Do ponto de vista de um desenvolvedor, geralmente gostaríamos de uma nova cópia do banco de dados de nosso ambiente de produção, para podermos trabalhar com os dados mais recentes. Nesses casos, raramente estamos interessados nos arquivos armazenados em BinaryContent (agora usando FILESTREAM).
Temos isso quase funcionando como gostaríamos. Fazemos backup do banco de dados, sem o fluxo de arquivo assim:
BACKUP DATABASE FileStreamDB
FILEGROUP = 'PRIMARY'
TO DISK = 'c:\backup\FileStreamDB_WithoutFS.bak' WITH INIT
E restaure-o assim:
RESTORE DATABASE FileStreamDB
FROM DISK = 'c:\backup\FileStreamDB_WithoutFS.bak'
Isso parece estar funcionando bem, e nosso sistema funciona desde que evitemos as partes que usam o FileBinaryContent
campo. Podemos, por exemplo, executar a seguinte consulta sem problemas:
SELECT TOP 10 [BinaryContentID],[FileName],[BinaryContentRowGUID]
--,[FileContentBinary]
FROM [dbo].[BinaryContent]
Naturalmente, se eu descomentar a linha acima, inclusive FileContentBinary
na consulta, recebo um erro:
Dados de objetos grandes (LOB) para a tabela "dbo.BinaryContent" residem em um grupo de arquivos offline ("FileStreamContentFG") que não pode ser acessado.
Nosso sistema lida com arquivos em que o conteúdo é definido como null
, então o que eu gostaria de fazer é algo assim:
UPDATE [dbo].[BinaryContent]
SET [FileContentBinary] = null
Mas é claro que isso me dá o mesmo erro acima. Neste ponto estou preso.
Pergunta
Existe alguma maneira de restaurar o banco de dados sem precisar restaurar também tudo do FileStreamContentFG
grupo de arquivos? Atualizando os valores para nulo como estou tentando acima, ou padrão para nulo quando o arquivo está ausente ou algo assim?
Ou talvez eu esteja abordando o problema da maneira errada?
Sou um desenvolvedor por natureza e não tenho muito conhecimento como DBA, então me desculpe se estou deixando passar alguma coisa trivial aqui.
O que você está tentando fazer deixaria o banco de dados em um estado inconsistente (transacionalmente), portanto, não é possível.
O white paper Partial Database Availability é um guia de referência útil e inclui um exemplo de como verificar se uma determinada tabela ou arquivo está online. Se o seu acesso aos dados fosse por meio de procedimentos armazenados, você poderia incorporar essa verificação com relativa facilidade.
Uma abordagem alternativa (mas um tanto hacky) que pode valer a pena dar uma olhada em seu cenário seria ocultar a tabela e substituí-la por uma visualização.
Você pode isolar a tabela com um
FILESTREAM
em um banco de dados separado e criar uma referência a ela no banco dePRODUCTION
dados usando uma exibição.Isso permitiria que você fizesse o que quisesse sem recorrer a hacks.