Got error 4009 'Cluster Failure' from NDB. Could not acquire global schema lock
MySQL Cluster (NDB) 7.2.5 -> 7.2.6 にアップデート後に、ホスト再起動したら出た。結論を先に書くと、iptables 切れば治るはず。だめだったら SELINUX 確認して 止められるなら Disable に、無理なら echo で値渡して Permissive にする。その後再起動。
[root@mgmd-node1 ~]# mysql -u root -p -h 192.168.254.11 dev_production mysql> show warnings;
アップデート直後に何時まで経っても API node が accepting connect になってるからおかしーなー、と思って warnings みたらこの有り様。調べると本家の以下のスレッドが引っかかる。
MySQL :: Re: Waiting for ndbcluster global schema lock
結局スレッド遡っていっても「コマンドが正しく見えない訳がないから、エラーログを提出してくれ」とか「SELINUX切ってるかーオラー?」みたいな事しか書いてなくてまじってレベル。
MySQL Cluster 自身のログを見ても、NDBD node とは通信できているっぽくて、 usage のログを出力し続けていて、特にエラーは見られない。なんなのもー、と思った所で、以下を試してみた。
[root@mgmd-node1 ~]# etc/init.d/iptables status [root@mgmd-node2 ~]# etc/init.d/iptables status テーブル: filter Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 5 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:80 6 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:443 7 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:1186 8 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:3306 [root@mgmd-node1 ~]# mysql -u root -p -h 192.168.254.12 dev_production [root@mgmd-node2 ~]# mysql -u root -p -h 192.168.254.11 dev_production
not connect じゃなくてつながるじゃねーかきれそううううううう!……あっ!
[root@mgmd-node1 ~]# /etc/init.d/iptables stop [root@mgmd-node2 ~]# /etc/init.d/iptables stop [mysqld(API)] 2 node(s) id=21 (not connected, accepting connect from 192.168.254.11) id=22 (not connected, accepting connect from 192.168.254.12)
だめじゃねーかきれそううううううう!!……あっ!!
[root@ndbd-node1 ~]# /etc/init.d/iptables stop [root@ndbd-node2 ~]# /etc/init.d/iptables stop [root@mgmd-node(1|2) ~]# ndb_mgm -e show Connected to Management Server at: 192.168.254.11:1186 Cluster Configuration --------------------- [ndbd(NDB)] 2 node(s) id=11 @192.168.254.21 (mysql-5.5.22 ndb-7.2.6, Nodegroup: 0, Master) id=12 @192.168.254.22 (mysql-5.5.22 ndb-7.2.6, Nodegroup: 0) [ndb_mgmd(MGM)] 2 node(s) id=1 @192.168.254.11 (mysql-5.5.22 ndb-7.2.6) id=2 @192.168.254.12 (mysql-5.5.22 ndb-7.2.6) [mysqld(API)] 2 node(s) id=21 @192.168.254.11 (mysql-5.5.22 ndb-7.2.6) id=22 @192.168.254.12 (mysql-5.5.22 ndb-7.2.6)
うごいたー。
今まで MGMD node 動いてないと NDBD node が起動しないことから、port 1186 でお互い通信してると思ってたけど違うのね…FW の下にいるしとりあえずは切っておいても問題ないけど、後で調べて iptables 起動させておかないとやばいこれ。とりあえず iptables で 1186 と 3306 あけただけじゃポート足りないってことが分かっただけである、きれそう。
追記
その後テストしてみたけど、MGMD + API node は iptables 起こしても大丈夫だった。 NDBD node は iptables 起こすと、ndb_mgmd_id_cluster.log にエラーが検知されてた。んで、調べてみると、以下の記事がヒットした。
http://blogs.ricollab.jp/webtech/2008/07/
症状が一緒だったので config.ini の [NDBD DEFAULT] に ServerPort=63132 を追記して NDBD node で動作してる iptables で対象ポート 63132 も通信許可して起動してみたけど、また症状再発した。駄目じゃねーかきれそうううううううう!
で、まさか逆なのか?と思って MGMD node の iptables に 63132 許可するようにして、 NDBD node 側は 63132 閉じてみた。が、駄目。きれそう通り越してつかれてきた。
両方の node で開放したら、なぜか NDBD node 二本立てているのに両方が Master フラグたって同期取られなくてデータずれてきれた。そもそもこの場合、API node が立ち上がって来なかったので利用できない(以下の様な)状態になる。
ndb_mgm> show Cluster Configuration --------------------- [ndbd(NDB)] 2 node(s) id=11 @192.168.254.21 (mysql-5.5.22 ndb-7.2.6, Nodegroup: 0, Master) id=12 @192.168.254.22 (mysql-5.5.22 ndb-7.2.6, Nodegroup: 0, Master) [ndb_mgmd(MGM)] 2 node(s) id=1 @192.168.254.11 (mysql-5.5.22 ndb-7.2.6) id=2 @192.168.254.12 (mysql-5.5.22 ndb-7.2.6) [mysqld(API)] 2 node(s) id=21 (not connected, accepting connect from 192.168.254.11) id=22 (not connected, accepting connect from 192.168.254.12)
追記2
MySQL Cluster で開放必要なポートは結局以下っぽい。
- NDBD node : そもそも閉じたらだーめ
- MGMD node : port 1186
- API node : port 3306
うわまじできれそう、きれそううううううううう!
追記3
注:クラスタ マネジメント ノードのデフォルトのポートは 1186で、データ ノードのデフォルトのポートは 2202 です。MySQL 5.0.3 以降ではこの制限が解除されており、クラスタはすでにフリーになっているものから自動的にデータ ノードにポートを割り当てます。
http://dev.mysql.com/doc/refman/5.1/ja/mysql-cluster-multi-config.html
つまりデフォルトでは 2202 が指定されていたはずだけど、 5.0.3 以降は開いてるポート探してそれを通信に勝手に使うってことか。起動順番によっては、他プログラムとポートのバッティング引き起こしてしまうんじゃ……っていうか SevrerPort で指定してんのになんで正常な通信できねーの?と思ったら、上記のリコーの記事にも合ったように。
ServerPort (旧式)
クラスタの各ノードは他のノードに接続するためにポートを使用しています。このポートはまた接続設定段階の非 TCP トランスポーターに使用されています。デフォルトのポートは同じコンピュータ上の 2 つのノードが同じポート番号を受信しないようにダイナミックに割り当てられているため、通常このパラメータの値を指定する必要はありません。
MySQL :: MySQL 5.6 リファレンスマニュアル :: 18.3.2.6 MySQL Cluster データノードの定義
引用ふたつを都合よく解釈すると、
「以前はデータノードとの通信に port 2202 がデフォルトの値として使用されていたけど、MySQL 5.0.3 以降ではデフォルトでも使用しないようにしたよ。代わりに、開いてるポートを自動で探して、そのポートで通信出来るようにしておいたよ!」
……もうつかれたのでこれ以上検証するのやめとくけど、そのうちサポートのライセンス買う見たいな話を職場で聞いたので、本当にライセンス購入したら聞いてみよう、もうつかれた。