SQLServer で高可用性を実現するための機能として、AlwaysOnという機能があります。
このAlwaysOnを利用している際に、以下のようなコトをPowerShellを利用して確認することができます。
- 可用性グループの状態
- 可用性レプリカの状態
- 可用性グループ内のプライマリサーバやセカンダリサーバのホスト名
などなど。
同期されていないときの調査やフェイルオーバーした際の状態確認などにも利用できると思います。この記事の内容を少し応用すれば、Zabbix などの監視ツールでフェイルオーバーしたかどうかの監視をすることもできます。
AlwaysOnのステータスをPowerShellで確認する
まず、PowerShellでSQLServerのインスタンスやオブジェクトを操作するためには、SQL Server PowerShell モジュールを利用する必要があります。
以下は、SQLServer PowerShell についてのMicrosoftのページからの引用です。
2 つの SQL Server PowerShell モジュールがあります。
SQLPS: このモジュールは (後方互換性のため) SQL Server のインストールに含まれていますが、今後更新されることはありません。 最新の PowerShell モジュールは SqlServer モジュールです。
SqlServer: このモジュールには、最新の SQL 機能をサポートする新しいコマンドレットが含まれています。 モジュールには、SQLPS 内のコマンドレットの更新バージョンも含まれています。
推奨は、SqlServerモジュールだが、SQLPS はSQLServer自体のインストールに含まれているため、追加の設定やインストールが不要で利用することができるということのようです。
今回は、別途インストールの必要がなく利用できる SQLPS を利用することにします。
コマンドプロンプトやPowerShellコンソールで、sqlps コマンドを最初に実行するだけで、SQLServerに接続することができます。
sqlps を実行したら、以下のコマンドを実行可能になります。
可用性グループとプライマリサーバの確認
以下の階層をGet-Childitemすることで、構成されている可用性グループを確認できる。
1 2 3 4 5 6 |
PS > Get-ChildItem SQLSERVER:\sql\$(hostname)\DEFAULT\AvailabilityGroups Name PrimaryReplicaServerName ---- ------------------------ AG_HOGE_DB SQL-NODE02 ALWAYS SQL-NODE02 |
上記では、『AG_HOGE_DB』と『ALWAYS』という二つの可用性グループがあります。
※$(hostname)の変数は展開されてコマンドを実行しているホストの名前がはいります。
階層の構造としては以下のようになっているので自分のホスト名が入ればOKです。
1 2 3 4 5 |
PS > Get-ChildItem SQLSERVER:\sql\ MachineName ----------- sql-node02 |
where-objectで可用性グループ名を指定すれば、指定した可用性グループの情報だけが確認できる。
1 2 3 4 5 |
PS > Get-ChildItem SQLSERVER:\sql\$(hostname)\DEFAULT\AvailabilityGroups | Where-Object { $_.name -eq 'AG_HOGE_DB' } Name PrimaryReplicaServerName ---- ------------------------ AG_HOGE_DB SQL-NODE02 |
更に、この可用性グループのプライマリサーバのホスト名が知りたければ以下のように指定すれば良い。
こんな感じで「ホスト名だけ」がとれれば、例えば Zabbix で UserParameter を利用して、フェイルオーバーの監視なんかもできる。
zabbixで監視する方法は別の記事でまとめます。
1 2 |
PS > (Get-ChildItem SQLSERVER:\sql\$(hostname)\DEFAULT\AvailabilityGroups | Where-Object { $_.name -eq 'AG_HOGE_DB' }).PrimaryReplicaServerName SQL-NODE02 |
スクリプトに書くときなんかは、一度変数に入れたほうが後で見たときにわかりやすいですね。
1 2 3 |
PS > $i=Get-ChildItem SQLSERVER:\sql\$(hostname)\DEFAULT\AvailabilityGroups | Where-Object { $_.name -eq 'AG_HOGE_DB' } PS > $i.PrimaryReplicaServerName SQL-NODE02 |
可用性レプリカの確認
以下のように実行することで、可用性グループ内の可用性レプリカ(AlwaysOnでクラスタを構成するホスト)の一覧を表示できる。
1 2 3 4 5 6 |
PS > Get-ChildItem SQLSERVER:\sql\$(hostname)\DEFAULT\AvailabilityGroups\AG_HOGE_DB\AvailabilityReplicas └→可用性グループ名 Name Role ConnectionState RollupSynchronizationState ---- ---- --------------- -------------------------- SQL-NODE01 Secondary Connected Synchronized SQL-NODE02 Primary Connected Synchronized |
以下でAlwaysOnを構成するホストを指定すれば、そのホストだけの情報を取得できる。
1 2 3 4 5 |
PS > Get-ChildItem SQLSERVER:\sql\$(hostname)\DEFAULT\AvailabilityGroups\AG_HOGE_DB\AvailabilityReplicas | Where-Object { $_.name -eq "SQL-NODE02" } Name Role ConnectionState RollupSynchronizationState ---- ---- --------------- -------------------------- SQL-NODE02 Primary Connected Synchronized |
そのホストが、現在PrimaryなのかSecondaryなのかを知りたければ以下。
1 2 |
PS> (Get-ChildItem SQLSERVER:\sql\$(hostname)\DEFAULT\AvailabilityGroups\AG_HOGE_DB\AvailabilityReplicas | Where-Object { $_.name -eq "SQL-NODE02" }).Role Primary |
この辺もフェイルオーバーを検知するための監視で使えますね。前回値から変化があった場合にアラートを発報させるようにすればフェイルオーバーを検知することができます。Zabbixでやるので別記事でまとめる予定です。
可用性グループ内の可用性レプリカの健全性を評価する
1.AvailabilityReplicas配下で各ノードの一覧を確認できる。
1 2 3 4 5 6 |
PS> Get-ChildItem SQLSERVER:\sql\sql-node02\default\AvailabilityGroups\AG_HOGE_DB\AvailabilityReplicas Name Role ConnectionState RollupSynchronizationState ---- ---- --------------- -------------------------- SQL-NODE01 Secondary Connected Synchronized SQL-NODE02 Primary Connected Synchronized |
2.Test-SqlAvailabilityReplica コマンドレットを使うことで可用性レプリカ(各ホスト)のステータスを確認できる。
1 2 3 4 5 6 |
PS> Get-ChildItem SQLSERVER:\sql\sql-node02\default\AvailabilityGroups\AG_HOGE_DB\AvailabilityReplicas | Test-SqlAvailabilityReplica HealthState AvailabilityGroup Name ----------- ----------------- ---- Healthy AG_HOGE_DB SQL-NODE01 Healthy AG_HOGE_DB SQL-NODE02 |
2-1.SQL-NODE01のステータスを確認する場合
1 2 3 4 5 |
PS> Get-ChildItem SQLSERVER:\sql\sql-node02\default\AvailabilityGroups\AG_HOGE_DB\AvailabilityReplicas | Test-SqlAvailabilityReplica | where { $_.name -eq "sql-node01" } HealthState AvailabilityGroup Name ----------- ----------------- ---- Healthy AG_HOGE_DB SQL-NODE01 |
2-2.ステータスだけとりたければ以下のように。
1 2 |
PS> (Get-ChildItem SQLSERVER:\sql\sql-node02\default\AvailabilityGroups\AG_HOGE_DB\AvailabilityReplicas | Test-SqlAvailabilityReplica | where { $_.name -eq "sql-node01" }).HealthState Healthy |
3-1.試しに SQL-NODE01 のSQLSERVERのサービスを停止してみると、HealthState が Healthy → Warning → Error に変化したところを確認できました。
1 2 3 4 5 6 7 8 9 10 11 |
PS> Get-ChildItem SQLSERVER:\sql\sql-node02\default\AvailabilityGroups\AG_HOGE_DB\AvailabilityReplicas | Test-SqlAvailabilityReplica | where { $_.name -eq "sql-node01" } HealthState AvailabilityGroup Name ----------- ----------------- ---- Warning AG_HOGE_DB SQL-NODE01 PS> Get-ChildItem SQLSERVER:\sql\sql-node02\default\AvailabilityGroups\AG_HOGE_DB\AvailabilityReplicas | Test-SqlAvailabilityReplica | where { $_.name -eq "sql-node01" } HealthState AvailabilityGroup Name ----------- ----------------- ---- Error AG_HOGE_DB SQL-NODE01 |
4-1.エラー状態にある(健全でない)可用性レプリカを確認する場合
現在の各ノード(可用性レプリカ)の状態は以下。
1 2 3 4 5 6 |
PS> Get-ChildItem SQLSERVER:\sql\sql-node02\default\AvailabilityGroups\AG_HOGE_DB\AvailabilityReplicas | Test-SqlAvailabilityReplica HealthState AvailabilityGroup Name ----------- ----------------- ---- Error AG_HOGE_DB SQL-NODE01 Healthy AG_HOGE_DB SQL-NODE02 |
4-2.エラーステータスのノード(可用性レプリカ)を取得する
1 2 3 4 5 |
PS> Get-ChildItem SQLSERVER:\sql\sql-node02\default\AvailabilityGroups\AG_HOGE_DB\AvailabilityReplicas | Test-SqlAvailabilityReplica | Where-Object { $_.HealthState -eq "Error" } HealthState AvailabilityGroup Name ----------- ----------------- ---- Error AG_HOGE_DB SQL-NODE01 |
4-3.ヘルシーステータス以外のノード(可用性レプリカ)を取得する
1 2 3 4 5 |
PS> Get-ChildItem SQLSERVER:\sql\sql-node02\default\AvailabilityGroups\AG_HOGE_DB\AvailabilityReplicas | Test-SqlAvailabilityReplica | Where-Object { $_.HealthState -ne "Healthy" } HealthState AvailabilityGroup Name ----------- ----------------- ---- Error AG_HOGE_DB SQL-NODE01 |
可用性データベースの健全性を確認する
SQL-NODE01のSQLServerがダウンしている状態で確認した結果。(SynchronizationState が NotSynchronizing と表示されています)
1 2 3 4 5 6 |
PS> Get-ChildItem SQLSERVER:\sql\sql-node02\default\AvailabilityGroups\AG_HOGE_DB\databasereplicastates AvailabilityReplicaServerName AvailabilityDatabaseName SynchronizationState EstimatedRecoveryTime SynchronizationPerformance LogSendQueueSize ----------------------------- ------------------------ -------------------- --------------------- -------------------------- ---------------- SQL-NODE01 HOGEDB NotSynchronizing 0 -1 -1 SQL-NODE02 HOGEDB Synchronized -1 -1 -1 |
この結果に、Test-SqlDatabaseReplicaState コマンドレッドをかませると、ステータスを取得できる。
1 2 3 4 5 6 |
PS> Get-ChildItem SQLSERVER:\sql\sql-node02\default\AvailabilityGroups\AG_HOGE_DB\databasereplicastates | Test-SqlDatabaseReplicaState HealthState AvailabilityGroup AvailabilityReplica Name ----------- ----------------- ------------------- ---- Warning AG_HOGE_DB SQL-NODE01 HOGEDB Healthy AG_HOGE_DB SQL-NODE02 HOGEDB |
あとは同じやり方で、ステータスがヘルシー以外を取得する。
1 2 3 4 5 |
PS> Get-ChildItem SQLSERVER:\sql\sql-node02\default\AvailabilityGroups\AG_HOGE_DB\databasereplicastates | Test-SqlDatabaseReplicaState | Where-Object { $_.HealthState -ne "Healthy" } HealthState AvailabilityGroup AvailabilityReplica Name ----------- ----------------- ------------------- ---- Warning AG_HOGE_DB SQL-NODE01 HOGEDB |
例えば、ステータスがヘルシー以外のホストを取得するとしたら以下のように。
1 2 |
PS> (Get-ChildItem SQLSERVER:\sql\sql-node02\default\AvailabilityGroups\AG_HOGE_DB\databasereplicastates | Test-SqlDatabaseReplicaState | Where-Object { $_.HealthState -ne "Healthy" }).AvailabilityReplica SQL-NODE01 |
可用性グループの健全性を確認する
Test-SqlAvailabilityGroup コマンドレットを使用して、可用性グループのパスを指定することでステータスを確認できる。
1 2 3 4 5 |
PS> Test-SqlAvailabilityGroup -path SQLSERVER:\sql\sql-node02\default\AvailabilityGroups\AG_HOGE_DB HealthState Name ----------- ---- Healthy AG_HOGE_DB |
Test-SqlAvailabilityReplica コマンドレットを使用して片系のホストが Warning の状態で可用性グループのステータスを確認してみる。
1 2 3 4 5 6 7 8 9 10 11 |
PS> Get-ChildItem SQLSERVER:\sql\sql-node02\default\AvailabilityGroups\AG_HOGE_DB\AvailabilityReplicas | Test-SqlAvailabilityReplica | where { $_.name -eq "sql-node01" } HealthState AvailabilityGroup Name ----------- ----------------- ---- Warning AG_HOGE_DB SQL-NODE01 # SQL-NODE01がWarning状態 PS> Test-SqlAvailabilityGroup SQLSERVER:\sql\sql-node02\default\AvailabilityGroups\AG_HOGE_DB HealthState Name ----------- ---- Error AG_HOGE_DB # 可用性グループのステータスもErrorとなる |
やはり、方系が異常だと可用性グループとしては Error となりますね。
まとめ
実際に使えそうなやり方を紹介してみましたが、いかがでしょうか。
実際の運用では、手動でコマンドを利用して確認する、というよりも、Zabbixなどの監視ツールを利用してフェイルオーバーしたらアラートメールを送信する、などのように自動で検知する仕組みを用意する必要があると思いますが、AlwaysOnの状態確認の 基本のき ということでまとめてみました。
以上です。
↓↓↓ 持っていると便利な一冊 ↓↓↓