銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

SQL Server Availability Group を RHEL Clusterで作ってみる

注意: SQL Server Availability Group をRHEL Clusterで作る場合はHA add-on が必要ですが、このアドオンはAzure上ではサポートされていません。ということでサポート対象外だけど試したいという場合にAzure上でどうぞ。全体の作り方はAzure上に限らないはずです。

公開直後になんとなく作ったのですがそのときは挙動があやしかったので再度作り直してみた結果をまとめてみます。

作業の流れとしては、

  1. Clusterを構成する各NodeにSQL Serverをインストールする
  2. Availability Groupを構築する
  3. Cluster化する

となります。最後のCluste化するところではプラットフォームごとに利用するPacemaker管理ソフトが異なります。RHELの場合はpcsを使います。このエントリを読む前にこちらで概要を把握するのがよいと思われます。

blog.engineer-memo.com

作業の流れ自体はこちらに書いてある通りになります。このドキュメントが公開された当初はいろいろ記述が足りなかったのですが、今やった限りでは一通り揃っているようです。とはいえ、いろいろハマリどころが多かったのでその辺をまとめておきたいと思います。

Configure availability group for SQL Server on Linux | Microsoft Docs

ホストの用意とSQL Serverのインストール

今回はAzure上のVMで構築しました。問題としては最後にVIPを割り振った後、VIPでのアクセスが同じネットワーク内の別ホストからできないことなのですが、これはAzureのNetworkを勉強しないといけなさそうです。また同じVNETのSubnet内にNodeを配置するので、ホスト名での通信はデフォルトのAzure DNSでできる状態です。VMを起動したら、このドキュメントに沿って、各NodeにSQL Serverをインストールします。

docs.microsoft.com

また、sqlcmdで接続して処理を進める必要があるのでSQL Server Toolsも各ホストにインストールしておきました。

docs.microsoft.com

Availability Groupの構築

次にこのドキュメントに沿ってAvailability Groupの構築を行います。ちなみにこの中の手順で失敗して、復旧が難しい状態になったらSQL Serverのアンインストールをして最初からやりなおすことをオススメします。。。

Configure availability group for SQL Server on Linux | Microsoft Docs

手順をまとめると

  1. Always On availability groupsを有効化してmssql-serverサービス再起動(全Node)
  2. AlwaysOn_health event sessionの有効化(任意、やる場合は全Node)
  3. db mirroring endpoint user作成(全Node)
  4. Masterでのcertificate作成とMaster以外のNodeへの転送(Masterのみ)
  5. Secondary Nodesでのcertificate作成(Master以外の全Node)
  6. database mirroring endpoints作成(全Node、設定するIPアドレスはNode自身のアドレス*1なのでNodeにより異なる)
  7. availability group作成(Masterのみ、ノード名やリスナーのIPを環境に合わせて設定する)
  8. Secondary Server(s)をAvailability Groupに追加(Master以外の全Node)
  9. DBを作成し、Availability Groupに追加(Masterのみ)
  10. 追加したDBがSecondary Nodeからアクセスできることを確認(Master以外のNode)

となります。mirroring endpointの作成あたりから操作うまくいったか不安になるのですが、まずendpointができているかどうかはSELECT * FROM sys.endpointsでわかります。

f:id:tanaka733:20170313185449p:plain

作ったエンドポイントのstate_descSTARTEDになっていればOKです。おかしい場合はDROP ENDPOINT Hadr_endpointで消せるはずです。ちなみにちゃんとうごいていると上のクエリがすぐに結果を返しますが、変な状態になっていたら結果がかえるのにやたら時間がかかる状態になっていました。

また、Availability Group自体はこの時点で動いているのでその状態を確認することもできます。このブログを参考にしました。

blog.dbi-services.com

なんとも見辛いですがこんな感じで表示されます。この環境はdb1とdb2を追加しています。

f:id:tanaka733:20170313190025p:plain f:id:tanaka733:20170313190032p:plain f:id:tanaka733:20170313190042p:plain

Cluster化

RHELではCluster化を行うのに、Pacemakerを利用して作られたHA add-onを使います。というわけでご利用の際には該当のSubscriptionが必要になります。

また、このCluster化の手順で失敗した場合、Availability Group本体に影響がなければこの手順のみをやりなおすことができます。その場合はまず、pcs cluster delete --all をMasterで実行するか、pcs cluster deleteを各Nodeで実行するとよさそうです。クラスターを削除した場合、pacemakerがdisableになっているのでsudo systemctl enable pacemakerを再実行します。また、pcs cluster authはclusterを削除しても認証が残ったままになりますが、ここもやり直したい場合は--forceオプションをつけることができます。

STONITH(Shoot-The-Other-Node-In-The-Head)の無効化ですが、テスト目的ではドキュメントどおり無効化すればよいのですが、本番環境では設定しておくべきでしょう。なぜかリンク先はRHEL6ですが、RHEL7向けのドキュメントはこちらです。

第4章 フェンス機能: STONITH の設定

また、こちらのドキュメントなどを見ると、Azure上ではVMをShutdownさせてるようにするの一つの方法のようです。

負荷分散セットを使用して MySQL をクラスター化する | Microsoft Docs

あとはドキュメント通りに、PacemakerがヘルスチェックするためのSQL Serverログインユーザーを作成し、pcsのavailability groupリソースと virtual IPリソースを作成します。ここまで来ればpcsの状態でも確認できます。

f:id:tanaka733:20170313191434p:plain

VIPが着いている側のNICにVIPに設定した172.17.2.50が割り振られているのがわかります。

リソースを手動でFailoverするとsolnode2に移動するのもわかります。

f:id:tanaka733:20170313191701p:plain f:id:tanaka733:20170313191707p:plain

solnode2側で見ればVIPがつけかわっています。

f:id:tanaka733:20170313191749p:plain

さて無事に動けばいいのですが、手順を誤まると動かないことがあります。実際にこんなエラーが出たことがありました。

f:id:tanaka733:20170313191914p:plain

こういうときはSQL Serverのエラーログを見てみましょう。/var/opt/mssql/log/errorlogにあります。

というのがSQL Server Availability Group on RHEL Clusterを作ってみた感想になります。特にCluster化はHA add on を使うのでドキュメントに倣うだけでもある程度知っておくことが必要で、実際に使いこなすにはさらに習得しておく必要を感じました。

*1:このアドレスはクラスタ内の別Nodeからアクセスできるアドレス