sql >> データベース >  >> RDS >> Sqlserver

MS SQLServer2017標準でのフェイルオーバーの実装

    はじめに

    多くの場合、特にEnterpriseエディションがなく、Standardエディションのみである場合は、MS SQLServerDBMSのフォールトトレランスを確保する必要があります。

    このインスタンスには重大な制限があるため、Expressエディションについては検討しません。もちろん、それらのいくつかをバイパスすることができます。たとえば、データベースサイズが10 GBの問題を解決するために、大きなデータベースを小さなデータベースに分割できます。これを行うには、特定のプロパティに基づいて新しいデータベースを作成し、プリンシパルデータベースのビューで異なるデータベースの同じテーブルからの選択を組み合わせることができます。ただし、Expressエディションのフォールトトレランスは、システム管理者によって、または独自のソフトウェアまたはサードパーティのソフトウェアを使用して実行されます。

    この記事では、MS SQL Server 2017の既存のすべての標準フォールトトレランステクノロジと、Standardエディションで最も適切なフォールトトレランスの統合標準を実装する例について説明します。

    簡単なレビュー

    1. 常にオン

      すべての関係者間での負荷分散、すべての関係者の特性は互いに類似している必要があります。同期モードは、データ送信の最大の信頼性を保証します。ただし、パフォーマンスは最も遅いパーティの速度と同じになります。非同期モードは最高のパフォーマンスを保証しますが、パーティ間でデータの不一致が発生する可能性があり、メンテナンスがより複雑になり、メインパーティに障害が発生した場合に最新の変更が失われる可能性があります。同期モードへの切り替え速度はほぼ瞬時に実行され、システム管理者とDBAは必要ありませんが、非同期モードでは、DB複製の現在の状態に依存し、通常は約5分かかります(システム管理者がいなくても、1人のDBAで切り替えプロセスを自動化できます)。 ).Microsoftは、データベースにこのテクノロジを使用することをお勧めします。これは、バージョン2012以降のEnterpriseエディションで利用可能であり、Standardエディションでは制限があります(詳細については、基本的な可用性グループに関する上位5つの質問を参照してください)。

    2. クラスタリング

      構成は単純ですが、単一のデータウェアハウスという形のボトルネックがあるため、このソリューションは信頼できません。データウェアハウスに障害が発生した場合、復元には1時間以上かかります。このテクノロジーは、バージョン2008以降のStandardエディションで利用できます。

    3. 複製

      レプリケーションには、参加しているテーブルごとにシステムトリガーを作成することが含まれますが、スナップショットレプリケーションはプリンシパルデータベースに大きな負荷をかけます。したがって、スナップショットレプリケーションは、データベースロードのオフピーク時間(たとえば、夜間)にのみ実行できます。これは、ホットスタンバイが必要なため、受け入れられません。マージレプリケーションは、一部のシステム(CRM、NAVなど)で維持するには複雑です。
      Enterprise Editionでは、トランザクションレプリケーションが可能です。 Standardエディション(マージおよびデータベーススナップショット)およびEnterpriseエディション(トランザクション)で、バージョン2008以降で使用できます。

    4. ミラーリング

      どのモードでも可能です。ただし、同期モードは最大の信頼性と高速スイッチングを保証し、非同期モードはユーザーにプリンシパルデータベースの最大パフォーマンス速度を提供します。ただし、パーティ間でデータの不一致が発生する可能性があり、切り替えが遅くなる可能性があります。

      ここで、監視サーバーまたはDBAは、データベースレベルで自動切り替えを提供します(たとえば、プリンシパルサーバーのCPU負荷が50%を超える場合)。システム管理者は、他のサーバーへの接続を許可します。あらゆるタイプのミラーリングのバックアップデータベースは継続的リカバリモードであるため、アクセスできません。

      データベースのリカバリモードがいっぱいです。

      Microsoftは、これを古いデータベーステクノロジと見なしています。 Standardエディション(同期モード)およびEnterpriseエディション(非同期モード)で、バージョン2008以降で使用できます。

    5. トランザクションログの送信

      スタンバイサーバーでの継続的なリカバリと遅延を伴うリカバリの2つのモードがあります。最初のモードでは、バックアップデータベースが継続的なリカバリモードに切り替わります。この場合、データベースにアクセスできません。

      2番目のモードでは、更新の展開中に定期的にバックアップデータベースをリカバリモードに切り替えます(バックアップデータベースは展開間で利用できますが、MS SQL Serverインスタンスが同じバージョンであれば可能です)。

      仕組み:

      1. 定期的に、データベーストランザクションログのバックアップコピーがソースサーバーとスタンバイサーバーのパブリックフォルダーに保存されます(ディレクトリとスケジュールはデフォルトで15分ごとに構成されます)。
      2. スタンバイサーバーは、データベースのトランザクションログバックアップをローカルフォルダーに定期的にコピーします(ディレクトリとスケジュールは、デフォルトで15分ごとに構成されます)。
      3. スタンバイサーバーは、トランザクションログのバックアップからトランザクションログを復元します(スケジュールはデフォルトで15分ごとに構成されます)。

      データベース管理者はデータベースレベルで切り替えプロセスを自動化できますが、システム管理者はサーバーへの接続レベルでこれを実行できます。

      また、この方法は常に非同期モードで機能することに注意してください。複数のバックアップデータベースを構成できます。

      データベースリカバリモードが完全または一括ログに記録されています。

      Standardエディションからバージョン2008以降で利用できます。

      スタンバイサーバーでの継続的なリカバリと遅延を伴うリカバリの2つのモードがあります。

    概要

    Standardエディションのトランザクションログ配布は、環境の更新時など、あるサーバーから別のサーバーへのスムーズな移行に便利なため、最も望ましい方法です。さらに、トランザクションログの配布はシンプルで使いやすく、同期ミラーリングモードとは異なり、データベースをあまりロードしない非同期モードで常に機能します。いずれの場合も、独自の自動切り替えを構成できる場合は、ミラーリングを使用できます。そうしないと、誤った切り替えが発生する可能性があります(たとえば、プリンシパルサーバーのCPUに50%を超える負荷がかかっている場合)。

    Enterpriseエディションの場合は、AlwaysOnテクノロジーを使用してください。

    トランザクションログ配布時のフェイルオーバーの構成

    トランザクションログ配布の構成の詳細については、こちらをご覧ください。さらに、繰り返し複数回使用するための独自のユーティリティを開発したり、フェイルオーバーの場合に修復後にプリンシパルサーバーに戻ったりすることで、このプロセスを自動化することができます。

    DBMSレベルでのトランザクションログ配布時のフェイルオーバーをデバッグするための可能なオプションの1つを調べてみましょう。

    この方法は、MS SQL Serverインスタンスの1つのインスタンスのみに予約されているサーバーに適していることに注意してください。複数のインスタンスでは、実行するタスクと実行しないタスクを決定する際に問題が発生するためです。

    手順の順序を説明しましょう:

    1. すべてのタスクを実行して、ソースから最新のファイルをコピーします(よく考えられたアーキテクチャでは、プリンシパルサーバーがダウンしている場合でもディレクトリにアクセスできる必要があります)
    2. ソースからファイルをコピーするためのすべてのタスクを無効にします
    3. ソースからの最新のファイルを使用してデータベースを復元するためのすべてのタスクを実行します
    4. ソースからの最新のファイルを使用して、すべてのデータベース復元タスクを無効にします
    5. データベースを復元し、ログ配布のプリンシパルにしますが、受信者は作成しません
    6. データベースの完全バックアップを作成する
    7. トランザクションログをバックアップするタスクを作成する

    以下に、上記のシーケンスをストアドプロシージャとして実装する例を示します。

    トランザクションログのバックアップを作成するためにタスクが実行されるログイン(できればドメインログイン)を構成することが重要であることに注意してください。

    トランザクションログ配布のフェイルオーバーのデバッグの例

    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

    プリンシパルサーバーに戻るには、スタンバイサーバーからプリンシパルサーバーへのトランザクションログ配布を構成してから、フェイルオーバーのデバッグを実行する必要があります。その後、プリンシパルサーバーが本番サーバーになります。その後、本番サーバーからスタンバイサーバーへのトランザクションログ配布を構成する必要があります。

    トランザクションログの出荷を監視するための自動調整の構成

    トランザクションログの出荷を監視するには、LSAlert_タスクと監視サーバーのレポートを使用します。これを行うには、監視サーバーでインスタンスを右クリックし、[レポート]/[標準レポート]/[トランザクションログの出荷ステータス]を選択します。

    非常に多くの場合、時間の経過とともに、監視サーバー(実稼働サーバーでない場合)は、実稼働サーバーでデータベーストランザクションログのバックアップを作成する最近の時間を誤って取得します。その結果、誤った警告に直面します。

    次のスクリプトを使用して問題を解決することができます:

    トランザクションログの出荷を監視するための調整を構成する例

    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

    ストアドプロシージャの呼び出しを時間ごとに自動化できます。たとえば、エージェントで適切なタスクを作成し、5分ごとにスケジュールすることができます。もちろん、本番サーバーはバックアップサーバー(サーバーオブジェクト\リンクサーバー)にリンクされている必要があります。

    ここでは、最新のデータベースバックアップを定義するSRVデータベースの[inf]。[vServerLastBackupDB]ビューを使用します。

    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;

    結果

    この記事では、MS SQL Server 2017で考えられるすべてのフォールトトレランスと迅速な可用性のオプション、およびフェイルオーバーのデバッグとトランザクションログ配布の監視の自動調整の実装例を簡単に確認しました。

    参照:

    • msdb
    • 利用可能なSQLServer2017エディション
    • 常時オン
    • SQLServerフェールオーバークラスターのインストール
    • レプリケーション
    • ミラーリング
    • ログ配布
    • ログ配布の構成

    1. PostgreSQL接続プール:パート1-長所と短所

    2. SQLiteで複合キーを自動生成する

    3. EBSR12の開始および停止スクリプト

    4. JSONファイルをPostgreSQLにインポートするにはどうすればよいですか?