sql >> Base de Datos >  >> RDS >> Sqlserver

Implementación de conmutación por error en MS SQL Server 2017 Standard

Introducción

A menudo, necesitamos garantizar la tolerancia a fallas de MS SQL Server DBMS, especialmente, cuando no hay una edición Enterprise, sino solo la Standard.

Nos gustaría señalar que no vamos a examinar la edición Express porque existen restricciones significativas para esta instancia. Claro, podemos pasar por alto algunos de ellos. Por ejemplo, para resolver el problema con el tamaño de la base de datos de 10 GB, podemos dividir una base de datos grande en otras más pequeñas. Para hacer esto, podemos crear una nueva base de datos basada en una determinada propiedad y combinar las selecciones de las mismas tablas de diferentes bases de datos en las vistas de la base de datos principal. Sin embargo, la tolerancia a fallas en la edición Express será realizada por un administrador del sistema o mediante el uso de su propio software o de un tercero.

En este artículo, vamos a explorar todas las tecnologías estándar de tolerancia a fallas existentes para MS SQL Server 2017 y un ejemplo de implementación del estándar unificado de tolerancia a fallas más adecuado en la edición Standard.

Revisión breve

  1. Siempre encendido

    Distribución de carga entre todas las partes, todas las partes deben ser similares en sus características entre sí. El modo síncrono garantiza la máxima fiabilidad de la transmisión de datos; sin embargo, el rendimiento será igual a la velocidad del grupo más lento. El modo asíncrono garantiza el máximo rendimiento, pero puede haber datos que no coinciden entre las partes, lo que puede causar un mantenimiento más complejo y la probabilidad de perder los últimos cambios en caso de que falle la parte principal. La velocidad de cambio a un modo síncrono es casi instantáneo y no requiere un administrador del sistema y un DBA, mientras que en el modo asincrónico, depende del estado actual de los duplicados de la base de datos y generalmente toma alrededor de 5 minutos (también puede automatizar el proceso de cambio por un DBA sin un administrador del sistema ).Microsoft recomienda usar esta tecnología para una base de datos. Está disponible en la edición Enterprise a partir de la versión 2012 y superior y con restricciones en la edición Standard (para obtener más información, consulte las 5 preguntas principales sobre los grupos de disponibilidad básica).

  2. Agrupación

    A pesar de la simplicidad de configuración, esta solución no es confiable debido al cuello de botella en forma de un único almacén de datos. En caso de falla del almacén de datos, se tardará más de 1 hora en restaurarlo. Esta tecnología está disponible en la edición estándar de la versión 2008 y superior.

  3. Replicación

    Cualquier replicación implica la creación de activadores del sistema para cada tabla participante, mientras que la replicación de instantáneas cargará mucho la base de datos principal. Por lo tanto, la replicación de instantáneas solo se puede realizar durante las horas de menor actividad de la carga de la base de datos (por ejemplo, por la noche), lo cual es inaceptable, ya que es necesario un modo de espera activo. Es complicado mantener la replicación de mezcla en algunos sistemas (por ejemplo, CRM, NAV).
    La replicación transaccional es posible en la edición Enterprise. Disponible en la edición Standard (fusión e instantáneas de bases de datos) y la edición Enterprise (transacciones) hasta la versión 2008 y posteriores.

  4. Reflejo

    Es posible en cualquier modo. Sin embargo, el modo síncrono garantiza la máxima confiabilidad y una conmutación rápida, mientras que el modo asíncrono proporciona a los usuarios la máxima velocidad de rendimiento de la base de datos principal. Sin embargo, es posible que los datos no coincidan entre las partes y el cambio puede ser lento.

    Aquí, un servidor testigo o DBA proporciona el cambio automático en el nivel de la base de datos (por ejemplo, cuando la carga de la CPU supera el 50 % en el servidor principal). Un administrador del sistema otorga la conexión al otro servidor. Una base de datos de respaldo para cualquier tipo de duplicación está en modo de recuperación continua, por lo que no se puede acceder a ella.

    Un modo de recuperación de la base de datos está lleno.

    Microsoft lo considera como una tecnología de base de datos obsoleta. Está disponible en la edición Standard (en el modo síncrono) y en la edición Enterprise (en el modo asíncrono) hasta la versión 2008 y superior.

  5. Envío de registros de transacciones

    Hay dos modos:recuperación continua en un servidor en espera o recuperación con retrasos. El primer modo cambia una base de datos de respaldo a un modo de recuperación continua y, en este caso, no podemos acceder a ella.

    El segundo modo cambia la base de datos de respaldo a un modo de recuperación regularmente mientras se implementan actualizaciones (la base de datos de respaldo está disponible entre implementaciones, pero esto es posible siempre que las instancias de MS SQL Server sean de la misma versión).

    Cómo funciona:

    1. Periódicamente, se almacena una copia de seguridad del registro de transacciones de la base de datos en una carpeta pública en el servidor de origen y en espera (el directorio y la programación se configuran cada 15 minutos de forma predeterminada).
    2. El servidor en espera copia periódicamente la copia de seguridad del registro de transacciones de la base de datos en una carpeta local (el directorio y la programación se configuran cada 15 minutos de forma predeterminada).
    3. El servidor en espera restaura el registro de transacciones a partir de la copia de seguridad del registro de transacciones (la programación se configura cada 15 minutos de manera predeterminada).

    Los administradores de bases de datos pueden automatizar el proceso de cambio a nivel de base de datos, mientras que un administrador de sistemas puede hacerlo a nivel de conexión al servidor.

    Además, cabe señalar que este método siempre funciona en modo asíncrono. Puede configurar múltiples bases de datos de respaldo.

    El modo de recuperación de la base de datos está lleno o registrado de forma masiva.

    Está disponible en la edición Standard hasta la versión 2008 y superior.

    Hay dos modos:recuperación continua en un servidor en espera o recuperación con retrasos.

