Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Implémentation du basculement dans MS SQL Server 2017 Standard

Présentation

Souvent, nous devons garantir la tolérance aux pannes du SGBD MS SQL Server, en particulier lorsqu'il n'y a pas d'édition Enterprise, mais uniquement l'édition Standard.

Nous voudrions noter que nous n'allons pas examiner l'édition Express car il y a des restrictions importantes à cette instance. Bien sûr, nous pouvons contourner certains d'entre eux. Par exemple, pour résoudre le problème avec la taille de la base de données de 10 Go, nous pouvons diviser une grande base de données en plus petites. Pour ce faire, nous pouvons créer une nouvelle base de données basée sur une certaine propriété et combiner les sélections des mêmes tables de différentes bases de données dans les vues de la base de données principale. Cependant, la tolérance aux pannes dans l'édition Express sera effectuée soit par un administrateur système, soit à l'aide de votre propre logiciel ou d'un logiciel tiers.

Dans cet article, nous allons explorer toutes les technologies de tolérance aux pannes standard existantes pour MS SQL Server 2017 et un exemple de mise en œuvre de la norme unifiée de tolérance aux pannes la plus appropriée dans l'édition Standard.

Bref examen

  1. Toujours activé

    Répartition de la charge entre toutes les parties, toutes les parties doivent être similaires dans leurs caractéristiques les unes aux autres. Le mode synchrone garantit une fiabilité maximale de la transmission des données ; cependant, les performances seront égales à la vitesse de la partie la plus lente. Le mode asynchrone assure les performances les plus élevées, mais il peut y avoir des données incohérentes entre les parties, ce qui peut entraîner une maintenance plus complexe et la probabilité de perdre les dernières modifications en cas de défaillance de la partie principale. La vitesse de basculement en mode synchrone est presque instantané et ne nécessite pas d'administrateur système ni de DBA, tandis qu'en mode asynchrone, cela dépend de l'état actuel des doublons de DB et prend généralement environ 5 minutes (vous pouvez également automatiser le processus de commutation par un DBA sans administrateur système ).Microsoft recommande d'utiliser cette technologie pour une base de données. Il est disponible dans l'édition Enterprise à partir de la version 2012 et supérieure et avec des restrictions dans l'édition Standard (pour en savoir plus, veuillez vous référer aux 5 principales questions sur les groupes de disponibilité de base).

  2. Cluster

    Malgré la simplicité de configuration, cette solution n'est pas fiable en raison du goulot d'étranglement sous la forme d'un entrepôt de données unique. En cas de panne de l'entrepôt de données, il faudra plus d'une heure pour le restaurer. Cette technologie est disponible dans l'édition Standard de la version 2008 et supérieure.

  3. Réplication

    Toute réplication implique la création de déclencheurs système pour chaque table participante, tandis que la réplication d'instantané chargera fortement la base de données principale. Par conséquent, la réplication d'instantané ne peut être effectuée que pendant les heures creuses du chargement de la base de données (par exemple, la nuit), ce qui est inacceptable, car un secours automatique est nécessaire. La réplication de fusion est compliquée à maintenir par certains systèmes (par exemple, CRM, NAV).
    La réplication transactionnelle est possible dans l'édition Enterprise. Disponible dans l'édition Standard (fusion et instantanés de base de données) et l'édition Enterprise (transactions) jusqu'à la version 2008 et supérieure.

  4. Mise en miroir

    C'est possible dans n'importe quel mode. Cependant, le mode synchrone garantit une fiabilité maximale et une commutation rapide, tandis que le mode asynchrone offre aux utilisateurs la vitesse de performance maximale de la base de données principale. Cependant, des données non concordantes sont possibles entre les parties et le changement peut être lent.

    Ici, un serveur témoin ou DBA assure le basculement automatique au niveau de la base de données (par exemple, lorsque la charge CPU est supérieure à 50 % sur le serveur principal). Un administrateur système accorde la connexion à l'autre serveur. Une base de données de sauvegarde pour tout type de mise en miroir est en mode de récupération continue, elle n'est donc pas accessible.

    Un mode de récupération de la base de données est plein.

    Microsoft le considère comme une technologie de base de données obsolète. Il est disponible dans l'édition Standard (en mode synchrone) et dans l'édition Enterprise (en mode asynchrone) jusqu'à la version 2008 et supérieure.

  5. Envoi du journal des transactions

    Il existe deux modes :restauration continue sur un serveur de secours ou restauration avec retards. Le premier mode fait passer une base de données de sauvegarde en mode de récupération continue et dans ce cas, nous ne pouvons pas y accéder.

    Le deuxième mode fait basculer régulièrement la base de données de sauvegarde en mode de récupération lors du déploiement des mises à jour (la base de données de sauvegarde est disponible entre les déploiements, mais cela est possible à condition que les instances MS SQL Server soient de la même version).

    Comment ça marche :

    1. Périodiquement, une copie de sauvegarde du journal des transactions de la base de données est stockée dans un dossier public sur les serveurs source et de secours (le répertoire et la planification sont configurés toutes les 15 minutes par défaut).
    2. Le serveur de secours copie périodiquement la sauvegarde du journal des transactions de la base de données dans un dossier local (le répertoire et la planification sont configurés toutes les 15 minutes par défaut).
    3. Le serveur de secours restaure le journal des transactions à partir de la sauvegarde du journal des transactions (la planification est configurée toutes les 15 minutes par défaut).

    Les administrateurs de base de données peuvent automatiser le processus de commutation au niveau de la base de données, tandis qu'un administrateur système peut le faire au niveau de la connexion au serveur.

    De plus, il convient de noter que cette méthode fonctionne toujours en mode asynchrone. Vous pouvez configurer plusieurs bases de données de sauvegarde.

    Le mode de récupération de la base de données est complet ou journalisé en masse.

    Il est disponible dans l'édition Standard jusqu'à la version 2008 et supérieure.

    Il existe deux modes :la récupération continue sur un serveur de secours ou la récupération avec des retards.

