Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Implementieren von Failover in MS SQL Server 2017 Standard

Einführung

Oft müssen wir die Fehlertoleranz von MS SQL Server DBMS sicherstellen, insbesondere wenn es keine Enterprise Edition gibt, sondern nur die Standard Edition.

Wir möchten darauf hinweisen, dass wir die Express-Edition nicht untersuchen werden, da es für diese Instanz erhebliche Einschränkungen gibt. Sicher, wir können einige von ihnen umgehen. Um beispielsweise das Problem mit der Datenbankgröße von 10 GB zu lösen, können wir eine große Datenbank in kleinere aufteilen. Dazu können wir eine neue Datenbank basierend auf einer bestimmten Eigenschaft erstellen und die Auswahlen aus denselben Tabellen verschiedener Datenbanken in den Ansichten in der Hauptdatenbank kombinieren. Die Fehlertoleranz in der Express Edition wird jedoch entweder von einem Systemadministrator oder durch die Verwendung Ihrer eigenen Software oder der Software von Drittanbietern durchgeführt.

In diesem Artikel werden wir alle bestehenden Standard-Fehlertoleranztechnologien für MS SQL Server 2017 und ein Beispiel für die Implementierung des am besten geeigneten einheitlichen Standards der Fehlertoleranz in der Standard Edition untersuchen.

Kurzer Rückblick

  1. Immer an

    Lastverteilung auf alle Parteien, alle Parteien sollten in ihren Eigenschaften einander ähnlich sein. Der synchrone Modus gewährleistet die maximale Zuverlässigkeit der Datenübertragung; die Leistung entspricht jedoch der Geschwindigkeit der langsamsten Partei. Der asynchrone Modus gewährleistet die höchste Leistung, aber es kann zu Datenabweichungen zwischen den Parteien kommen, was zu einer komplexeren Wartung und der Wahrscheinlichkeit führen kann, dass die letzten Änderungen im Falle eines Ausfalls der Hauptpartei verloren gehen. Die Geschwindigkeit des Umschaltens in einen synchronen Modus ist fast augenblicklich und erfordert keinen Systemadministrator und DBA, während es im asynchronen Modus vom aktuellen Zustand der DB-Duplikate abhängt und normalerweise etwa 5 Minuten dauert (Sie können den Umschaltvorgang auch durch einen DBA ohne Systemadministrator automatisieren ).Microsoft empfiehlt die Verwendung dieser Technologie für eine Datenbank. Es ist in der Enterprise-Edition ab Version 2012 und höher und mit Einschränkungen in der Standard-Edition verfügbar (Weitere Informationen finden Sie unter Top 5 Fragen zu Basic-Verfügbarkeitsgruppen).

  2. Clustering

    Trotz der Einfachheit der Konfiguration ist diese Lösung aufgrund des Engpasses in Form eines einzelnen Data Warehouse unzuverlässig. Im Falle eines Ausfalls des Data Warehouse dauert die Wiederherstellung über 1 Stunde. Diese Technologie ist in der Standard Edition ab Version 2008 verfügbar.

  3. Replikation

    Jede Replikation beinhaltet das Erstellen von Systemtriggern für jede teilnehmende Tabelle, während die Snapshot-Replikation die Prinzipaldatenbank stark belastet. Daher kann die Snapshot-Replikation nur außerhalb der Spitzenzeiten der Datenbanklast (z. B. nachts) durchgeführt werden, was nicht akzeptabel ist, da ein Hot-Standby erforderlich ist. Die Mergereplikation ist in einigen Systemen kompliziert zu verwalten (z. B. CRM, NAV).
    Transaktionsreplikation ist in der Enterprise Edition möglich. Verfügbar in der Standard-Edition (Merging und Datenbank-Snapshots) und der Enterprise-Edition (Transaktionen) bis zur Version 2008 und höher.

  4. Spiegelung

    Es ist in jedem Modus möglich. Der synchrone Modus gewährleistet jedoch maximale Zuverlässigkeit und schnelles Umschalten, während der asynchrone Modus Benutzern die maximale Leistungsgeschwindigkeit der Prinzipaldatenbank bietet. Es ist jedoch möglich, dass die Daten zwischen den Parteien nicht übereinstimmen, und das Umschalten kann langsam sein.

    Hier sorgt ein Zeugenserver oder DBA für die automatische Umschaltung auf Datenbankebene (z. B. wenn die CPU-Last auf dem Prinzipalserver über 50 % liegt). Ein Systemadministrator gewährt die Verbindung zum anderen Server. Eine Sicherungsdatenbank für jede Art von Spiegelung befindet sich in einem kontinuierlichen Wiederherstellungsmodus, sodass nicht darauf zugegriffen werden kann.

    Ein Wiederherstellungsmodus der Datenbank ist voll.

    Microsoft hält es für eine veraltete Datenbanktechnologie. Es ist in der Standard Edition (im synchronen Modus) und in der Enterprise Edition (im asynchronen Modus) bis Version 2008 und höher verfügbar.

  5. Transaktionsprotokollversand

    Es gibt zwei Modi:kontinuierliche Wiederherstellung auf einem Standby-Server oder Wiederherstellung mit Verzögerungen. Der erste Modus schaltet eine Sicherungsdatenbank in einen kontinuierlichen Wiederherstellungsmodus und in diesem Fall können wir nicht darauf zugreifen.

    Der zweite Modus schaltet die Sicherungsdatenbank während der Bereitstellung von Updates regelmäßig in einen Wiederherstellungsmodus (die Sicherungsdatenbank ist zwischen den Bereitstellungen verfügbar, dies ist jedoch möglich, sofern die MS SQL Server-Instanzen dieselbe Version aufweisen).

    Wie es funktioniert:

    1. In regelmäßigen Abständen wird eine Sicherungskopie des Datenbank-Transaktionsprotokolls in einem öffentlichen Ordner auf dem Quell- und Standby-Server gespeichert (das Verzeichnis und der Zeitplan werden standardmäßig alle 15 Minuten konfiguriert).
    2. Der Standby-Server kopiert regelmäßig die Transaktionsprotokollsicherung der Datenbank in einen lokalen Ordner (das Verzeichnis und der Zeitplan werden standardmäßig alle 15 Minuten konfiguriert).
    3. Der Standby-Server stellt das Transaktionsprotokoll aus der Sicherung des Transaktionsprotokolls wieder her (der Zeitplan ist standardmäßig alle 15 Minuten konfiguriert).

    Datenbankadministratoren können den Umschaltvorgang auf Datenbankebene automatisieren, während ein Systemadministrator dies auf der Verbindungsebene zum Server tun kann.

    Außerdem ist zu beachten, dass dieses Verfahren immer im asynchronen Modus arbeitet. Sie können mehrere Sicherungsdatenbanken konfigurieren.

    Der Datenbankwiederherstellungsmodus ist vollständig oder massenprotokolliert.

    Es ist in der Standard Edition bis zur Version 2008 und höher verfügbar.

    Es gibt zwei Modi:kontinuierliche Wiederherstellung auf einem Standby-Server oder Wiederherstellung mit Verzögerungen.

