Database
 sql >> Datenbank >  >> RDS >> Database

Beheben von Datenverlust durch Protokollversand mit verzögerter Wiederherstellung

Einführung

Der Transaktionsprotokollversand ist eine sehr bekannte Technologie, die in SQL Server verwendet wird, um eine Kopie der Live-Datenbank auf der Disaster Recovery-Site zu verwalten. Die Technologie hängt von drei Schlüsseljobs ab:dem Sicherungsjob, dem Kopierjob und dem Wiederherstellungsjob. Während der Sicherungsjob auf dem Primärserver ausgeführt wird, werden die Kopier- und Wiederherstellungsjobs auf dem Sekundärserver ausgeführt. Im Wesentlichen umfasst der Prozess regelmäßige Sicherungen des Transaktionsprotokolls auf eine Freigabe, von der der Kopierauftrag auf den sekundären Server verschoben wird. Anschließend wendet der Wiederherstellungsjob die Protokollsicherungen auf dem sekundären Server an. Bevor dies alles beginnt, muss die sekundäre Datenbank mit einer vollständigen Sicherung vom primären Server initialisiert werden, die mit der Option NORECOVERY wiederhergestellt wurde.

Microsoft stellt eine Reihe gespeicherter Prozeduren bereit, mit denen der Protokollversand von Anfang bis Ende konfiguriert werden kann, sowie GUI-Äquivalente, beginnend mit dem Eigenschaftenelement jeder Datenbank, für die Sie den Protokollversand konfigurieren möchten. Beachten Sie, dass die sekundäre Datenbank im NORECOVERY-Modus oder im STANDBY-Modus konfiguriert werden kann. Im NORECOVERY-Modus steht die Datenbank niemals für Abfragen zur Verfügung, aber im STANDBY-Modus kann die sekundäre Datenbank abgefragt werden, wenn kein Transaktionsprotokoll-Wiederherstellungsvorgang im Gange ist.

Umgebung einrichten

Um den Stein ins Rollen zu bringen, erstellen wir zwei SQL Server-Instanzen auf AWS mit einem identischen Amazon EC2-Image. Auf dieser Amazon EC2-Instance wird SQL Server 2017 RTM-CU5 auf Windows Server 2016 ausgeführt. Dann stellen wir eine Kopie der WideWorldImporters-Datenbank mithilfe eines von GitHub erworbenen Sicherungssatzes auf der ersten Instance, unserer primären Instance, wieder her. Wir verwenden denselben Sicherungssatz, um zwei identische Datenbanken namens BranchDB und CorporateDB zu erstellen.

Abb. 1 SQL Server-Version

Abb. 2 BranchDB und CorporateDB auf primärer Instanz (sekundäre Instanz leer)

Listing 1:Wiederherstellen der WideWorldImporters-Beispieldatenbank

restore filelistonly from disk='WideWorldImporters-Full.bak'

restore database CorporateDB from disk='WideWorldImporters-Full.bak' with stats=10,recovery,

move 'WWI_Primary' to 'M:\MSSQL\Data\WWI_Primary.mdf' , move 'WWI_UserData' to 'M:\MSSQL\Data\WWI_UserData.ndf' , move 'WWI_Log' to 'N:\MSSQL\Log\WWI_Log.ldf',

move 'WWI_InMemory_Data_1' to 'M:\MSSQL\Data\WWI_InMemory_Data_1.ndf'

restore database BranchDB from disk='WideWorldImporters-Full.bak' with stats=10,recovery,

move 'WWI_Primary' to 'M:\MSSQL\Data\WWI_Primary1.mdf' , move 'WWI_UserData' to 'M:\MSSQL\Data\WWI_UserData1.ndf' , move 'WWI_Log' to 'N:\MSSQL\Log\WWI_Log1.ldf',

move 'WWI_InMemory_Data_1' to 'M:\MSSQL\Data\WWI_InMemory_Data_11.ndf

