Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Implementando Failover no MS SQL Server 2017 Standard


Introdução

Muitas vezes, precisamos garantir a tolerância a falhas do SGBD MS SQL Server, principalmente, quando não há edição Enterprise, mas apenas a Standard.

Gostaríamos de observar que não examinaremos a edição Express porque há restrições significativas para essa instância. Claro, podemos ignorar alguns deles. Por exemplo, para resolver o problema com o tamanho do banco de dados de 10 GB, podemos dividir um banco de dados grande em menores. Para fazer isso, podemos criar um novo banco de dados com base em uma determinada propriedade e combinar as seleções das mesmas tabelas de diferentes bancos de dados nas visualizações do banco de dados principal. No entanto, a tolerância a falhas na edição Express será executada por um administrador do sistema ou usando seu próprio software ou software de terceiros.

Neste artigo, vamos explorar todas as tecnologias de tolerância a falhas padrão existentes para o MS SQL Server 2017 e um exemplo de implementação do padrão unificado de tolerância a falhas mais adequado na edição Standard.


Revisão breve

  1. Sempre ativado


    Distribuição de carga entre todas as partes, todas as partes devem ser semelhantes em suas características entre si. O modo síncrono garante a máxima confiabilidade da transmissão de dados; no entanto, o desempenho será igual à velocidade da parte mais lenta. O modo assíncrono garante o mais alto desempenho, mas pode haver incompatibilidade de dados entre as partes, o que pode causar uma manutenção mais complexa e a probabilidade de perder as últimas alterações no caso de falha da parte principal. A velocidade de comutação para o modo síncrono é quase instantâneo e não requer um administrador de sistema e DBA, enquanto no modo assíncrono, depende do estado atual de duplicatas de banco de dados e geralmente leva cerca de 5 minutos (você também pode automatizar o processo de comutação por um DBA sem um administrador de sistema ).A Microsoft recomenda usar essa tecnologia para um banco de dados. Ele está disponível na edição Enterprise a partir da versão 2012 e superior e com restrições na edição Standard (para saber mais, consulte as 5 principais perguntas sobre grupos de disponibilidade básicos).
  2. Agrupamento


    Apesar da simplicidade de configuração, esta solução não é confiável devido ao gargalo na forma de um único data warehouse. Em caso de falha do data warehouse, levará mais de 1 hora para restaurá-lo. Essa tecnologia está disponível na edição Standard da versão 2008 e superior.
  3. Replicação


    Qualquer replicação envolve a criação de acionadores do sistema para cada tabela participante, enquanto a replicação de instantâneo carregará pesadamente o banco de dados principal. Portanto, a replicação de snapshots pode ser feita apenas fora do horário de pico da carga do banco de dados (por exemplo, à noite), o que é inaceitável, pois é necessário um hot standby. A replicação de mesclagem é complicada de ser mantida por alguns sistemas (por exemplo, CRM, NAV).
    A replicação transacional é possível na edição Enterprise. Disponível na edição Standard (mescla e instantâneos de banco de dados) e na edição Enterprise (transações) até a versão 2008 e superior.
  4. Espelhamento


    É possível em qualquer modo. No entanto, o modo síncrono garante a máxima confiabilidade e comutação rápida, enquanto o modo assíncrono fornece aos usuários a velocidade máxima de desempenho do banco de dados principal. No entanto, dados incompatíveis são possíveis entre as partes e a comutação pode ser lenta.

    Aqui, um servidor testemunha ou DBA fornece a alternância automática no nível do banco de dados (por exemplo, quando a carga da CPU é superior a 50% no servidor principal). Um administrador do sistema concede a conexão com o outro servidor. Um banco de dados de backup para qualquer tipo de espelhamento está em modo de recuperação contínua, portanto, não pode ser acessado.

    Um modo de recuperação do banco de dados está cheio.

    A Microsoft considera isso como uma tecnologia de banco de dados desatualizada. Está disponível na edição Standard (no modo síncrono) e na edição Enterprise (no modo assíncrono) até a versão 2008 e superior.
  5. Envio do registro de transações


    Existem dois modos:recuperação contínua em um servidor em espera ou recuperação com atrasos. O primeiro modo alterna um banco de dados de backup para um modo de recuperação contínua e, neste caso, não podemos acessá-lo.

    O segundo modo alterna o banco de dados de backup para um modo de recuperação regularmente durante a implantação de atualizações (o banco de dados de backup está disponível entre implantações, mas isso é possível desde que as instâncias do MS SQL Server sejam da mesma versão).

    Como funciona:
    1. Periodicamente, uma cópia de backup do log de transações do banco de dados é armazenada em uma pasta pública no servidor de origem e em espera (o diretório e a programação são configurados a cada 15 minutos por padrão).
    2. O servidor em espera copia periodicamente o backup do log de transações do banco de dados para uma pasta local (o diretório e a programação são configurados a cada 15 minutos por padrão).
    3. O servidor em espera restaura o log de transações do backup do log de transações (o agendamento é configurado a cada 15 minutos por padrão).

    Os administradores de banco de dados podem automatizar o processo de comutação no nível do banco de dados, enquanto um administrador do sistema pode fazer isso no nível de conexão com o servidor.

    Além disso, deve-se notar que este método sempre funciona no modo assíncrono. Você pode configurar vários bancos de dados de backup.

    O modo de recuperação do banco de dados é completo ou registrado em massa.

    Está disponível na edição Standard até a versão 2008 e superior.

    Existem dois modos:recuperação contínua em um servidor em espera ou recuperação com atrasos.

