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

Implementazione del failover in MS SQL Server 2017 Standard

Introduzione

Spesso è necessario garantire la tolleranza agli errori dei DBMS di MS SQL Server, soprattutto quando non esiste l'edizione Enterprise, ma solo quella Standard.

Vorremmo notare che non esamineremo l'edizione Express perché ci sono restrizioni significative a questa istanza. Certo, possiamo bypassarne alcuni. Ad esempio, per risolvere il problema con la dimensione del database di 10 GB, possiamo dividere un database di grandi dimensioni in database più piccoli. Per fare ciò, possiamo creare un nuovo database basato su una determinata proprietà e combinare le selezioni dalle stesse tabelle di database diversi nelle viste nel database principale. Tuttavia, la tolleranza agli errori nell'edizione Express verrà eseguita da un amministratore di sistema o utilizzando il tuo software o di terze parti.

In questo articolo esploreremo tutte le tecnologie di tolleranza agli errori standard esistenti per MS SQL Server 2017 e un esempio di implementazione dello standard unificato di tolleranza agli errori più adatto nell'edizione Standard.

Breve recensione

  1. Sempre acceso

    La distribuzione del carico tra tutte le parti, tutte le parti dovrebbero essere simili nelle loro caratteristiche tra loro. La modalità sincrona garantisce la massima affidabilità della trasmissione dei dati; tuttavia, la performance sarà uguale alla velocità della parte più lenta. La modalità asincrona garantisce le massime prestazioni, ma potrebbero esserci dati discordanti tra le parti, che possono causare una manutenzione più complessa e la probabilità di perdere le ultime modifiche in caso di guasto della parte principale. La velocità di passaggio a una modalità sincrona è quasi istantaneo e non richiede un amministratore di sistema e DBA, mentre in modalità asincrona, dipende dallo stato attuale dei duplicati DB e richiede solitamente circa 5 minuti (puoi anche automatizzare il processo di commutazione di un DBA senza un amministratore di sistema ).Microsoft consiglia di utilizzare questa tecnologia per un database. È disponibile nell'edizione Enterprise a partire dalla versione 2012 e successive e con limitazioni nell'edizione Standard (per ulteriori informazioni, fare riferimento alle 5 domande principali sui gruppi di disponibilità di base).

  2. Raggruppamento

    Nonostante la semplicità di configurazione, questa soluzione è inaffidabile a causa del collo di bottiglia nella forma di un unico data warehouse. In caso di guasto del data warehouse, ci vorrà più di 1 ora per ripristinarlo. Questa tecnologia è disponibile nell'edizione Standard della versione 2008 e successive.

  3. Replica

    Qualsiasi replica implica la creazione di trigger di sistema per ogni tabella partecipante, mentre la replica di snapshot caricherà pesantemente il database principale. Pertanto, la replica degli snapshot può essere eseguita solo durante le ore non di punta del caricamento del database (ad esempio, di notte), il che è inaccettabile, poiché è necessario un hot standby. La replica di tipo merge è complicata da gestire in alcuni sistemi (ad esempio, CRM, NAV).
    La replica transazionale è possibile nell'edizione Enterprise. Disponibile nell'edizione Standard (unione e snapshot di database) e nell'edizione Enterprise (transazioni) fino alla versione 2008 e successive.

  4. Specchio

    È possibile in qualsiasi modalità. Tuttavia, la modalità sincrona garantisce la massima affidabilità e rapidità di commutazione, mentre la modalità asincrona offre agli utenti la massima velocità di prestazione del database principale. Tuttavia, è possibile che i dati non corrispondano tra le parti e il passaggio potrebbe essere lento.

    Qui, un server di controllo o DBA fornisce il passaggio automatico a livello di database (ad esempio, quando il carico della CPU è superiore al 50% sul server principale). Un amministratore di sistema concede la connessione all'altro server. Un database di backup per qualsiasi tipo di mirroring è in modalità di ripristino continuo, quindi non è possibile accedervi.

    Una modalità di ripristino del database è piena.

    Microsoft la considera una tecnologia di database obsoleta. È disponibile nell'edizione Standard (in modalità sincrona) e nell'edizione Enterprise (in modalità asincrona) fino alla versione 2008 e successive.

  5. Spedizione registro transazioni

    Sono disponibili due modalità:ripristino continuo su un server in standby o ripristino con ritardi. La prima modalità cambia un database di backup in una modalità di ripristino continuo e in questo caso non possiamo accedervi.

    La seconda modalità imposta regolarmente il database di backup su una modalità di ripristino durante la distribuzione degli aggiornamenti (il database di backup è disponibile tra le distribuzioni, ma ciò è possibile a condizione che le istanze di MS SQL Server siano della stessa versione).

    Come funziona:

    1. Periodicamente, una copia di backup del registro delle transazioni del database viene archiviata in una cartella pubblica sul server di origine e di standby (la directory e la pianificazione sono configurate ogni 15 minuti per impostazione predefinita).
    2. Il server di standby copia periodicamente il backup del registro delle transazioni del database in una cartella locale (per impostazione predefinita, la directory e la pianificazione sono configurate ogni 15 minuti).
    3. Il server di standby ripristina il registro delle transazioni dal backup del registro delle transazioni (la pianificazione è configurata ogni 15 minuti per impostazione predefinita).

    Gli amministratori di database possono automatizzare il processo di commutazione a livello di database, mentre un amministratore di sistema può farlo a livello di connessione al server.

    Inoltre, va notato che questo metodo funziona sempre in modalità asincrona. Puoi configurare più database di backup.

    La modalità di ripristino del database è completa o con registrazione in blocco.

    È disponibile nell'edizione Standard fino alla versione 2008 e successive.

    Sono disponibili due modalità:ripristino continuo su un server in standby o ripristino con ritardi.