Wir haben jetzt zwei Instanzen, die primäre Instanz, die die beiden primären Datenbanken (BranchDB und CorporateDB) hostet, und die sekundäre Instanz ohne Benutzerdatenbanken. Wir fahren mit der Konfiguration des Transaktionsprotokollversands auf beiden Datenbanken fort, unterscheiden sie jedoch, indem wir eine Verzögerung auf die Wiederherstellungskonfiguration von anwenden erste Datenbank. Denken Sie daran, dass die Datenbanken in Bezug auf die Daten, die sie enthalten, tatsächlich identisch sind. Die folgenden Grafiken zeigen die wichtigsten Optionen, die in der Protokollversandkonfiguration ausgewählt wurden.

Abb. 3 Sicherungseinstellungen für BranchDB

Abb. 4 Einstellungen für BranchDB kopieren

Abb. 5 Wiederherstellungseinstellungen für BranchDB

Jeder Protokollversandauftrag ist so konfiguriert, dass er alle fünf Minuten ausgeführt wird. Um „Wiederherstellen von Sicherungen verzögern“ zu verarbeiten, müssen wir den Standby-Wiederherstellungsmodus in der Protokollversandkonfiguration verwenden. Dies ist logisch, da die sekundäre Datenbank im Standby-Modus ist und anzeigt, dass wir die sekundäre Datenbank abfragen können, wenn keine Transaktionsprotokollwiederherstellung ausgeführt wird. Der Wert, den wir in dieser Option angeben (in diesem Fall 30 Minuten), gibt uns ein gutes Zeitfenster, in dem wir Berichte aus der sekundären Datenbank ausführen können, abgesehen von der Kernanforderung dieses Artikels, die in der Lage ist, Benutzerfehler zu beheben.

Außerdem sollten wir erwähnen, dass sich die Wiederherstellung von Transaktionsprotokollsicherungen tatsächlich verzögert. Sein Zeitstempel ist später als der Verzögerungswert. Dies bedeutet, dass alle Transaktionsprotokollsicherungen auf den sekundären Server kopiert werden, was auf dem Zeitplan basiert und im Kopierauftrag angegeben ist. Tatsächlich wird der Wiederherstellungsjob weiterhin planmäßig ausgeführt, aber Transaktionsprotokollsicherungen (die nicht älter als 30 Minuten sind) werden nicht wiederhergestellt. Im Wesentlichen liegt die BranchDB-Standby-Datenbank 30 Minuten hinter der primären BranchDB-Datenbank. Um diese Verzögerung zu demonstrieren, erstellen wir im nächsten Abschnitt eine Tabelle in beiden Datenbanken und erstellen einen Job, der jede Minute einen Datensatz einfügt. Wir werden diese Tabelle in den sekundären Datenbanken untersuchen.

Die Einstellungen für die CorporateDB-Datenbank sind die gleichen wie in Abb. 3 bis 5, mit Ausnahme des Wiederherstellungsjobs, der NICHT darauf eingestellt ist, Transaktionsprotokollsicherungen zu verzögern.

Abb. 6 Einstellungen für CorporateDB wiederherstellen

Überprüfen der Konfiguration

Sobald die Konfiguration abgeschlossen ist, können wir überprüfen, ob die Konfiguration in Ordnung ist, und mit der Beobachtung ihrer Arbeit beginnen. Der Transaktionsprotokoll-Versandbericht zeigt uns, dass die Branch-DB der CorporateDB in Bezug auf Wiederherstellungen tatsächlich hinterherhinkt:

Abb. 7a Transaktionsprotokoll-Versandbericht auf Primärserver

Abb. 7b Transaktionsprotokoll-Versandbericht auf sekundärem Server

Außerdem sehen Sie die folgende Meldung im Verlauf des Wiederherstellungsauftrags für die BranchDB:

Abb. 8 Übersprungene Wiederherstellung des Transaktionsprotokolls auf dem sekundären Server

Wir können mit dieser Überprüfung weiter gehen, indem wir eine Tabelle erstellen und einen Job verwenden, um diese Tabelle jede Minute mit Zeilen zu füllen. Der Job ist eine einfache Möglichkeit, zu simulieren, was eine Anwendung mit einer Benutzertabelle machen könnte. Dies kann uns zeigen, dass diese Verzögerung definitiv in den Benutzerdaten angezeigt wird.

