実際の案件で話に出そうな気がするので、軽く検証してみました。
Standard エディションで使用可能な「基本的な可用性グループ」では、
- プライマリ / セカンダリの 2 台構成
- 読み取り可能なセカンダリは利用できない
- 可用性グループに含められるデータベースは一つ
- リスナーを作成することが可能
- 複数の可用性グループを作成可能
というような制約があります。
通常の構築では、以下のような構成をとることになるかと思います。
このような構成をとった場合、データベースを跨いだクエリの実行などをどのように行うかの考慮が必要となってきます。
そこで、下のような構成を簡易的な方法を用いてとってみたいと思います。
基本的な構成としては、以下になります。
- リスナーを持つ可用性グループは一つ
- リスナーが動作しているノードに可用性グループを寄せる
AG02 はリスナーを持っている可用性グループで、他の可用性グループについてはリスナーを作成していません。
リスナーを持っているノードにすべての可用性グループが寄っていれば、リスナーに接続ができれば、すべての可用性データベースにアクセスができるということになります。
ということで、以下のようなスクリプトを作成してみました。
リスナーが含まれている可用性グループ以外をスクリプトが動作しているノードに寄せるためのスクリプトとなります。
Import-Module SQLPS -DisableNameChecking while($true){ # 可用性グループが含まれるクラスターリソースのグループを取得 $AGResource = Get-ClusterResource | ? ResourceType -eq "SQL Server Availability Group" # リスナーのクラスターグループを取得 $ListenerResource = Get-ClusterResource | ? {($_.OwnerGroup -In $AGResource.Name) -and ($_.ResourceType -eq "Network Name")} # フェールオーバー対象のクラスターグループを取得 $FailoverAG = $AGResource | ? OwnerNode -ne $ListenerResource.OwnerNode # スクリプトを実行しているノードに可用性グループをフェールオーバー $FailoverAG | %{Switch-SqlAvailabilityGroup ("SQLSERVER:\SQL\{0}\DEFAULT\AvailabilityGroups\{1}" -f $env:COMPUTERNAME, $_.Name)} Start-Sleep -Seconds 60 }
このスクリプトを可用性グループの各ノードに配置し、リスナーを含んでいるクラスターグループに「汎用アプリケーション」を作成して、上記のスクリプトが動作するようにします。
汎用アプリケーションは「Local System」で動作しますが、上記のスクリプトは「Switch-SqlAvailabilityGroup」を使用して、自身に可用性グループをフェールオーバーするものとなりますので「Local System」が自身で動作している SQL Server に対してアクセスができれば、フェールオーバーを実施できることになります。
# 他のノードに対してフェールオーバーをしようとすると、資格情報を使用した PSDriver の作成が必要となるのですが。
これのような汎用アプリケーションリソースがクラスターグループ内に存在していれば、そのクラスターグループが動作しているノードに、すべての可用性グループが寄ることになります。
他の可用性グループがフェールオーバーされたことを考慮し、一度のみの実行ではなく、60 秒間隔でフェールオーバーの実行を行うようにしています。
以下のような感じで動作します。
こまごまとした処理は考える必要がありますが基本的な仕組みを簡易な方法で実施するためには使えるのかなと。