Zusammenfassung

Am besten ist der Versand von Transaktionsprotokollen in der Standard Edition, da es praktisch ist, es für einen reibungslosen Übergang von einem Server zu einem anderen zu verwenden, beispielsweise beim Aktualisieren der Umgebung. Darüber hinaus ist der Transaktionsprotokollversand einfach und leicht zu bedienen und arbeitet immer im asynchronen Modus, der die Datenbank im Gegensatz zum synchronen Spiegelungsmodus nicht stark belastet. In jedem Fall ist eine Spiegelung akzeptabel, wenn es möglich ist, eine eigene automatische Umschaltung zu konfigurieren; Andernfalls ist ein falsches Umschalten möglich (z. B. wenn die CPU des Prinzipalservers um mehr als 50 % belastet ist).

Verwenden Sie für die Enterprise Edition die AlwaysOn-Technologie.

Failover beim Versand von Transaktionsprotokollen konfigurieren

Ausführlichere Informationen zur Konfiguration des Transaktionsprotokollversands finden Sie hier. Darüber hinaus ist es möglich, diesen Prozess zu automatisieren, indem Sie ein eigenes Dienstprogramm für eine wiederholte Mehrfachnutzung entwickeln, sowie für die Rückkehr zum Hauptserver, nachdem dieser im Fall eines Failover repariert wurde.

Lassen Sie uns eine der möglichen Optionen zum Debuggen von Failover beim Versand von Transaktionsprotokollen auf DBMS-Ebene untersuchen.