Listing 2 – Log-Tracker-Tabelle erstellen

use BranchDB

go

create table log_ship_tracker

( ID int identity (100,1)

,Database_Name sysname default db_name()

,RecordTime datetime default getdate()

,ServerName sysname default @@servername)



use CorporateDB

go

create table log_ship_tracker

( ID int identity (100,1)

,Database_Name sysname default db_name()

,RecordTime datetime default getdate()

,ServerName sysname default @@servername)

Listing 3 – Job zum Füllen der Log-Tracker-Tabelle erstellen

/* ==Scripting Parameters==

Source Server Version : SQL Server 2017 (14.0.3023)
Source Database Engine Edition : Microsoft SQL Server Standard Edition
Source Database Engine Type : Standalone SQL Server

Target Server Version : SQL Server 2017

Target Database Engine Edition : Microsoft SQL Server Standard Edition
Target Database Engine Type : Standalone SQL Server
*/

USE [msdb]

GO

/****** Object: Job [InsertRecords] Script Date: 7/2/2018 3:32:00 PM ******/

BEGIN TRANSACTION

DECLARE @ReturnCode INT

SELECT @ReturnCode = 0

/****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 7/2/2018 3:32:00 PM ******/

IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)

BEGIN

EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]'

IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

END

DECLARE @jobId BINARY(16)

EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'InsertRecords', @enabled=1,

@notify_level_eventlog=0,

@notify_level_email=0,

@notify_level_netsend=0,

@notify_level_page=0,

@delete_level=0,

@description=N'No description available.',

@category_name=N'[Uncategorized (Local)]',

@owner_login_name=N'kairos\kigiri', @job_id = @jobId OUTPUT

IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

/****** Object: Step [InsertRecords] Script Date: 7/2/2018 3:32:00 PM ******/

EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @[email protected],

@step_name=N'InsertRecords',

@step_id=1,

@cmdexec_success_code=0,

@on_success_action=1,

@on_success_step_id=0,

@on_fail_action=2,

@on_fail_step_id=0,

@retry_attempts=0,

@retry_interval=0,

@os_run_priority=0, @subsystem=N'TSQL',

@command=N'use BranchDB

go

insert into

log_ship_tracker

values

(db_name(),getdate(),@@servername)



use CorporateDB

go

insert into

log_ship_tracker

values

(db_name(),getdate(),@@servername)

GO',

@database_name=N'master',

@flags=0

IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @[email protected], @name=N'Schedule', @enabled=1,

@freq_type=4,

@freq_interval=1,

@freq_subday_type=4,

@freq_subday_interval=1,

@freq_relative_interval=0,

@freq_recurrence_factor=0,

@active_start_date=20180702,

@active_end_date=99991231,

@active_start_time=0,

@active_end_time=235959,

@schedule_uid=N'03e5f1b2-2e0b-4b30-8d60-3643c84aa08d' IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'

IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

COMMIT TRANSACTION

GOTO EndSave

QuitWithRollback:

IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION

EndSave:

GO

Wenn wir die Tabelle jeweils in den primären Datenbanken abfragen, können wir (unter Verwendung der RecordTime-Spalte) bestätigen, dass die Zeilen in BranchDB und CorporateDB übereinstimmen. Wenn wir die Tabelle in den sekundären Datenbanken auf die gleiche Weise untersuchen, sehen wir deutlich, dass wir eine 30-minütige Lücke zwischen BranchDB und CorporateDB haben.

Listing 4 – Abfragen der Log-Tracker-Tabelle

select top 10 @@servername [Current_Server],* from BranchDB.dbo.log_ship_tracker order by RecordTime desc

select top 10 @@servername [Current_Server], * from CorporateDB.dbo.log_ship_tracker order by RecordTime desc

Abb. 9 Log Tracker-Tabellen stimmen in Primärdatenbanken überein

Abb. 10 Log-Tracker-Tabellen haben eine ~30-Minuten-Lücke in sekundären Datenbanken

Wiederherstellung nach Benutzerfehler

