Usunięcie FILESTREAM z backupu bazy


Ani Azure ani AWS nie wspierają funkcji FILESTREAM w bazach Microsoft SQL Server. Uniemożliwia to migrację z lokalnej bazy danych do chmury. Możemy sobie z tym jednak poradzić bez konieczności modyfikacji aplikacji. Wszytko, co musimy zrobić, to odpowiednio zmodyfikować bazę lub plik backupu.

Restore backup’u

Musimy pracować lokalnie na instancji, która faktycznie wspiera funkcję FILESTREAM. Możemy to zweryfikować następującym zapytaniem

SELECT
    SERVERPROPERTY('FileStreamShareName')        as Share_Name,  
    SERVERPROPERTY('FIleStreamConfiguredLevel') as Config_Level, 
    SERVERPROPERTY('FileStreamEffectiveLevel')     as Effective_Level

Znaczenie otrzymanych wartości jest następujące:

  • 0 – nie ma wsparcia
  • 1 – wsparcie dla sesji TSQL
  • 2 – wsparcie dla sesji TSQL i Win32

Jeśli widzimy 1 lub 2, to nasza instancja wspiera FILESTREAM i możemy odtworzyć backup.

Zaczynamy od wyciągnięcia prawidłowej nazwy bazy danych z pliku backupu

RESTORE HEADERONLY FROM DISK = 'C:\katalog_backupow\moja_baza.bak'

Weryfikujemy ścieżki, pod które będzie się chciała odtworzyć baza

RESTORE FILELISTONLY FROM DISK = 'C:\katalog_backupow\moja_baza.bak'

W tym przykładzie dostajemy następujący wynik:

LogicalNamePhysicalName
moja_bazaD:\DATA\moja_baza\moja_baza.mdf
moja_baza_logD:\DATA\moja_baza\moja_baza_log.ldf
moja_baza_filestreamD:\DATA\moja_baza\moja_baza_filestream

Zapamiętujemy nazwę logiczną [moja_baza_filestream]

Skomplikujmy sobie nieco scenariusz – załóżmy, że na naszej maszynie nie ma dysku D:\ za to mamy dużo miejsca na dysku E:\ Jesteśmy zatem zmuszeni użyć metody RESTORE WITH MOVE

Będzie to wyglądać tak:

RESTORE DATABASE
    [moja_baza]
FROM DISK = 'C:\katalog_backupow\moja_baza.bak'
WITH
MOVE 'moja_baza'                   TO 'E:\DATA\moja_baza\moja_baza.mdf',
MOVE 'moja_baza_log'            TO 'E:\DATA\moja_baza\moja_baza_log.ldf',
MOVE 'moja_baza_filestream' TO 'E:\DATA\moja_baza\moja_baza_filestream'

Zabezpieczenie danych

Pewną niedogodnością jest to, że musimy z góry znać każdą tabelę, która korzysta z FILESTREAM’u. Najlepiej jest zapytać o to opiekuna aplikacji. W naszym przykładzie będzie tylko jedna taka tabela: [moja_schema].[moja_tabela_1]

W celu zachowania danych tworzymy tabelę przejściową o nazwie [moja_schema].[moja_tabela_2]
Jej struktura musi być zgodna z [moja_schema].[moja_tabela_1]
Celowo nie używamy metody SELECT INTO.

CREATE TABLE [moja_schema].[moja_tabela_2]  (
    [file_id]        UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY NOT NULL,
    [file_stream]      varbinary(max) NULL,
    [file_name]             nvarchar(255) NOT NULL
ON [PRIMARY];

INSERT INTO [Documents].[Files_v2][Documents].[Files_v2] (
    [file_id],
    [file_stream],
    [file_name]
)
SELECT
    [file_id],
    [file_stream],
    [file_name]
FROM [moja_schema].[moja_tabela_1]

Usunięcie FILESTREAM’u

Jeżeli dotarliśmy do tego miejsca, to znaczy, że mamy sprawną bazę danych i zabezpieczyliśmy dane przed ich utratą. Możemy zatem przystąpić do usuwania FILESTREAM’u.

Ustalamy nazwę filegroup’y, która obsługuje FILESTREAM. W tym przykładzie to [FILESTREAM_FILEGROUP]

SELECT * FROM sys.filegroups

Dropujemy tabelę i usuwamy filegrupę. Poniższy przykład demonstruje również jak poradzić sobie z ewentualnym kluczem obcym odnoszącym się do usuwanej tabeli.

ALTER TABLE [moja_schema].[tabela_z_kluczem_obcym]  DROP CONSTRAINT [moj_constraint]
DROP TABLE  [moja_schema].[moja_tabela_1]
ALTER Database [moja_baza] REMOVE FILE              [moja_baza_filestream]
ALTER Database [moja_baza] REMOVE FILEGROUP [FILESTREAM_FILEGROUP]

Zamieniamy tabelę przejściową na tabelę docelową. Drugi argument poniższej komendy celowo nie ma podanej schemy

EXEC sp_rename 'moja_schema.moja_tabela_2','moja_tabela_1'

Na koniec odtwarzamy wspomniany wyżej klucz obcy. Powinno się to udać bez problemu, jeżeli INSERT z SELECT’em przeszły bezbłednie

ALTER TABLE 
    [moja_schema].[tabela_z_kluczem_obcym]  
WITH CHECK ADD  CONSTRAINT [moj_constraint] 
FOREIGN KEY([file_id]) 
REFERENCES [moja_schema].[moja_tabela_1] ([file_id])
,

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.