MySQL 5.0, 5.1 でクラスタを組んでみる

目的

「書き込みするDBの可用性確保」を焦点に、 MySQL4.1以降で実装されているNDB Clusterについて調査・構築・動作テストした。
基本的にはGAになっているMySQL5.0をメインに調査したが、5.0のクラスタは オンメモリという致命的な制限があるため、現在はベータであるが近日GAになるであろう 5.1の調査・構築・動作テストも行なった。※とはいえ5.1もデータはディスクにおけるがインデックスはメモリにのせることになる。
MySQLクラスタとは?」といったような基本的なことは他のサイトを参照ください。

サーバー群


xxxxxxxx.co.jp 172.18.6.59 #Data兼SQLノード
xxxxxxxx.co.jp 172.18.6.60 #Data兼SQLノード
xxxxxxxx.co.jp 172.18.6.61 #Data兼SQLノード
xxxxxxxx.co.jp 172.18.6.62 #Data兼SQLノード
xxxxxxxx.co.jp 172.18.6.63 #管理ノード

  • Dataノードは「NoOfReplicas」(後述)の倍数台必要。最低2台。
  • 管理ノードも2台以上が望ましい
  • SQLノードはDataノードと兼ねてもいいし、あるいは分離することも可能

OSなど

FreeBSD-6.1
jail環境にて構築

ユーザー・グループの追加(全ノード)


sudo vi /etc/group

                                                                        • -

mysql:*:10001:

                                                                        • -


sudo vipw;

                                                                        • -

mysql:*:10001:10001::0:0:MySQL User:/tmp:/bin/sh

                                                                      • -

MySQL-5.0.27-maxダウンロード・展開・コピー(全ノード)


fetch -o mysql-max-5.0.27-freebsd6.0-x86_64.tar.gz "http://dev.mysql.com/get/Downloads/MySQL-5.0/mysql-max-5.0.27-freebsd6.0-x86_64.tar.gz/from/http://mirror.mysql-partners-jp.biz/";
tar xvzf mysql-max-5.0.27-freebsd6.0-x86_64.tar.gz;
sudo cp -r mysql-max-5.0.27-freebsd6.0-x86_64 /usr/local/;
sudo ln -s /usr/local/mysql-max-5.0.27-freebsd6.0-x86_64 /usr/local/mysql;
cd /usr/local/mysql;
sudo scripts/mysql_install_db --user=mysql;
sudo chown -R root .;
sudo chown -R mysql data;
sudo chgrp -R mysql .;
※5.1も同様の手順でOK。tar ballは下記からダウンロードした。 http://dev.mysql.com/get/Downloads/MySQL-5.1/mysql-5.1.14-beta-freebsd6.0-x86_64.tar.gz/from/http://mirror.mysql-partners-jp.biz/

MySQLセットアップ(SQLノードとDataノード)


sudo vi /etc/my.cnf;

                                                                        • -

[MYSQLD]
ndbcluster
ndb-connectstring="172.18.6.63"
old-passwords=1
interactive_timeout=900
wait_timeout=900
max_connections=100
[MYSQL_CLUSTER]
ndb-connectstring="172.18.6.63"

                                                                        • -

※5.1も同様の手順でOK。

管理ノードセットアップ(管理ノード)


sudo mkdir /var/lib /var/lib/mysql-cluster;
sudo vi /var/lib/mysql-cluster/config.ini;

                                                                        • -

[NDBD DEFAULT]
NoOfReplicas=2
DataMemory=150M
IndexMemory=75M
# Managment Server
[NDB_MGMD]
id=1
hostname=172.18.6.63
datadir=/var/lib/mysql-cluster
# Storage Engines
[NDBD]
id=2
hostname=172.18.6.62
datadir=/usr/local/mysql/data
[NDBD]
id=3
hostname=172.18.6.61
datadir=/usr/local/mysql/data
[NDBD]
id=4
hostname=172.18.6.60
datadir=/usr/local/mysql/data
[NDBD]
id=5
hostname=172.18.6.59
datadir=/usr/local/mysql/data
# SQL node options:
[MYSQLD]
[MYSQLD]
[MYSQLD]
[MYSQLD]

                                                                        • -

MYSQLDの項目はSQLノードの入れ替え等に対応しやすいように、敢えて空にしておきます。
なんなら多めに取っておいてもいいかもしれません。
※5.1も同様の手順でOK。

管理ノード起動(管理ノード)


sudo /usr/local/mysql/bin/ndb_mgmd -f /var/lib/mysql-cluster/config.ini;
/usr/local/mysql/bin/ndb_mgm;