Lassen Sie uns nun über den Hauptvorteil dieser Verzögerung sprechen. In dem Szenario, in dem ein Benutzer versehentlich eine Tabelle löscht, können wir die Daten schnell aus der sekundären Datenbank wiederherstellen, solange die Verzögerungszeit nicht abgelaufen ist. In diesem Beispiel löschen wir die Tabelle Sales.Orderlines in BEIDEN Datenbanken und prüfen, ob die Tabelle nicht mehr in BEIDEN Datenbanken existiert.

Listing 5 – Tabelle mit fallenden Bestellposten

drop table BranchDB.Sales.Orderlines

drop table CorporateDB.Sales.Orderlines

GO



use BranchDB

go

select

@@servername [Current_Server]

, db_name() [Database_Name]

, name

, schema_name(schema_id) [schema]

, type_desc

, create_date

, modify_date

from sys.tables where name='Orderlines'

GO



use CorporateDB

go

select

@@servername [Current_Server]

, db_name() [Database_Name]

, name

, schema_name(schema_id) [schema]

, type_desc

, create_date

, modify_date

from sys.tables where name='Orderlines'

GO

Abb. 11 Dropping-Tabelle Sales.Orderlines

Wenn wir auf dem sekundären Server nach der Tabelle suchen, stellen wir fest, dass die Tabelle noch in BEIDEN Datenbanken verfügbar ist. Daher haben wir für CorporateDB weniger als fünf Minuten Zeit, um die Daten wiederherzustellen. (Abb. 12). Aber sobald der nächste Wiederherstellungszyklus ausgeführt wird, verlieren wir die Tabelle in der Corporate DB-Datenbank. Um diese Tabelle wiederherzustellen, müssen wir eine Point-in-Time-Wiederherstellung mit einer vollständigen Sicherung in einer separaten Umgebung durchführen und dann diese spezifische Tabelle extrahieren. Sie werden zustimmen, dass es einige Zeit dauern wird. Für die BranchDB Orderlines-Tabelle haben wir etwas mehr Zeit und können die Tabelle mit einem einzigen SQL-Statement über einen Linked Server wiederherstellen (siehe Listing 6).

Abb. 12 Fünf-Minuten-Countdown:Tabelle existiert in beiden sekundären Datenbanken

Abb. 13 Zusätzliche 25 Minuten zum Wiederherstellen der BranchDB-Tabelle

Listing 6 – Tabelle „Bestellposten wiederherstellen“

USE [master]

GO

/****** Object: LinkedServer [10.2.1.84] Script Date: 7/2/2018 4:14:59 PM ******/

EXEC master.dbo.sp_addlinkedserver @server = N'10.2.1.84', @srvproduct=N'SQL Server'

/* For security reasons the linked server remote logins password is changed with ######## */

EXEC master.dbo.sp_addlinkedsrvlogin

@rmtsrvname=N'10.2.1.84',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpasswo rd=NULL

GO

select * into BranchDB.Sales.Orderlines from [10.2.1.84].BranchDB.Sales.Orderlines

Abb. 14 Stellen Sie die Tabelle Sales.Orderlines von BranchDB wieder her

Dann überprüfen wir den primären Server (BranchDB-Datenbank), ob die Tabelle wiederhergestellt ist.

Abb. 15 Stellen Sie die Tabelle Sales.Orderlines von BranchDB wieder her

Schlussfolgerung

SQL Server bietet eine Reihe von Möglichkeiten zur Wiederherstellung nach Datenverlust aus einer Vielzahl von Ursachen – Festplattenfehler, Beschädigung, Benutzerfehler usw. Die Point-in-Time-Wiederherstellung aus Backups ist wahrscheinlich die bekannteste dieser Methoden. Für bestimmte einfache Fälle von Benutzerfehlern oder ähnlichen Fällen, in denen ein oder zwei Objekte verloren gehen, ist die Verwendung des Transaktionsprotokollversands mit verzögerter Wiederherstellung ein guter Ansatz. Es sollte jedoch beachtet werden, dass für niedrigere RPOs eine sekundäre Datenbank ausgewählt werden muss, die ausschließlich für DR-Anforderungen konfiguriert ist.