はじめに
このブログでもしばしば取り上げている Galera Cluster ですが、つい最近 wsrep_notify_cmd というパラメータ変数の存在を知りました。
調べてみると中々に便利そうな機能だったので、早速このブログで紹介したいと思います。
wsrep_notify_cmd とは
端的に言えば、Galera Cluster の各ノードの状態が変化した時に、自動で指定した任意のスクリプトを実行する機能です。
Galeraのノードは安定稼働している間、「Synced」になります。これは、wsrep_local_state_commentステータス変数で確認できます。
このノードのステータスは以下のようなケースで変動します。こうしたイベントをトリガーとして、変数に指定したスクリプトを実行するのが wsrep_notify_cmd の役割です。
- ノード間のネットワークが切断、または不安定なとき
- ノードを追加、もしくは削除したとき
wsrep_notify_cmd を活用することにより、以下のような効果が期待できます。
- ネットワーク障害が疑われる場合に、運用管理者にメールを送信する
- ノードの状態を逐次ファイルに記録し、想定外の操作が行われていないか監査を行う
- 障害発生時に自動モニタリング、リカバリスクリプトをキックする
その他の詳細は、以下の公式マニュアルで解説されています。
実際に使ってみよう
それでは、さっそく wsrep_notify_cmd を使ってみましょう。上記のマニュアルにスクリプトのサンプルが用意されているので、それを使用します。
1. PXC環境を用意する
お好きな方法で、PXCの3ノード環境を用意してください。
ちなみに、以前弊社のブログ
でも取り上げた dbdeployer が、ついに Percona XtraDB Cluster(以下PXC)にも対応しました。
今回は、この dbdeployer を使って用意したPXCを使用します。
※ 詳しいセットアップ手順は、dbdeployer開発者のブログを参考にしてください
2. スクリプトの準備
本来は全ノードで設定することが望ましいですが、今回はNode3でのみ設定します。まずは、マニュアルに載っているスクリプトを作成します。
ユーザ名やパスワードなど接続情報は適宜変更してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
$ vi ./my-wsrep-notify.sh ============================== #!/bin/sh -eu # This is a simple example of wsrep notification script (wsrep_notify_cmd). # It will create 'wsrep' schema and two tables in it: 'membeship' and 'status' # and fill them on every membership or node status change. # # Edit parameters below to specify the address and login to server. USER=msandbox PSWD=msandbox HOST=127.0.0.1 PORT=26228 SCHEMA="wsrep" MEMB_TABLE="$SCHEMA.membership" STATUS_TABLE="$SCHEMA.status" BEGIN=" SET wsrep_on=0; DROP SCHEMA IF EXISTS $SCHEMA; CREATE SCHEMA $SCHEMA; CREATE TABLE $MEMB_TABLE ( idx INT UNIQUE PRIMARY KEY, uuid CHAR(40) UNIQUE, /* node UUID */ name VARCHAR(32), /* node name */ addr VARCHAR(256) /* node address */ ) ENGINE=MEMORY; CREATE TABLE $STATUS_TABLE ( size INT, /* component size */ idx INT, /* this node index */ status CHAR(16), /* this node status */ uuid CHAR(40), /* cluster UUID */ prim BOOLEAN /* if component is primary */ ) ENGINE=MEMORY; BEGIN; DELETE FROM $MEMB_TABLE; DELETE FROM $STATUS_TABLE; " END="COMMIT;" configuration_change() { echo "$BEGIN;" local idx=0 for NODE in $(echo $MEMBERS | sed s/,/\ /g) do echo "INSERT INTO $MEMB_TABLE VALUES ( $idx, " # Don't forget to properly quote string values echo "'$NODE'" | sed s/\\//\',\'/g echo ");" idx=$(( $idx + 1 )) done echo " INSERT INTO $STATUS_TABLE VALUES($idx, $INDEX,'$STATUS', '$CLUSTER_UUID', $PRIMARY); " echo "$END" } status_update() { echo " SET wsrep_on=0; BEGIN; UPDATE $STATUS_TABLE SET status='$STATUS'; COMMIT; " } COM=status_update # not a configuration change by default while [ $# -gt 0 ] do case $1 in --status) STATUS=$2 shift ;; --uuid) CLUSTER_UUID=$2 shift ;; --primary) [ "$2" = "yes" ] && PRIMARY="1" || PRIMARY="0" COM=configuration_change shift ;; --index) INDEX=$2 shift ;; --members) MEMBERS=$2 shift ;; esac shift done # Undefined means node is shutting down if [ "$STATUS" != "Undefined" ] then $COM | mysql -B -u$USER -p$PSWD -h$HOST -P$PORT fi exit 0 ============================== $ sudo mv ./my-wsrep-notify.sh /usr/bin/ $ sudo chown mysql:mysql /usr/bin/my-wsrep-notify.sh $ sudo chmod 700 /usr/bin/my-wsrep-notify.sh |
3. wsrep_notify_cmd変数の有効化
my.cnfにwsrep_notify_cmd変数を追加します。設定値は上記で準備をしたスクリプトのパスを指定します。最後に設定を有効化するためにノードを再起動します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
$ sudo vi /xxxxx/pxc_msb_pxc_5_7_25/node3/my.sandbox.cnf 以下を追加 wsrep_notify_cmd=/usr/bin/my-wsrep-notify.sh pxc_strict_mode = PERMISSIVE ### ENFORCEだとスクリプトのテーブル作成時にエラーになります $ /xxxxx/pxc_msb_pxc_5_7_25/node3/restart $ /xxxxx/pxc_msb_pxc_5_7_25/node3/use node3 [localhost:26228] {msandbox} ((none)) > show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | test | | wsrep | +--------------------+ 6 rows in set (0.01 sec) |
wsrepデータベースが作成されていたら、スクリプトは稼働しています。
4. 動作確認
ノードのステータスを変化させるため、Node2を停止します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
$ /xxxxx/pxc_msb_pxc_5_7_25/node2/stop $ /xxxxx/pxc_msb_pxc_5_7_25/node3/use node3 [localhost:26228] {msandbox} ((none)) > SELECT * FROM wsrep.status\G *************************** 1. row *************************** size: 2 idx: 1 status: Synced uuid: 3e7b59e2-6666-11e9-8b15-5be31b040a94 prim: 1 1 row in set (0.00 sec) node3 [localhost:26228] {msandbox} ((none)) > SELECT * FROM wsrep.membership\G *************************** 1. row *************************** idx: 0 uuid: 6a04b8fa-67c3-11e9-aa8d-1f78a54fe162 name: Node1 addr: 127.0.0.1:26226 *************************** 2. row *************************** idx: 1 uuid: 70a110dc-67c3-11e9-b1eb-fe377e38d63c name: Node3 addr: 127.0.0.1:26228 2 rows in set (0.00 sec) |
この時の動作としては、Node2がクラスタから消えたことをキャッチして my-wsrep-notify.sh が作動、wsrep.membershipテーブルを自動で更新するという流れになっています。そのため、Node2を再起動すると、membership テーブルが再度更新されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
$ /xxxxx/pxc_msb_pxc_5_7_25/node2/start $ /xxxxx/pxc_msb_pxc_5_7_25/node3/use node3 [localhost:26228] {msandbox} ((none)) > SELECT * FROM wsrep.membership\G *************************** 1. row *************************** idx: 0 uuid: 6a04b8fa-67c3-11e9-aa8d-1f78a54fe162 name: Node1 addr: 127.0.0.1:26226 *************************** 2. row *************************** idx: 1 uuid: 70a110dc-67c3-11e9-b1eb-fe377e38d63c name: Node3 addr: 127.0.0.1:26228 *************************** 3. row *************************** idx: 2 uuid: 8eb4e220-67c5-11e9-b854-3a97191ebf6d name: Node2 addr: 127.0.0.1:26227 3 rows in set (0.00 sec) |
スクリプトの内容は自由なので、ノードダウン時にアラートを飛ばしたり、他のソフトウェアを起動したりといった動作も可能です。
おわりに
以上、wsrep_notify_cmd 変数について説明しました。機能としてはシンプルですが、実行するスクリプトの内容によって、さまざまな使い方が実現できそうです。もし興味があれば、試してみてください!