Es sollte beachtet werden, dass diese Methode für einen Server geeignet ist, der nur für eine Instanz von MS SQL Server reserviert ist, da es bei mehreren Instanzen ein Problem gibt, zu bestimmen, welche Aufgaben ausgeführt werden sollen und welche nicht.

Lassen Sie uns die Abfolge der Schritte beschreiben:

  1. Führen Sie alle Aufgaben aus, um die neuesten Dateien aus der Quelle zu kopieren (Bei einer gut durchdachten Architektur muss das Verzeichnis zugänglich sein, auch wenn der Hauptserver ausgefallen ist)
  2. Deaktivieren Sie alle Aufgaben zum Kopieren von Dateien aus der Quelle
  3. Führen Sie alle Aufgaben aus, um eine Datenbank mit den neuesten Dateien aus der Quelle wiederherzustellen
  4. Deaktivieren Sie alle Datenbankwiederherstellungsaufgaben, die die neuesten Dateien aus der Quelle verwenden
  5. Stellen Sie die Datenbank und den Prinzipal für den Protokollversand wieder her, aber ohne Empfänger
  6. Erstellen Sie vollständige Backups der Datenbank
  7. Aufgaben erstellen, um Transaktionsprotokolle zu sichern

Nachfolgend finden Sie ein Beispiel für die Implementierung der oben genannten Sequenz als gespeicherte Prozedur.

Es ist zu beachten, dass es wichtig ist, ein Login (vorzugsweise ein Domain-Login) zu konfigurieren, unter dem die Aufgaben zum Erstellen von Backups von Transaktionsprotokollen ausgeführt werden.

Ein Beispiel für das Debuggen des Failover des Transaktionsprotokollversands

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

Um zum Prinzipalserver zurückzukehren, ist es erforderlich, den Transaktionsprotokollversand vom Standbyserver zum Prinzipalserver zu konfigurieren und dann das Debuggen eines Failovers durchzuführen. Dann wird der Prinzipalserver zum Produktionsserver. Danach müssen Sie den Transaktionsprotokollversand vom Produktionsserver zum Standby-Server konfigurieren.

Konfigurieren der automatischen Anpassung zur Überwachung des Transaktionsprotokollversands

Verwenden Sie zum Überwachen des Transaktionsprotokollversands die Aufgabe LSAlert_ und einen Bericht auf dem Überwachungsserver. Klicken Sie dazu mit der rechten Maustaste auf die Instanz auf dem Überwachungsserver und wählen Sie dann Berichte/Standardbericht/Transaktionsprotokoll-Versandstatus aus.

Im Laufe der Zeit nimmt der Überwachungsserver (falls es sich nicht um einen Produktionsserver handelt) häufig fälschlicherweise die letzte Zeit an, um eine Sicherung des Datenbanktransaktionsprotokolls auf dem Produktionsserver zu erstellen. Infolgedessen werden wir mit falschen Warnungen konfrontiert.

Es ist möglich, das Problem mit dem folgenden Skript zu lösen:

Ein Beispiel für die Konfiguration der Anpassung zur Überwachung des Versands von Transaktionsprotokollen

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

Wir können einen Aufruf für eine gespeicherte Prozedur nach Zeit automatisieren. Beispielsweise können wir im Agent eine entsprechende Aufgabe erstellen und alle 5 Minuten einplanen. Natürlich muss der Produktionsserver mit dem Backup-Server verbunden sein (Serverobjekte\Verknüpfte Server).

Hier verwenden wir die Ansicht [inf].[vServerLastBackupDB] in der SRV-Datenbank, die die neuesten Datenbanksicherungen definiert:

Ein Beispiel für die Implementierung der vServerLastBackupDB-Ansicht:

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;

Ergebnis

In diesem Artikel haben wir kurz alle möglichen Fehlertoleranz- und Schnellverfügbarkeitsoptionen in MS SQL Server 2017 sowie Beispiele für die Implementierung des Debugging von Failover und die automatische Anpassung der Überwachung des Transaktionsprotokollversands überprüft.

Referenzen:

  • msdb
  • Verfügbare SQL Server 2017-Editionen
  • Immer an
  • Installation des SQL Server-Failover-Clusters
  • Replikation
  • Spiegelung
  • Protokollversand
  • Protokollversand konfigurieren