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

Correzione della perdita di dati utilizzando il log shipping con recupero ritardato

Introduzione

Il log shipping delle transazioni è una tecnologia molto nota utilizzata in SQL Server per mantenere una copia del database attivo nel sito di ripristino di emergenza. La tecnologia dipende da tre processi chiave:il processo di backup, il processo di copia e il processo di ripristino. Mentre il processo di backup viene eseguito sul server primario, i processi di copia e ripristino vengono eseguiti sul server secondario. In sostanza, il processo prevede backup periodici del registro delle transazioni su una condivisione da cui il processo di copia si sposta sul server secondario; successivamente, il processo di ripristino applica i backup del registro al server secondario. Prima che tutto questo abbia inizio, il Database Secondario deve essere inizializzato con un backup completo dal server Primario ripristinato con l'opzione NORECOVERY.

Microsoft fornisce una serie di stored procedure che possono essere utilizzate per configurare Log Shipping end-to-end, nonché equivalenti della GUI a partire dall'elemento delle proprietà di ogni database per il quale potresti voler configurare Log Shipping. Da notare che il Database Secondario può essere configurato in modalità NORECOVERY oppure in modalità STANDBY. In modalità NORECOVERY il database non è mai disponibile per le query, ma in modalità STANDBY è possibile eseguire query sul database secondario quando non è in corso alcuna operazione di ripristino del registro delle transazioni.

Impostazione dell'ambiente

Per iniziare, creiamo due istanze SQL Server su AWS con un'immagine Amazon EC2 identica. Questa istanza Amazon EC2 esegue SQL Server 2017 RTM-CU5 su Windows Server 2016. Quindi ripristiniamo una copia del database WideWorldImporters utilizzando un set di backup acquisito da GitHub sulla prima istanza, la nostra istanza primaria. Utilizziamo lo stesso set di backup per creare due database identici denominati BranchDB e CorporateDB.

Fig. 1 versione di SQL Server

Fig. 2 BranchDB e CorporateDB su istanza primaria (istanza secondaria vuota)

Listato 1:ripristino del database di esempio di WideWorldImporters

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

Ora abbiamo due istanze, l'istanza primaria che ospita i due database primari (BranchDB e CorporateDB e l'istanza secondaria senza database utente. Procediamo con la configurazione del Transaction Log Shipping su entrambi i database ma li differenziamo applicando un ritardo al ripristino della configurazione del primo database. Ricordiamo che i database sono in realtà identici in termini di dati che contengono. Il grafico seguente mostra le opzioni chiave selezionate nella Configurazione Log Shipping.

Fig. 3 Impostazioni di backup per BranchDB

Fig. 4 Copia impostazioni per BranchDB

Fig. 5 Ripristina le impostazioni per BranchDB

Ogni processo di Log Shipping è configurato per l'esecuzione ogni cinque minuti. Per elaborare "Ritardo ripristino backup", è necessario utilizzare la modalità di ripristino standby nella configurazione Log Shipping. È logico poiché ha il database secondario in modalità standby e indica che possiamo interrogare il database secondario ogni volta che un ripristino del registro delle transazioni non è in corso. Il valore che specifichiamo in questa opzione (30 minuti in questo caso) ci offre una buona finestra durante la quale possiamo eseguire i rapporti dal database secondario oltre al requisito fondamentale di questo articolo che è essere in grado di recuperare dall'errore dell'utente.

Inoltre, dobbiamo menzionare che il ripristino dei backup del registro delle transazioni viene effettivamente ritardato. Il suo timestamp è successivo al valore del ritardo. Ciò significa che tutti i backup del registro delle transazioni verranno copiati sul server secondario, che è basato sulla pianificazione e specificato nel processo di copia. In effetti, il processo di ripristino verrà comunque eseguito secondo la pianificazione, ma i backup del registro delle transazioni (che non risalgono a 30 minuti prima) non verranno ripristinati. In sostanza, il database BranchDB Standby è 30 minuti indietro rispetto al database primario BranchDB. Per dimostrare questo ritardo, nella prossima sezione creeremo una tabella in entrambi i database e creeremo un lavoro che inserisce un record ogni minuto. Esamineremo questa tabella nei database secondari.

Le Impostazioni per il Database CorporateDB sono le stesse delle Figg. da 3 a 5, ad eccezione del processo di ripristino che NON è impostato per ritardare i backup del registro delle transazioni.

