SQL Server 2017 の AlwaysOn 可用性グループでは、CLUSTER_TYPE=EXTERNAL を設定することで、可用性グループの切り替えをクラスターマネージャー主導で実施することができます。
というより、EXTERNAL を使用した場合、通常の方法ですとフェールオーバーができないようにロックされているんですよね。
とはいっても、SQL Server ですので何らかの方法で、SQL Server に対してクエリを実行してフェールオーバーを実行しているのではと思って調べてみました。
結論を書くと、EXTERNAL を使っていても、クエリベースでフェールオーバーを実行することは可能でした。
EXTERNAL の場合、プライマリ / セカンダリの切り替えについては次の SQL で実行することが可能です。
ALTER AVAILABILITY GROUP [ag1] SET (ROLE = SECONDARY) GO
これでプライマリとセカンダリを切り替えることができるのですが、セカンダリをプライマリに昇格させるために、プライマリにしたいサーバーでフェールオーバーを実行しようとすると次のエラーが発生するという状態となります。
ALTER AVAILABILITY GROUP [ag1] FAILOVER GO
メッセージ 47104、レベル 16、状態 1、行 1
外部のクラスター タイプが含まれるため、可用性グループ ‘ag1’ に対してこの操作を実行できません。
クラスター管理ツールを使用して操作を実行してください。
単純にフェールオーバーを実行しようとすると、このようなエラーとなり、フェールオーバーを行うことができません。
それでは、CLUSTER_TYPE=EXTERNAL がどのようにして、フェールオーバーを実行しているかというと、特定のセッションコンテキストが設定されている場合には、フェールオーバーができるというような仕組みとなっているようです。
単純に FAILOVER を実行しただけではエラーとなってしまいますが、フェールオーバーを実行するセッション内で、次のセッションコンテキストが設定されている場合にはフェールオーバーを実行することができるようになります。
EXEC sp_set_session_context @key = N'external_cluster', @value = N'yes', @read_only = 1 GO
先ほどのフェールオーバーのクエリを次のようにして実行します。
EXEC sp_set_session_context @key = N'external_cluster', @value = N'yes', @read_only = 1 GO ALTER AVAILABILITY GROUP [ag1] FAILOVER GO
そうすると、エラーとならずに実行することができ、プライマリとセカンダリの切り替えをクエリベースで実行することができます。
クラスターマネージャーで管理されている場合は、クラスターマネージャー以外から手動で設定を変更してしまうと、クラスターマネージャーで管理されているプライマリ / セカンダリの状態と、SQL Server のセカンダリ、プライマリの状態が不整合を起こしてしまうため、クラスターマネージャー側ではエラーが発生 / クラスターマネージャーの管理しているプライマリ / セカンダリの状態にフェールオーバーさせてしまうというような動作が行われるようですが。
クラスタベースでフェールオーバーを実行できる方法を知っておくと、独自のクラスターマネージャーを実装することができるかもしれないですね。