Riepilogo

La più preferibile è la spedizione del registro delle transazioni nell'edizione Standard perché è conveniente utilizzarla per una transizione graduale da un server all'altro, ad esempio, durante l'aggiornamento dell'ambiente. Inoltre, il log shipping delle transazioni è semplice e facile da usare, oltre a funzionare sempre in modalità asincrona, che non carica molto il database, a differenza della modalità di mirroring sincrono. In ogni caso è accettabile il mirroring, se è possibile configurare la propria commutazione automatica; in caso contrario, è possibile una falsa commutazione (ad esempio, quando la CPU del server principale viene caricata di oltre il 50%).

Per l'edizione Enterprise, usa la tecnologia AlwaysOn.

Configurazione del failover durante la spedizione del registro delle transazioni

Puoi trovare informazioni più dettagliate sulla configurazione della spedizione del registro delle transazioni qui. Inoltre, è possibile automatizzare questo processo sviluppando la propria utilità per un utilizzo multiplo ripetitivo, nonché per tornare al server principale dopo che è stato riparato in caso di failover.

Esaminiamo una delle possibili opzioni per il debug del failover durante la spedizione del log delle transazioni a livello di DBMS.

Va notato che questo metodo è adatto per un server riservato a una sola istanza dell'istanza di MS SQL Server, poiché, per diverse istanze, c'è un problema nel determinare quali attività eseguire e quali no.

Descriviamo la sequenza dei passaggi:

  1. Esegui tutte le attività per copiare i file più recenti dall'origine (con un'architettura ben congegnata, la directory deve essere accessibile anche se il server principale è inattivo)
  2. Disabilita tutte le attività per copiare i file dall'origine
  3. Esegui tutte le attività per ripristinare un database utilizzando i file più recenti dall'origine
  4. Disabilita tutte le attività di ripristino del database utilizzando i file più recenti dall'origine
  5. Rendi il database ripristinato e principale per il log shipping, ma senza un destinatario
  6. Crea backup completi del database
  7. Crea attività per eseguire il backup dei registri delle transazioni