Fig. 6 Ripristina le impostazioni per CorporateDB

Verifica della configurazione

Una volta completata la configurazione, possiamo verificare che la configurazione sia OK e iniziare con l'osservazione del suo lavoro. Il rapporto sulla spedizione del registro delle transazioni ci mostra che il DB Branch è effettivamente in ritardo rispetto al CorporateDB in termini di ripristini:

Fig. 7a Rapporto di spedizione del registro delle transazioni sul server primario

Fig. 7b Rapporto di spedizione del registro delle transazioni sul server secondario

Inoltre, noterai il messaggio di seguito nella cronologia dei lavori di ripristino per BranchDB:

Fig. 8 Ripristini del registro delle transazioni saltati sul server secondario

Possiamo andare oltre con questa verifica creando una tabella e utilizzando un processo per popolare questa tabella con righe ogni minuto. Il lavoro è un modo semplice per simulare ciò che un'applicazione potrebbe fare su una tabella utente. Questo può mostrarci che questo ritardo è sicuramente mostrato nei dati dell'utente.

Listato 2 – Crea tabella log tracker

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)

Listato 3 – Crea lavoro per popolare la tabella di tracciamento log

/* ==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

Quando interroghiamo la tabella rispettivamente sui database primari, possiamo confermare (utilizzando la colonna RecordTime) che le righe corrispondono in BranchDB e CorporateDB. Quando esaminiamo la tabella nei database secondari, allo stesso modo, vediamo chiaramente che abbiamo un intervallo di 30 minuti tra BranchDB e CorporateDB.

Listato 4 – Interrogazione della tabella Log Tracker

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

Fig. 9 Tabelle Log Tracker corrispondono nei database primari

Fig. 10 tabelle Log Tracker hanno un gap di circa 30 minuti nei database secondari

Recupero da errore utente

Ora parliamo del vantaggio chiave di questo ritardo. Nello scenario in cui un utente elimina inavvertitamente una tabella, possiamo recuperare rapidamente i dati dal database secondario purché non sia trascorso il periodo di ritardo. In questo esempio, eliminiamo la tabella Sales.Orderlines su ENTRAMBI i database e verifichiamo che la tabella non esista più in ENTRAMBI i database.

Listato 5 – Eliminazione della tabella delle linee d'ordine

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

Fig. 11 Dropping Table Sales.Ordini

Quando cerchiamo la tabella sul server secondario, scopriamo che la tabella è ancora disponibile in ENTRAMBI i database. Pertanto, per CorporateDB abbiamo meno di cinque minuti per recuperare i dati. (Fig. 12). Ma una volta eseguito il successivo ripristino Cycle, perdiamo la tabella nel database del database aziendale. Per ripristinare questa tabella, è necessario eseguire il ripristino point-in-time utilizzando un backup completo in un ambiente separato e quindi estrarre questa tabella specifica. Sarai d'accordo che ci vorrà del tempo. Per la tabella BranchDB Orderlines, abbiamo un po' più di tempo e possiamo recuperare la tabella con una singola istruzione SQL su un server collegato (vedi Listato 6).

Fig. 12 Conto alla rovescia di cinque minuti:la tabella esiste in entrambi i database secondari

Fig. 13 25 minuti aggiuntivi per recuperare la tabella BranchDB

Listato 6 – Recupera tabella ordini

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

Fig. 14 Recuperare la tabella Sales.Orderlines di BranchDB

Quindi verifichiamo sul server primario (database BranchDB) che la tabella sia stata ripristinata.

Fig. 15 Recuperare la tabella Sales.Orderlines di BranchDB

Conclusione

SQL Server offre diversi modi per eseguire il ripristino dalla perdita di dati dovuta a diverse cause principali:guasto del disco, danneggiamento, errore dell'utente e così via. Il ripristino point-in-time dai backup è probabilmente il più noto di questi metodi. Per alcuni semplici casi di errore dell'utente o casi simili, in cui uno o due oggetti vengono persi, l'utilizzo di Transaction Log Shipping con Delayed Recovery è un buon approccio da considerare. Tuttavia, va notato che un database secondario, che è configurato rigorosamente per le esigenze di DR, deve essere selezionato per RPO inferiori.