Pełna kopia zapasowa w SQL Server 2008 nie przerywa łańcucha dziennika. Resetuje tylko różnicowy base-lsn.
Można również przywrócić kopie zapasowe dziennika po przywróceniu tylko z kopii. Poniższe wersje demonstracyjne skryptu, które:
CREATE DATABASE BakTst13;
GO
ALTER DATABASE BakTst13 SET RECOVERY FULL;
GO
USE BakTst13;
GO
CREATE TABLE dbo.tst(id INT IDENTITY(1,1));
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13
TO DISK = 'BakTst13_Full_1' WITH INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP LOG BakTst13
TO DISK = 'BakTst13_Log_1' WITH INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13
TO DISK = 'BakTst13_Full_2' WITH INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13
TO DISK = 'BakTst13_Full_C' WITH COPY_ONLY,INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP LOG BakTst13
TO DISK = 'BakTst13_Log_2' WITH INIT,FORMAT;
GO
USE tempdb;
GO
DROP DATABASE BakTst13;
GO
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Full_1' WITH NORECOVERY;
RESTORE LOG BakTst13 FROM DISK='BakTst13_Log_1' WITH NORECOVERY;
RESTORE LOG BakTst13 FROM DISK='BakTst13_Log_2' WITH RECOVERY;
GO
SELECT * FROM BakTst13.dbo.tst;
GO
DROP DATABASE BakTst13;
GO
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Full_C' WITH NORECOVERY;
RESTORE LOG BakTst13 FROM DISK='BakTst13_Log_2' WITH RECOVERY;
GO
SELECT * FROM BakTst13.dbo.tst;
GO
DROP DATABASE BakTst13;
Tworzy bazę danych i tabelę i wstawia do niej 50 wierszy. Pomiędzy tymi wstawkami wykonanych jest kilka kopii zapasowych w następującej kolejności:
- Pełny
- Log
- Pełny
- Pełna kopia tylko
- Log
Następnie baza danych jest usuwana i przywracana w następujący sposób:
- 1. pełne
- 1. dziennik
- 2nd Log
Poniżej SELECT
pokazano, że przywracanie zakończyło się powodzeniem.
To pokazuje, że COP_ONLY
ani normalna, ani pełna kopia zapasowa nie przerywają łańcucha dziennika.
Następnie baza danych jest ponownie usuwana i przywracana w następujący sposób:
- Copy_Only Full
- 2nd Log
Potem znów SELECT
pokazuje sukces.
To pokazuje, że możesz użyć COPY_ONLY
pełnej kopii zapasowej jako podstawy przywracania dziennika.
Testy różnicowe
Stworzyłem też DIFFERENTIAL
wersję:
CREATE DATABASE BakTst13;
GO
ALTER DATABASE BakTst13 SET RECOVERY FULL;
GO
USE BakTst13;
GO
CREATE TABLE dbo.tst(id INT IDENTITY(1,1));
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13
TO DISK = 'BakTst13_Full_1' WITH INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13
TO DISK = 'BakTst13_Diff_1' WITH DIFFERENTIAL,INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13
TO DISK = 'BakTst13_Full_2' WITH INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13
TO DISK = 'BakTst13_Diff_2' WITH DIFFERENTIAL,INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13
TO DISK = 'BakTst13_Full_C' WITH COPY_ONLY,INIT,FORMAT;
GO
INSERT INTO dbo.tst DEFAULT VALUES
GO 10
GO
BACKUP DATABASE BakTst13
TO DISK = 'BakTst13_Diff_3' WITH DIFFERENTIAL,INIT,FORMAT;
GO
USE tempdb;
GO
DROP DATABASE BakTst13;
GO
RAISERROR('------> Starting restore F1, D1, D2',0,1)WITH NOWAIT;
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Full_1' WITH NORECOVERY;
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Diff_1' WITH NORECOVERY;
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Diff_2' WITH NORECOVERY;--<--Fails!
GO
DROP DATABASE BakTst13;
GO
RAISERROR('------> Starting restore FC, D3',0,1)WITH NOWAIT;
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Full_C' WITH NORECOVERY;
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Diff_3' WITH NORECOVERY;--<--Fails!
GO
DROP DATABASE BakTst13;
GO
RAISERROR('------> Starting restore F2, D2, D3',0,1)WITH NOWAIT;
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Full_2' WITH NORECOVERY;
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Diff_2' WITH NORECOVERY;
RESTORE DATABASE BakTst13 FROM DISK='BakTst13_Diff_3' WITH RECOVERY;
GO
SELECT * FROM BakTst13.dbo.tst;
GO
DROP DATABASE BakTst13;
To zajmuje kopie zapasowe w tej kolejności:
- 1. pełne
- 1. dyferencjał
- 2. pełne
- 2. dyferencjał
- Copy_Only Diff
- 3 dyferencjał
Następnie próbuje wykonać tę trasę przywracania:
- 1. pełne
- 1. dyferencjał
- 2. dyferencjał
Krok 3 kończy się niepowodzeniem z powodu tego błędu:
Msg 3136, Level 16, State 1, Line 4
This differential backup cannot be restored because the database has not been restored to the correct earlier state.
To pokazuje, że normalna pełna kopia zapasowa przerywa łańcuch różnicowy.
Następnie baza danych jest usuwana i następuje próba przywrócenia:
- Copy_Only Full
- 3 dyferencjał
Krok 2 kończy się niepowodzeniem z takim samym błędem jak krok 3 powyżej. To pokazuje, że kopia zapasowa tylko kopii nie może być używana jako podstawa do różnicowego przywracania.
Następnie baza danych jest ponownie usuwana i wykonywane jest następujące przywracanie:
- 2. pełne
- 2. dyferencjał
- 3 dyferencjał
Poniższy wybór potwierdza, że przywracanie powiodło się. To pokazuje, że COPY_ONLY
pełna kopia zapasowa nie przerywa łańcucha różnicowego.
Oto, co dzieje się, gdy w grę wchodzą różnice:
Jednym słowem: tak, możesz użyć
COPY_ONLY
kopii zapasowej, aby przywrócić kolejne kopie zapasowe dziennika. Nie możesz użyćCOPY_ONLY
kopii zapasowej jako bazy różnicowej. Oznacza to, że nie będzie można przywrócić różnicowych kopii zapasowych na przywróconejCOPY_ONLY
kopii zapasowej:Jeśli spróbujesz tego, pojawi się błąd:
Różnicowe kopie zapasowe mogą być trudne do zrozumienia i mogą oszukać nawet doświadczonych DBA.
źródło