Resumen

El más preferible es el envío de registros de transacciones en la edición estándar porque es conveniente usarlo para una transición sin problemas de un servidor a otro, por ejemplo, al actualizar el entorno. Además, el envío del registro de transacciones es simple y fácil de usar, y siempre funciona en el modo asíncrono, que no carga mucho la base de datos, a diferencia del modo de duplicación síncrona. En cualquier caso, la duplicación es aceptable, si es posible configurar su propia conmutación automática; de lo contrario, es posible un cambio falso (por ejemplo, cuando la CPU del servidor principal está cargada en más del 50%).

Para la edición Enterprise, utilice la tecnología AlwaysOn.

Configurar la conmutación por error tras el envío del registro de transacciones

Puede encontrar información más detallada sobre cómo configurar el envío del registro de transacciones aquí. Además, es posible automatizar este proceso desarrollando su propia utilidad para un uso múltiple repetitivo, así como para volver al servidor principal después de haber sido reparado en caso de falla.

Exploremos una de las posibles opciones para depurar la conmutación por error en el envío del registro de transacciones a nivel de DBMS.

Cabe señalar que este método es adecuado para un servidor reservado para una sola instancia de instancia de MS SQL Server, ya que, para varias instancias, existe un problema para determinar qué tareas ejecutar y cuáles no.

Describamos la secuencia de pasos:

  1. Realice todas las tareas para copiar los archivos más recientes desde el origen (con una arquitectura bien pensada, el directorio debe ser accesible incluso si el servidor principal está inactivo)
  2. Deshabilitar todas las tareas para copiar archivos desde la fuente
  3. Realice todas las tareas para restaurar una base de datos usando los archivos más recientes de la fuente
  4. Desactive todas las tareas de restauración de la base de datos usando los archivos más recientes de la fuente
  5. Haga que la base de datos sea restaurada y principal para el trasvase de registros, pero sin un destinatario
  6. Crea copias de seguridad completas de la base de datos
  7. Crear tareas para realizar copias de seguridad de los registros de transacciones

A continuación, hay un ejemplo de implementación de la secuencia mencionada anteriormente como un procedimiento almacenado.

Cabe señalar que es importante configurar un inicio de sesión (preferiblemente un inicio de sesión de dominio) bajo el cual se realizarán las tareas para crear copias de seguridad de los registros de transacciones.

Un ejemplo de depuración de la conmutación por error del envío del registro de transacciones

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

Para volver al servidor principal, es necesario configurar el envío del registro de transacciones desde el servidor en espera al servidor principal y luego realizar la depuración de una conmutación por error. Luego, el servidor principal se convertirá en el servidor de producción. Después de eso, debe configurar el envío del registro de transacciones desde el servidor de producción al de reserva.

Configurar el ajuste automático para monitorear el envío del registro de transacciones

Para monitorear el envío del registro de transacciones, use la tarea LSAlert_ y un informe en el servidor de monitoreo. Para hacer esto, haga clic con el botón derecho en la instancia en el servidor de monitoreo y luego seleccione Informes/Informe estándar/estado de envío del registro de transacciones.

Muy a menudo, con el tiempo, el servidor de monitoreo (en caso de que no sea uno de producción) toma incorrectamente el tiempo reciente de creación de una copia de seguridad del registro de transacciones de la base de datos en el servidor de producción. Como resultado, enfrentamos advertencias falsas.

Es posible resolver el problema usando el siguiente script:

Un ejemplo de cómo configurar el ajuste para monitorear el envío del registro de transacciones

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

Podemos automatizar una llamada para un procedimiento almacenado por tiempo. Por ejemplo, podemos crear una tarea adecuada en el Agente y programarla cada 5 minutos. Por supuesto, el servidor de producción debe estar vinculado al servidor de respaldo (Objetos del servidor\Servidores vinculados).

Aquí usamos la vista [inf].[vServerLastBackupDB] en la base de datos SRV que define las últimas copias de seguridad de la base de datos:

Un ejemplo de implementación de la 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;

Resultado

En este artículo, hemos revisado brevemente todas las opciones posibles de tolerancia a fallas y disponibilidad rápida en MS SQL Server 2017, así como ejemplos de implementación de la depuración de la conmutación por error y el ajuste automático de la supervisión del envío del registro de transacciones.

Referencias:

  • msdb
  • Ediciones disponibles de SQL Server 2017
  • Siempre encendido
  • Instalación del clúster de conmutación por error de SQL Server
  • Replicación
  • Duplicar
  • Envío de registros
  • Configurar envío de registros