Di seguito, c'è un esempio di implementazione della sequenza sopra menzionata come stored procedure.

Va notato che è importante configurare un login (preferibilmente un login di dominio) in base al quale verranno eseguite le attività per creare backup dei registri delle transazioni.

Un esempio di debug del failover della spedizione del registro delle transazioni

CREATE PROCEDURE [srv].[RunLogShippingFailover]
	@isfailover			bit=1,
	@login				nvarchar(255)=N'LOGIN', -- a domain login under which the tasks will be performed run to create backups of transaction logs.
	@backup_directory	nvarchar(255)=N'DIRECTORY'—public directory to send backups of transaction logs between MS SQL Server instances (for example, 'D:\Shared')
AS
	/*
	Moving the standby server to the main mode when the principal server is down if @ isfailover = 1 is fully automated
        when @isfailover equals 0, nothing happens - here we need to create anew the shipping log from the standby to the principal one,
        and then we need to switch to the principal server and then to configure the transaction log shipping again.
        this standby server is believed to receive backups of transaction logs from one server 
        */
BEGIN
	--if there is a shift switch to a standby server, you need to perform all the tasks to copy the latest files from the source
	if(@isfailover=1)
	begin
		select [job_id]
		into #jobs
		from [msdb].[dbo].[sysjobs]
		where [name] like 'LSCopy%';
	
		declare @job_id uniqueidentifier;
	
		while(exists(select top(1) 1 from #jobs))
		begin
			select top(1)
			@job_id=[job_id]
			from #jobs;
	
			begin try
				EXEC [msdb].dbo.sp_start_job @[email protected]_id;
			end try
			begin catch
			end catch
	
			delete from #jobs
			where [job_id][email protected]_id;
		end
		
		drop table #jobs;
	end
	
	--disable all the tasks for copying files from the source when switching to the backup server
	--enable all the tasks for copying files from the source when returning to the production server
	update [msdb].[dbo].[sysjobs]
	set [enabled]=case when (@isfailover=1) then 0 else 1 end
	where [name] like 'LSCopy%';
	
	--if we shift to a standby server, we need to perform all the tasks to restore databases by using the latest files from the source
	if(@isfailover=1)
	begin
		select [job_id]
		into #jobs2
		from [msdb].[dbo].[sysjobs]
		where [name] like 'LSRestore%';
	
		while(exists(select top(1) 1 from #jobs2))
		begin
			select top(1)
			@job_id=[job_id]
			from #jobs2;
	
			begin try
				EXEC [msdb].dbo.sp_start_job @[email protected]_id;
				EXEC [msdb].dbo.sp_start_job @[email protected]_id;
			end try
			begin catch
			end catch
	
			delete from #jobs2
			where [job_id][email protected]_id;
		end
		drop table #jobs2;
	end
	
	--disable all the tasks to restore databases using the latest files from the source when switching to a standby server
	--enable all the tasks to restore databases using the latest files when returning to the production server 
	update [msdb].[dbo].[sysjobs]
	set [enabled]=case when (@isfailover=1) then 0 else 1 end
	where [name] like 'LSRestore%';
	
	--when switching to a standby server, we make the database restorable and principal for log shipping without a recipient
	if(@isfailover=1)
	begin
		select [secondary_database] as [name]
		into #dbs
		from msdb.dbo.log_shipping_monitor_secondary
		where [secondary_server][email protected]@SERVERNAME;
	
		declare @db nvarchar(255);
	
		while(exists(select top(1) 1 from #dbs))
		begin
			select top(1)
			@db=[name]
			from #dbs;
	
			begin try
				RESTORE DATABASE @db WITH RECOVERY;
			end try
			begin catch
			end catch
	
			delete from #dbs
			where [name][email protected];
		end
	
		drop table #dbs;
	
		select [secondary_database] as [name]
		into #dbs2
		from msdb.dbo.log_shipping_monitor_secondary
		where [secondary_server][email protected]@SERVERNAME;
	
		declare @jobId BINARY(16);
		declare @command nvarchar(max);
	
		declare @dt nvarchar(255)=cast(YEAR(GetDate()) as nvarchar(255))
							  +'_'+cast(MONTH(GetDate()) as nvarchar(255))
							  +'_'+cast(DAY(GetDate()) as nvarchar(255))
							  +'_'+cast(DatePart(hour,GetDate()) as nvarchar(255))
							  +'_'+cast(DatePart(minute,GetDate()) as nvarchar(255))
							  +'.trn';
	
		declare @backup_job_name		nvarchar(255);
		declare @schedule_name			nvarchar(255);
		declare @disk					nvarchar(255);
		declare @uid					uniqueidentifier;
	
		while(exists(select top(1) 1 from #dbs2))
		begin
			select top(1)
			@db=[name]
			from #dbs2;
	
			set @[email protected]_directory+N'\'[email protected]+N'.bak';
			set @backup_job_name=N'LSBackup_'[email protected];
			set @schedule_name=N'LSBackupSchedule_'[email protected]@SERVERNAME+N'_'[email protected];
			set @command=N'declare @disk nvarchar(max)='+N''''[email protected]_directory+N'\'[email protected]+'_'[email protected]+N''''
						+N'BACKUP LOG ['[email protected]+'] TO DISK = @disk
							WITH NOFORMAT, NOINIT,  NAME = '+N''''[email protected]+N''''+N', SKIP, NOREWIND, NOUNLOAD,  STATS = 10;';
			set @uid=newid();
			
			begin try
				BACKUP DATABASE @db TO  DISK = @disk 
				WITH NOFORMAT, NOINIT,  NAME = @db, SKIP, NOREWIND, NOUNLOAD,  STATS = 10;
				
				EXEC msdb.dbo.sp_add_job @[email protected]_job_name, 
				@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)]', 
				@[email protected], @job_id = @jobId OUTPUT;
		
				EXEC msdb.dbo.sp_add_jobstep @[email protected], @[email protected]_job_name, 
				@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', 
				@[email protected], 
				@database_name=N'master', 
				@flags=0;
	
				EXEC msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1;
	
				EXEC msdb.dbo.sp_add_jobschedule @[email protected], @[email protected]_job_name, 
				@enabled=1, 
				@freq_type=4, 
				@freq_interval=1, 
				@freq_subday_type=4, 
				@freq_subday_interval=5, 
				@freq_relative_interval=0, 
				@freq_recurrence_factor=0, 
				@active_start_date=20171009, 
				@active_end_date=99991231, 
				@active_start_time=0, 
				@active_end_time=235959, 
				@[email protected];
	
				EXEC msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)';
			end try
			begin catch
			end catch
	
			delete from #dbs2
			where [name][email protected];
		end
	
		drop table #dbs2;
	end
END

Per tornare al server principale, è necessario configurare la spedizione del log delle transazioni dal server di standby a quello principale, quindi eseguire il debug di un failover. Quindi, il server principale diventerà il server di produzione. Successivamente, è necessario configurare la spedizione del registro delle transazioni dal server di produzione a quello di standby.

Configurazione dell'adeguamento automatico per il monitoraggio della spedizione del registro delle transazioni

Per monitorare la spedizione del registro delle transazioni, utilizzare l'attività LSAlert_ e un report sul server di monitoraggio. A tale scopo, fare clic con il pulsante destro del mouse sull'istanza sul server di monitoraggio, quindi selezionare Report/Report standard/Stato spedizione registro transazioni.

Abbastanza spesso, nel tempo, il server di monitoraggio (se non di produzione) impiega erroneamente l'ora recente di creazione di un backup del log delle transazioni del database sul server di produzione. Di conseguenza, dobbiamo affrontare falsi avvisi.

È possibile risolvere il problema utilizzando il seguente script:

Un esempio di configurazione dell'aggiustamento per il monitoraggio della spedizione del registro delle transazioni

CREATE PROCEDURE [srv].[AutoCorrectMonitorLogShipping] 
AS
BEGIN
	/*
		Adjustment of monitoring the transaction log shipping
	*/
	SET NOCOUNT ON;

    update t2
	set
	    t2.[last_backup_date]=t1.[BackupFinishDate]
	    ,t2.[last_backup_date_utc]=DateAdd(hour,-DateDiff(hour,GetUTCDate(),GetDate()),t1.[BackupFinishDate])
		,t2.[last_backup_file]=
RIGHT(t1.[PhysicalDeviceName], CHARINDEX('\',REVERSE(t1.[PhysicalDeviceName]),1)-1)

	from [PRODUCTION_INSTANCE_NAME].[SRV].[inf].[vServerLastBackupDB] as t1
	inner join [msdb].[dbo].[log_shipping_monitor_primary] as t2 on t1.[DBName] collate SQL_Latin1_General_CP1_CI_AS=t2.[primary_database] collate SQL_Latin1_General_CP1_CI_AS
	where t1.[BackupType]=N'log';
END

Possiamo automatizzare una chiamata per una stored procedure in base al tempo. Ad esempio, possiamo creare un'attività appropriata nell'Agente e pianificarla ogni 5 minuti. Naturalmente, il server di produzione deve essere collegato al server di backup (Oggetti server\Server collegati).

Qui utilizziamo la vista [inf].[vServerLastBackupDB] nel database SRV che definisce gli ultimi backup del database:

Un esempio di implementazione della vista vServerLastBackupDB:

CREATE VIEW [inf].[vServerLastBackupDB] as
with backup_cte as
(
    select
        bs.[database_name],
        backup_type =
            case bs.[type]
                when 'D' then 'database'
                when 'L' then 'log'
                when 'I' then 'differential'
                else 'other'
            end,
        bs.[first_lsn],
		bs.[last_lsn],
		bs.[backup_start_date],
		bs.[backup_finish_date],
		cast(bs.[backup_size] as decimal(18,3))/1024/1024 as BackupSizeMb,
        rownum = 
            row_number() over
            (
                partition by bs.[database_name], type 
                order by bs.[backup_finish_date] desc
            ),
		LogicalDeviceName = bmf.[logical_device_name],
		PhysicalDeviceName = bmf.[physical_device_name],
		bs.[server_name],
		bs.[user_name]
    FROM msdb.dbo.backupset bs
    INNER JOIN msdb.dbo.backupmediafamily bmf 
        ON [bs].[media_set_id] = [bmf].[media_set_id]
)
select
    [server_name] as [ServerName],
	[database_name] as [DBName],
	[user_name] as [USerName],
    [backup_type] as [BackupType],
	[backup_start_date] as [BackupStartDate],
    [backup_finish_date] as [BackupFinishDate],
	[BackupSizeMb], -- uncompressed size
	[LogicalDeviceName],
	[PhysicalDeviceName],
	[first_lsn] as [FirstLSN],
	[last_lsn] as [LastLSN]
from backup_cte
where rownum = 1;

Risultato

In questo articolo, abbiamo esaminato brevemente tutte le possibili opzioni di tolleranza agli errori e disponibilità rapida in MS SQL Server 2017, nonché esempi di implementazione del debug del failover e dell'adeguamento automatico del monitoraggio del log shipping delle transazioni.

Riferimenti:

  • msdb
  • Edizioni disponibili di SQL Server 2017
  • Sempre acceso
  • Installazione del cluster di failover di SQL Server
  • Replica
  • Mirroring
  • Spedizione log
  • Configura spedizione log