-- NDB Cluster -- Management Client --
ndb_mgm> show
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)] 4 node(s)
id=2 (not connected, accepting connect from 172.18.6.62)
id=3 (not connected, accepting connect from 172.18.6.61)
id=4 (not connected, accepting connect from 172.18.6.60)
id=5 (not connected, accepting connect from 172.18.6.59)

[ndb_mgmd(MGM)] 1 node(s)
id=1 @172.18.6.63 (Version: 5.0.27)

[mysqld(API)] 4 node(s)
id=6 (not connected, accepting connect from any host)
id=7 (not connected, accepting connect from any host)
id=8 (not connected, accepting connect from any host)
id=9 (not connected, accepting connect from any host)
※5.1も同様の手順でOK。

Dataノード起動(Dataノード)


sudo /usr/local/mysql/bin/ndbd --initial;
※5.1も同様の手順でOK。

管理ノードで確認(管理ノード)


ndb_mgm>
Node 2: Started (version 5.0.27)
Node 3: Started (version 5.0.27)
Node 5: Started (version 5.0.27)
Node 4: Started (version 5.0.27)

ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)] 4 node(s)
id=2 @172.18.6.62 (Version: 5.0.27, Nodegroup: 0, Master)
id=3 @172.18.6.61 (Version: 5.0.27, Nodegroup: 0)
id=4 @172.18.6.60 (Version: 5.0.27, Nodegroup: 1)
id=5 @172.18.6.59 (Version: 5.0.27, Nodegroup: 1)

[ndb_mgmd(MGM)] 1 node(s)
id=1 @172.18.6.63 (Version: 5.0.27)

[mysqld(API)] 4 node(s)
id=6 (not connected, accepting connect from any host)
id=7 (not connected, accepting connect from any host)
id=8 (not connected, accepting connect from any host)
id=9 (not connected, accepting connect from any host)
※5.1も同様の手順でOK。

SQLノード起動(SQLノード)


sudo /usr/local/mysql/support-files/mysql.server start
※5.1も同様の手順でOK。

管理ノードで確認(管理ノード)


ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)] 4 node(s)
id=2 @172.18.6.62 (Version: 5.0.27, Nodegroup: 0, Master)
id=3 @172.18.6.61 (Version: 5.0.27, Nodegroup: 0)
id=4 @172.18.6.60 (Version: 5.0.27, Nodegroup: 1)
id=5 @172.18.6.59 (Version: 5.0.27, Nodegroup: 1)

[ndb_mgmd(MGM)] 1 node(s)
id=1 @172.18.6.63 (Version: 5.0.27)

[mysqld(API)] 4 node(s)
id=6 @172.18.6.59 (Version: 5.0.27)
id=7 @172.18.6.60 (Version: 5.0.27)
id=8 @172.18.6.61 (Version: 5.0.27)
id=9 @172.18.6.62 (Version: 5.0.27)
※5.1も同様の手順でOK。

5.0 動作確認(SQLノード)

※5.1のオンディスクは手順が異なります。まずは5.0から。


/usr/local/mysql/bin/mysql;

mysql> use test;
mysql> CREATE TABLE ctest (i INT) ENGINE=NDBCLUSTER;
mysql> INSERT INTO ctest () VALUES (1);
mysql> SELECT * FROM ctest;

              • +
i
              • +
1
              • +

他のSQLノードでも確認。

/usr/local/mysql/bin/mysql;

mysql> use test;
mysql> SELECT * FROM ctest;

              • +
i
              • +
1
              • +

1 row in set (0.01 sec)

mysql> INSERT INTO ctest () VALUES (2);
mysql> SELECT * FROM ctest;

              • +
i
              • +
1
2
              • +

2 rows in set (0.00 sec)

さらに他のSQLノード(あるいは最初のノードに戻って)でも確認。

/usr/local/mysql/bin/mysql;

mysql> use test;
mysql> SELECT * FROM ctest;

              • +
i
              • +
1
2
              • +

2 rows in set (0.00 sec)

5.0 障害発生時動作確認

下記の4つのDBノードのうち、id=2とid=4のndbdをダウンさせて、SQLを発行してみたところ、問題なく動作した。


id=2 @172.18.6.62 (Version: 5.0.27, Nodegroup: 0, Master)
id=3 @172.18.6.61 (Version: 5.0.27, Nodegroup: 0)
id=4 @172.18.6.60 (Version: 5.0.27, Nodegroup: 1)
id=5 @172.18.6.59 (Version: 5.0.27, Nodegroup: 1)

5.1 動作確認(SQLノード)


/usr/local/mysql/bin/mysql;

mysql> use test;

mysql> CREATE LOGFILE GROUP lg_1
-> ADD UNDOFILE 'undo_1.dat'
-> INITIAL_SIZE 16M
-> UNDO_BUFFER_SIZE 2M
-> ENGINE NDB;