Résumé

Le plus préférable est l'envoi des journaux de transactions dans l'édition Standard car il est pratique de l'utiliser pour une transition en douceur d'un serveur à un autre, par exemple lors de la mise à jour de l'environnement. De plus, l'envoi des journaux de transactions est simple et facile à utiliser, et fonctionne toujours en mode asynchrone, ce qui ne charge pas beaucoup la base de données, contrairement au mode de mise en miroir synchrone. Dans tous les cas, la mise en miroir est acceptable, s'il est possible de configurer sa propre commutation automatique ; sinon, un faux basculement est possible (par exemple, lorsque le CPU du serveur principal est chargé à plus de 50%).

Pour l'édition Enterprise, utilisez la technologie AlwaysOn.

Configuration du basculement lors de l'envoi du journal des transactions

Vous pouvez trouver des informations plus détaillées sur la configuration de l'envoi du journal des transactions ici. De plus, il est possible d'automatiser ce processus en développant votre propre utilitaire pour un usage multiple répétitif, ainsi que pour revenir au serveur principal après réparation en cas de basculement.

Explorons l'une des options possibles pour le débogage du basculement lors de l'envoi du journal des transactions au niveau du SGBD.

Il est à noter que cette méthode convient à un serveur réservé à une seule instance d'instance MS SQL Server, car, pour plusieurs instances, il y a un problème pour déterminer quelles tâches exécuter et lesquelles nous ne faisons pas.

Décrivons la séquence d'étapes :

  1. Effectuer toutes les tâches pour copier les derniers fichiers depuis la source (Avec une architecture bien pensée, le répertoire doit être accessible même si le serveur principal est en panne)
  2. Désactiver toutes les tâches pour copier des fichiers depuis la source
  3. Effectuer toutes les tâches pour restaurer une base de données en utilisant les derniers fichiers de la source
  4. Désactivez toutes les tâches de restauration de la base de données à l'aide des derniers fichiers de la source
  5. Restaurez la base de données et le principal pour l'envoi des journaux, mais sans destinataire
  6. Créer des sauvegardes complètes de la base de données
  7. Créer des tâches pour sauvegarder les journaux de transactions

Vous trouverez ci-dessous un exemple d'implémentation de la séquence mentionnée ci-dessus en tant que procédure stockée.

Il convient de noter qu'il est important de configurer une connexion (de préférence une connexion de domaine) sous laquelle les tâches seront effectuées pour créer des sauvegardes des journaux de transactions.

Un exemple de débogage du basculement de l'envoi du journal des transactions

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

Pour revenir au serveur principal, il est nécessaire de configurer l'envoi des journaux de transactions du serveur de secours vers le serveur principal, puis d'effectuer le débogage d'un basculement. Ensuite, le serveur principal deviendra le serveur de production. Après cela, vous devez configurer l'envoi du journal des transactions du serveur de production vers celui de secours.

Configuration de l'ajustement automatique pour surveiller l'envoi du journal des transactions

Pour surveiller l'envoi des journaux de transactions, utilisez la tâche LSAlert_ et un rapport sur le serveur de surveillance. Pour ce faire, cliquez avec le bouton droit sur l'instance sur le serveur de surveillance, puis sélectionnez Rapports/Rapport standard/État d'envoi du journal des transactions.

Très souvent, au fil du temps, le serveur de surveillance (au cas où il ne s'agirait pas d'un serveur de production) prend à tort l'heure récente de création d'une sauvegarde du journal des transactions de la base de données sur le serveur de production. En conséquence, nous sommes confrontés à de faux avertissements.

Il est possible de résoudre le problème en utilisant le script suivant :

Exemple de configuration de l'ajustement pour la surveillance de l'envoi des journaux de transactions

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

Nous pouvons automatiser un appel pour une procédure stockée par le temps. Par exemple, nous pouvons créer une tâche appropriée dans l'Agent et la programmer toutes les 5 minutes. Bien entendu, le serveur de production doit être lié au serveur de secours (Objets serveur\Serveurs liés).

Ici, nous utilisons la vue [inf].[vServerLastBackupDB] dans la base de données SRV qui définit les dernières sauvegardes de base de données :

Un exemple d'implémentation de la vue 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;

Résultat

Dans cet article, nous avons brièvement passé en revue toutes les options possibles de tolérance aux pannes et de disponibilité rapide dans MS SQL Server 2017, ainsi que des exemples de mise en œuvre du débogage du basculement et de l'ajustement automatique de la surveillance de l'envoi des journaux de transactions.

Références :

  • msdb
  • Éditions SQL Server 2017 disponibles
  • Toujours activé
  • Installation du cluster de basculement SQL Server
  • Réplication
  • Mise en miroir
  • Envoi de journaux
  • Configurer l'envoi des journaux