Kontekst
Opracowujemy system z dużą bazą danych na dole. Jest to baza danych MS SQL działająca na SQL Server 2008 R2. Całkowity rozmiar bazy danych wynosi około 12 GB.
Spośród nich około 8,5 GB znajduje się w jednej tabeli BinaryContent
. Jak sama nazwa wskazuje, jest to tabela, w której przechowujemy proste pliki dowolnego rodzaju bezpośrednio w tabeli jako BLOB. Ostatnio testowaliśmy możliwość przeniesienia wszystkich tych plików z bazy danych do systemu plików za pomocą FILESTREAM.
Dokonaliśmy niezbędnych modyfikacji naszej bazy danych bez żadnych problemów, a nasz system nadal działa dobrze po migracji. BinaryContent
Tabela wygląda mniej więcej tak:
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]
Wszystko znajduje się w PRIMARY
grupie plików, z wyjątkiem pola FileBinaryContent
znajdującego się w osobnej grupie plików FileStreamContentFG
.
Scenariusz
Z punktu widzenia dewelopera często chcielibyśmy mieć świeżą kopię bazy danych z naszego środowiska produkcyjnego, aby móc pracować z najnowszymi danymi. W takich przypadkach rzadko jesteśmy zainteresowani plikami przechowywanymi w BinaryContent (teraz za pomocą FILESTREAM).
To działa prawie tak, jak byśmy tego chcieli. Wykonujemy kopię zapasową bazy danych, bez takiego strumienia plików:
BACKUP DATABASE FileStreamDB
FILEGROUP = 'PRIMARY'
TO DISK = 'c:\backup\FileStreamDB_WithoutFS.bak' WITH INIT
I przywróć go w następujący sposób:
RESTORE DATABASE FileStreamDB
FROM DISK = 'c:\backup\FileStreamDB_WithoutFS.bak'
Wygląda na to, że działa OK, a nasz system działa tak długo, jak omijamy części wykorzystujące FileBinaryContent
pole. Możemy na przykład uruchomić następujące zapytanie bez problemu:
SELECT TOP 10 [BinaryContentID],[FileName],[BinaryContentRowGUID]
--,[FileContentBinary]
FROM [dbo].[BinaryContent]
Oczywiście, jeśli nie skomentuję powyższej linii, w tym FileContentBinary
w zapytaniu, otrzymuję błąd:
Dane dużych obiektów (LOB) dla tabeli „dbo.BinaryContent” znajdują się w grupie plików offline („FileStreamContentFG”), do której nie można uzyskać dostępu.
Nasze uchwyty plików systemowych, w których zawartość jest ustawiony na null
, więc co ja lubię robić coś takiego:
UPDATE [dbo].[BinaryContent]
SET [FileContentBinary] = null
Ale to oczywiście daje mi taki sam błąd jak powyżej. W tym momencie utknąłem.
Pytanie
Czy istnieje sposób na przywrócenie bazy danych bez konieczności przywracania wszystkiego z FileStreamContentFG
grupy plików? Albo aktualizując wartości do null, gdy próbuję powyżej, lub domyślnie do null, gdy brakuje pliku lub coś?
A może podchodzę do problemu w niewłaściwy sposób?
Jestem programistą z natury i nie mam zbyt dużej wiedzy jako DBA, więc przepraszam, jeśli pomijam tutaj jakąś trywialną rzecz.
źródło
Odpowiedzi:
To, co próbujesz zrobić, pozostawiłoby bazę danych w niespójnym (transakcyjnie) stanie, dlatego nie jest to możliwe.
Częściowa Database Dostępność whitepaper jest przydatny podręcznik i zawiera przykładowe, jak sprawdzić, czy dana tabela lub plik jest online. Jeśli dostęp do danych odbywa się za pomocą procedur przechowywanych, można stosunkowo łatwo włączyć tę kontrolę.
Jednym z alternatywnych (ale nieco hackerskich) podejść, które warto sprawdzić w twoim scenariuszu, byłoby ukrycie stołu i zastąpienie go widokiem.
źródło
Możesz wyizolować tabelę za pomocą
FILESTREAM
oddzielnej bazy danych i utworzyć odwołanie do niej wPRODUCTION
bazie danych za pomocą widoku.To pozwoli ci robić, co chcesz, bez uciekania się do hacków.
źródło