Resumo

O mais preferível é o envio do log de transações na edição Standard porque é conveniente usá-lo para uma transição suave de um servidor para outro, por exemplo, ao atualizar o ambiente. Além disso, o envio do log de transações é simples e fácil de usar, além de funcionar sempre no modo assíncrono, que não carrega muito o banco de dados, ao contrário do modo de espelhamento síncrono. Em qualquer caso, o espelhamento é aceitável, se for possível configurar sua própria comutação automática; caso contrário, a comutação falsa é possível (por exemplo, quando a CPU do servidor principal é carregada em mais de 50%).

Para a edição Enterprise, use a tecnologia AlwaysOn.

Configurando o failover no envio do log de transações


Você pode encontrar informações mais detalhadas sobre como configurar o envio do log de transações aqui. Além disso, é possível automatizar esse processo desenvolvendo seu próprio utilitário para um uso múltiplo repetitivo, bem como para retornar ao servidor principal após ser reparado em caso de failover.

Vamos explorar uma das opções possíveis para depurar o failover no envio do log de transações em um nível de DBMS.

Deve-se notar que este método é adequado para um servidor reservado para apenas uma instância do MS SQL Server, pois, para várias instâncias, há um problema em determinar quais tarefas executar e quais não executar.

Vamos descrever a sequência de etapas:
  1. Realize todas as tarefas para copiar os arquivos mais recentes da fonte (com uma arquitetura bem pensada, o diretório deve estar acessível mesmo se o servidor principal estiver inativo)
  2. Desabilite todas as tarefas para copiar arquivos da fonte
  3. Realize todas as tarefas para restaurar um banco de dados usando os arquivos mais recentes da fonte
  4. Desabilite todas as tarefas de restauração do banco de dados usando os arquivos mais recentes da origem
  5. Torne o banco de dados restaurado e principal para o envio de logs, mas sem um destinatário
  6. Criar backups completos do banco de dados
  7. Crie tarefas para fazer backup de logs de transações

Abaixo, há um exemplo de implementação da sequência mencionada acima como um procedimento armazenado.

Deve-se notar que é importante configurar um login (de preferência um login de domínio) sob o qual serão executadas as tarefas para criar backups de logs de transações.

Um exemplo de depuração do failover do envio do log de transações
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 retornar ao servidor principal, é necessário configurar o envio do log de transações do servidor em espera para o principal e, em seguida, realizar a depuração de um failover. Em seguida, o servidor principal se tornará o servidor de produção. Depois disso, você precisa configurar o envio do log de transações do servidor de produção para o de espera.

Configurando o ajuste automático para monitorar o envio do log de transações


Para monitorar o envio do log de transações, use a tarefa LSAlert_ e um relatório no servidor de monitoramento. Para fazer isso, clique com o botão direito do mouse na instância no servidor de monitoramento e selecione Relatórios/relatório padrão/status de envio do log de transações.

Muitas vezes, ao longo do tempo, o servidor de monitoramento (caso não seja de produção) incorretamente usa o tempo recente para criar um backup do log de transações do banco de dados no servidor de produção. Como resultado, enfrentamos falsos avisos.

É possível resolver o problema usando o seguinte script:

Um exemplo de configuração do ajuste para monitorar o envio do log de transações
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 uma chamada para um procedimento armazenado por tempo. Por exemplo, podemos criar uma tarefa apropriada no Agente e agendá-la a cada 5 minutos. Obviamente, o servidor de produção deve estar vinculado ao servidor de backup (objetos de servidor\servidores vinculados).

Aqui usamos a visualização [inf].[vServerLastBackupDB] no banco de dados SRV que define os backups de banco de dados mais recentes:

Um exemplo de implementação da visualização 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


Neste artigo, revisamos brevemente todas as opções possíveis de tolerância a falhas e disponibilidade rápida no MS SQL Server 2017, bem como exemplos de implementação da depuração de failover e ajuste automático de monitoramento do envio do log de transações.

Referências:

  • msdb
  • Edições do SQL Server 2017 disponíveis
  • Sempre ativo
  • Instalação de cluster de failover do SQL Server
  • Replicação
  • Espelhamento
  • Envio de registros
  • Configurar envio de log