Contexte
Nous développons un système avec une base de données de grande taille en bas. Il s'agit d'une base de données MS SQL exécutée sur SQL Server 2008 R2. La taille totale de la base de données est d'environ 12 Go.
Parmi ceux-ci, environ 8,5 Go se trouvent dans une seule table BinaryContent
. Comme son nom l'indique, il s'agit d'un tableau dans lequel nous stockons des fichiers simples, de toute nature, directement dans le tableau en tant que BLOB. Récemment, nous avons testé la possibilité de déplacer tous ces fichiers de la base de données vers le système de fichiers à l'aide de FILESTREAM.
Nous avons apporté les modifications nécessaires à notre base de données sans aucun problème, et notre système fonctionne toujours bien après la migration. Le BinaryContent
tableau ressemble à peu près à ceci:
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]
Avec tout ce qui réside dans le PRIMARY
groupe de fichiers, sauf le champ FileBinaryContent
qui se trouve dans un groupe de fichiers distinct FileStreamContentFG
.
Scénario
Du point de vue d'un développeur, nous souhaitons souvent une nouvelle copie de la base de données de notre environnement de production, pour pouvoir travailler les dernières données. Dans ces cas, nous sommes rarement intéressés par les fichiers stockés dans BinaryContent (utilisant désormais FILESTREAM).
Nous fonctionnons presque comme nous le souhaiterions. Nous sauvegardons la base de données, sans le flux de fichiers comme ceci:
BACKUP DATABASE FileStreamDB
FILEGROUP = 'PRIMARY'
TO DISK = 'c:\backup\FileStreamDB_WithoutFS.bak' WITH INIT
Et restaurez-le comme ceci:
RESTORE DATABASE FileStreamDB
FROM DISK = 'c:\backup\FileStreamDB_WithoutFS.bak'
Cela semble fonctionner correctement, et notre système fonctionne tant que nous évitons les pièces qui utilisent le FileBinaryContent
champ. Nous pouvons par exemple exécuter la requête suivante sans problème:
SELECT TOP 10 [BinaryContentID],[FileName],[BinaryContentRowGUID]
--,[FileContentBinary]
FROM [dbo].[BinaryContent]
Naturellement, si je commente la ligne ci-dessus, y compris FileContentBinary
dans la requête, j'obtiens une erreur:
Les données d'objets volumineux (LOB) pour la table "dbo.BinaryContent" résident sur un groupe de fichiers hors ligne ("FileStreamContentFG") auquel il n'est pas possible d'accéder.
Nos fichiers poignées de système où le contenu est défini sur null
, donc ce que je veux faire est quelque chose comme ceci:
UPDATE [dbo].[BinaryContent]
SET [FileContentBinary] = null
Mais cela me donne bien sûr la même erreur que ci-dessus. À ce stade, je suis coincé.
Question
Existe-t-il un moyen de restaurer la base de données sans avoir à tout restaurer également à partir duFileStreamContentFG
groupe de fichiers? Soit en mettant à jour les valeurs à null comme j'essaye ci-dessus, soit par défaut à null lorsque le fichier est manquant ou quelque chose?
Ou est-ce que j'aborde peut-être le problème de la mauvaise façon?
Je suis un développeur par nature et je n'ai pas beaucoup de connaissances en tant que DBA, alors excusez-moi si je néglige quelque chose de trivial ici.
Réponses:
Ce que vous essayez de faire laisserait la base de données dans un état (transactionnellement) incohérent, donc ce n'est pas possible.
Le livre blanc sur la disponibilité partielle de la base de données est un guide de référence utile et comprend un exemple de vérification de la connexion en ligne d'une table ou d'un fichier particulier. Si votre accès aux données se faisait par le biais de procédures stockées, vous pourriez relativement facilement intégrer cette vérification.
Une approche alternative (mais quelque peu hacky) qui pourrait valoir la peine d'être examinée dans votre scénario serait de masquer la table et de la remplacer par une vue.
la source
Vous pouvez isoler la table avec un
FILESTREAM
dans une base de données distincte et créer une référence à celle-ci dans laPRODUCTION
base de données à l'aide d'une vue.Cela vous permettrait de faire ce que vous voulez sans avoir recours à des hacks.
la source