Posted at

LinuxでMySQLクラスタが上手く動かない時はiptablesのファイアウォールととSELinuxが二大ボス

More than 5 years have passed since last update.

データベース周りは全然詳しくないのですが、Connection Failures Between Nodes in MySQL Clustersを読む機会があったので部分適当訳を貼ってみます。


1. データノードがstartingから進まない問題

1台はスタートしたのにもう一台はstartingのままだったりする場合も

showコマンドの結果がこういう感じになってる時


[ndbd(NDB)] 2 node(s)

id=2 @192.168.56.211 (mysql-5.6.11 ndb-7.3.2, Nodegroup: 0, Master)

id=3 @192.168.56.212 (mysql-5.6.11 ndb-7.3.2, starting, Nodegroup: 0)


ndb_1_cluster.logの内容


[MgmtSrvr] INFO -- Node 3: Initial start, waiting for 2 to connect, nodes [ all: 2 and 3 connected: 3 no-wait: ]


これは、データノード間の通信がうまくいってないのが原因


データノードの通信について

データノードと管理ノードはport 1186で通信する。これはIANAが予約してて、MySQLが入ってるシステムだとだいたい開いてる

データノードが起動してIDを得ると、エフェメラルポートという動的かつユニークなportをもらえる。

こっちはOSが割り振るので、データノードからはどんな値になるかはわからない。

IANAは49152〜65535の間でIDが振られると思っているが、

Linuxでは32768〜61000でふられるらしい

> cat /proc/sys/net/ipv4/ip_local_port_range

すると実際の値がわかる

Firewallによってアクセス塞がれてたりするとデータノード間の通信が出来ず、

MySQLクラスタはデータノードの監視を見つけられない

(--nowait-nodesオプションをつけるとそうじゃないけど、普段はこのオプションを使わないべき)


iptables and SeverPort

管理ノードのconfig.iniに以下のように書くと、データノードが使うポートを指定できる


[ndbd]

Hostname=datahost1

ServerPort=50501

[ndbd]

Hostname=datahost2

ServerPort=50502


データノード側で以下の様なコマンドを打ってポートをあける

> iptables -I INPUT -p tcp --dport 50501 -s 192.168.56.0/24 -j ACCEPT

> service iptables save


2. 管理ノードがオワコン

管理ノードのポートが空いてない場合もある。tar.gzみたいな圧縮形式でMySQLのバイナリをコピーしてインスコとかしてたときはこういう場合があるらしい

こういうときもiptablesでポートを開けてあげるとよい


3. MySQLサーバーノードが接続に失敗する

RPMでMySQLを入れると、SELinuxの設定も入る。

デフォルトの設定ではMySQLは3306番と1186番ポートを見れる

これはmysqldプロセスとMySQLクラスタの管理ノード

しかしデフォルトの設定はMySQLクラスタの中でAPI的に動くことを想定してないので、mysqldプロセスはデータノードのポートが見れない

こういうときshowすると以下の様な感じ


[mysqld(API)] 1 node(s)

id=5 (not connected, accepting connect from any host)


show warningsは


+---------+------+---------------------------------------------------------------------------------+

| Level | Code | Message |

+---------+------+---------------------------------------------------------------------------------+

| Warning | 1296 | Got error 4009 'Cluster Failure' from NDB. Could not acquire global schema lock |

| Warning | 1296 | Got error 4009 'Cluster Failure' from NDB |

| Error | 157 | Could not connect to storage engine |

| Error | 1499 | Too many partitions (including subpartitions) were defined |

+---------+------+---------------------------------------------------------------------------------+


これに対処するにはSELinuxをdisabledにすればいいけど、もうちょっとスマートにやるなら

 上で設定したポートを元に


semanage port -a -t mysqld_port_t -p tcp 50501-50524


というように特定のポートにアクセスする権限を与えることが出来る