mysql> ALTER LOGFILE GROUP lg_1
-> ADD UNDOFILE 'undo_2.dat'
-> INITIAL_SIZE 12M
-> ENGINE NDB;

mysql> CREATE TABLESPACE ts_1
-> ADD DATAFILE 'data_1.dat'
-> USE LOGFILE GROUP lg_1
-> INITIAL_SIZE 32M
-> ENGINE NDB;

mysql> ALTER TABLESPACE ts_1
-> ADD DATAFILE 'data_2.dat'
-> INITIAL_SIZE 48M
-> ENGINE NDB;

mysql> CREATE TABLE ctest ( i INT, INDEX(i) ) TABLESPACE ts_1 STORAGE DISK ENGINE=NDBCLUSTER;
mysql> INSERT INTO ctest () VALUES (1);
mysql> SELECT * FROM ctest;

              • +
i
              • +
1
              • +

他のSQLノードでも確認。

/usr/local/mysql/bin/mysql;

mysql> use test;
mysql> SELECT * FROM ctest;

              • +
i
              • +
1
              • +

1 row in set (0.01 sec)

mysql> INSERT INTO ctest () VALUES (2);
mysql> SELECT * FROM ctest;

              • +
i
              • +
1
2
              • +

2 rows in set (0.00 sec)

さらに他のSQLノード(あるいは最初のノードに戻って)でも確認。

/usr/local/mysql/bin/mysql;

mysql> use test;
mysql> SELECT * FROM ctest;

              • +
i
              • +
1
2
              • +

2 rows in set (0.00 sec)

5.1 実ファイル(Dataノード)

下記のような配置になります。


sudo ls -alGF /usr/local/mysql/data/ndb_5_fs/
total 110873
drwxr-x--- 9 root mysql 512 Dec 14 17:05 ./
drwxr-x--- 5 mysql mysql 512 Dec 14 16:19 ../
drwxr-x--- 4 root mysql 512 Dec 14 16:18 D1/
drwxr-x--- 3 root mysql 512 Dec 14 16:17 D10/
drwxr-x--- 3 root mysql 512 Dec 14 16:17 D11/
drwxr-x--- 4 root mysql 512 Dec 14 16:18 D2/
drwxr-x--- 3 root mysql 512 Dec 14 16:17 D8/
drwxr-x--- 3 root mysql 512 Dec 14 16:17 D9/
drwxr-x--- 3 root mysql 512 Dec 14 16:18 LCP/
-rw-r--r-- 1 root mysql 33619968 Dec 14 16:45 data_1.dat
-rw-r--r-- 1 root mysql 50397184 Dec 14 17:05 data_2.dat
-rw-r--r-- 1 root mysql 16777216 Dec 14 16:43 undo_1.dat
-rw-r--r-- 1 root mysql 12582912 Dec 14 17:03 undo_2.dat

障害時動作テスト

停電等で、全ノードがダウンしてもデータが消失しないか

管理デーモンシャットダウン(管理ノード)


/usr/local/mysql/bin/ndb_mgm

-- NDB Cluster -- Management Client --
ndb_mgm> shutdown
Node 2: Cluster shutdown initiated
Node 3: Cluster shutdown initiated
Node 4: Cluster shutdown initiated
Node 5: Cluster shutdown initiated

Node 2: Node shutdown completed.
Node 3: Node shutdown completed.
4 NDB Cluster node(s) have shutdown.
Disconnecting to allow management server to shutdown.
Node 4: Node shutdown completed.
ndb_mgm> exit

NDBDシャットダウン(Dataノード)

前述の管理デーモンshutdownにて自動的にダウンします。なので作業不要。

MySQLデーモンシャットダウン(SQLノード)

データ消失のテストとしては、特にSQLノードは落とす必要はないがついでなので落としちゃいます。


sudo /usr/local/mysql/support-files/mysql.server stop

OS自体のシャットダウン

今回はjail環境なので、仮想的にサーバーを落としメモリをクリアします。

OS起動

今回はjail環境なので、仮想的にサーバーを起動します。

各ノードの起動
  • 管理ノード起動(管理ノード)
  • Dataノード起動(Dataノード)
  • 管理ノードで確認(管理ノード)
  • SQLノード起動(SQLノード)
  • 管理ノードで確認(管理ノード)

詳細はそれぞれの段落を参照

データの確認


/usr/local/mysql/bin/mysql;

mysql> use test;
mysql> SELECT * FROM ctest;
+------+
| i |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.00 sec)
データが消失していないことが確認できた。


現場で使える MySQL
MySQL Clustering (ペーパーバック)
実践ハイパフォーマンスMySQL (単行本)