How To Set Up A Load-Balanced MySQL Cluster (NDB CLUSTER)

This tutorial shows how to configure a MySQL 5 cluster with three
nodes: two storage nodes and one management node. This cluster is
load-balanced by a high-availability load balancer that in fact has two
nodes that use the Ultra Monkey package which provides heartbeat (for checking if the other node is still alive) and ldirectord (to split up the requests to the nodes of the MySQL cluster).

In this document I use Ubuntu8.10 for all nodes. Therefore the
setup might differ a bit for other distributions. The MySQL version I
use in this setup is mysql-cluster 7.0.7.

This howto is meant as a practical guide; it does not cover the
theoretical backgrounds. They are treated in a lot of other documents
in the web.

This document comes without warranty of any kind! I want to say that
this is not the only way of setting up such a system. There are many
ways of achieving this goal but this is the way I take. I do not issue
any guarantee that this will work for you!

1 My Servers

I use the following Ubuntu servers that are all in the same network (192.168.1.x in this example):

  • MySQL cluster node 1
  • MySQL cluster node 2
  • Load Balancer 1 + MySQL cluster management server
  • Load Balancer 2

In addition to that we need a virtual IP address :
It will be assigned to the MySQL cluster by the load balancer so that
applications have a single IP address to access the cluster.

Although we want to have two MySQL cluster nodes in our MySQL
cluster, we still need a third node, the MySQL cluster management
server, for mainly one reason: if one of the two MySQL cluster nodes
fails, and the management server is not running, then the data on the
two cluster nodes will become inconsistent ("split brain"). We also need it for configuring the MySQL cluster.

So normally we would need five machines for our setup:

2 MySQL cluster nodes + 1 cluster management server + 2 Load Balancers = 5

As the MySQL cluster management server does not use many resources,
and the system would just sit there doing nothing, we can put our first
load balancer on the same machine, which saves us one machine, so we
end up with four machines.

2 Set Up The MySQL Cluster Management Server

First we have to download MySQL-Cluster 7.0.7 and install the cluster management server (ndb_mgmd) and the cluster management client (ndb_mgm – it can be used to monitor what’s going on in the cluster). The following steps are carried out on (

mkdir /usr/src/mysql-mgm
cd /usr/src/mysql-mgm
tar xvfz mysql-cluster-gpl-7.0.7-linux-i686-glibc23.tar.gz
cd mysql-cluster-gpl-7.0.7-linux-i686-glibc23
mv bin/ndb_mgm /usr/bin
mv bin/ndb_mgmd /usr/bin
chmod 755 /usr/bin/ndb_mg*
cd /usr/src
rm -rf /usr/src/mysql-mgm

Next, we must create the cluster configuration file, /var/lib/mysql-cluster/config.ini:

mkdir /var/lib/mysql-cluster
cd /var/lib/mysql-cluster
vi config.ini





# Section for the cluster management node
# IP address of the management node (this system)

# Section for the storage nodes
# IP address of the first storage node
DataDir= /var/lib/mysql-cluster

# IP address of the second storage node

# one [MYSQLD] per storage node

Please replace the IP addresses in the file appropriately.

We may need to create directory for default config when mgm running.

mkdir -p /usr/local/mysql/mysql-cluster

Then we start the cluster management server:

ndb_mgmd -f /var/lib/mysql-cluster/config.ini

It makes sense to automatically start the management server at
system boot time
, so we create a very simple init script and the
appropriate startup links:

echo ‘ndb_mgmd -f /var/lib/mysql-cluster/config.ini’ > /etc/init.d/ndb_mgmd
chmod 755 /etc/init.d/ndb_mgmd
update-rc.d ndb_mgmd defaults

3 Set Up The MySQL Cluster Nodes (Storage Nodes)

Now we install mysql-max-5.0.19 on both and

groupadd mysql
useradd -g mysql mysql
cd /usr/local/
tar xvfz mysql-cluster-gpl-7.0.7-linux-i686-glibc23.tar.gz
ln -s mysql-cluster-gpl-7.0.7-linux-i686-glibc23 mysql
cd mysql

./scripts/mysql_install_db –no-defaults –port=3306
–socket=/tmp/mysql.sock –skip-locking –key_buffer=16M
–max_allowed_packet=1M –table_cache=64 –sort_buffer_size=512K
–net_buffer_length=8K –read_buffer_size=256K 
–read_rnd_buffer_size=512K –myisam_sort_buffer_size=8M
–log-bin=mysql-bin –server-id=1 –user=mysql
–socket=/var/run/mysqld/mysqld.sock  –port=3306
–basedir=/usr/local/mysql –datadir=/usr/local/mysql/var –tmpdir=/tmp
–skip-external-locking –bind-address= –key_buffer=16M
–max_allowed_packet=16M –thread_stack=128K –thread_cache_size=8
–query_cache_limit=1M –query_cache_size=16M –expire_logs_days=10

chown -R root:mysql .
chown -R mysql data
cp support-files/mysql.server /etc/init.d/
chmod 755 /etc/init.d/mysql.server
update-rc.d mysql.server defaults
cd /usr/local/mysql/bin
mv * /usr/bin
cd ../
rm -fr /usr/local/mysql/bin
ln -s /usr/bin /usr/local/mysql/bin

Then we create the MySQL configuration file /etc/my.cnf on both nodes: /

vi /etc/my.cnf

# IP address of the cluster management node

# IP address of the cluster management node

Make sure you fill in the correct IP address of the MySQL cluster management server.

Next we create the data directories and start the MySQL server on both cluster nodes: /

mkdir /var/lib/mysql-cluster
cd /var/lib/mysql-cluster
ndbd –initial
/etc/init.d/mysql.server start

(Please note: we have to run ndbd –initial only when the start MySQL for the first time, and if /var/lib/mysql-cluster/config.ini on changes.)

Now is a good time to set a password for the MySQL root user: /

mysqladmin -u root password yourrootsqlpassword

We want to start the cluster nodes at boot time, so we create an ndbd init script and the appropriate system startup links: /

echo ‘ndbd’ > /etc/init.d/ndbd
chmod 755 /etc/init.d/ndbd
update-rc.d ndbd defaults

4. การทดสอบ MySQL Cluster

ขั้นตอนที่ 1 : ทดสอบว่า MySQL cluster management server (sqlmang: สามารถ query สถานะของ cluster ได้หรือไม่
ขั้นตอนที่ 2 : ทดสอบการ replicate ข้อมูลของ storage node ทั้งสองเครื่อง (sqlnode1: และ sqlnode2:
ขั้นตอนที่ 3 : ทดสอบการเรียกใช้งานข้อมูลจากฐานข้อมูลผ่านทาง web application (PHP)

ขั้นตอนที่ 1 : จะทดสอบโดยการ kill process ndbd ของ storage node nodeใดนnodeหนึ่ง (ในที่นี้เลือก sqlnode1:

กรณีที่ storage node ทั้งสองเครื่องทำงานปกติ


คำสั่ง ndb_mgm เพื่อ run cluster management client (ndb_mgm)
สำหรับตรวจสอบว่ามี cluster node (storage node) ใด connect อยู่บ้าง



– NDB Cluster — Management Client –

ใช้คำสั่ง show สำหรับการแสดงผล

ใช้คำสั่ง quit เพื่อออกจาก ndb_mgm client console

ndb_mgm> quit;

กรณีที่ storage node nodeใดnodeหนึ่ง (ในที่นี้เลือก sqlnode1: process ndbd ไม่ทำงาน


ทำการ kill process ndbd โดยใช้คำสั่ง

killall ndbd

ขณะที่ run คำสั่ง killall ndbd ที่ sqlnode1: ที่หน้า ndb_mgm
client console ของ MySQL cluster management server
(sqlmang: จะแสดง

ndb_mgm>Node 2: Node shutdown completed. Initiated by signal 15.

ตรวจสอบว่า process ndbd ยัง run อยู่หรือไม่โดยใช้คำสั่ง

ps aux | grep ndbd | grep -iv grep

ในกรณีที่ยังมี process ndbd run อยู่ให้ใช้คำสั่ง killall ndbd อีกจนกระทั่งไม่มี process ndbd ทำงานอยู่

จากนั้นให้ทำการตรวจสอบสถานะของ cluster บน MySQL cluster management server (sqlmang:


สังเกตว่า sqlnode2: จะทำหน้าที่เป็น Master แทน sqlnode1:

ถ้าต้องการให้ sqlnode1: กลับมาทำงานได้ตามปกติ ให้ใช้คำสั่ง



จากนั้นตรวจสอบสถานะการทำงานของ cluster บน MySQL cluster management server (sqlmang:


สังเกตว่า sqlnode2: จะยังคงทำหน้าที่เป็น Master อยู่ถึงแม้ sqlnode1: จะทำงานได้ตามปกติแล้ว

ที่ 2 : ทดสอบโดยจะสลับกันเพิ่มข้อมูลที่ storage node nodeใดnodeหนึ่ง
ซึ่งผลที่ได้ข้อมูลภายในฐานข้อมูลที่ storage node ทั้งสองต้องเหมือนกัน

กำหนด การสร้างตาราง (table) ภายในฐานข้อมูลใด ๆ ที่ใช้สำหรับ cluster
จำเป็นต้องกำหนดให้ table เหล่านั้นใช้ ENGINE=NDBCLUSTER ถ้าคุณใช้
ENGINE ประเภทอื่น จะไม่สามารถทำ cluster ได้

เริ่มต้นสร้างฐานข้อมูลและ table สำหรับการทดสอบที่ sqlnode1:


mysql -u root -p
USE test_db;
INSERT INTO test_table () VALUES (1);
INSERT INTO test_table () VALUES (2);
SELECT * FROM test_table;

ผลลัพธ์ที่ได้จากการ select ข้อมูลมีดังนี้

ที่ sqlnode2: เราสร้างเพียงฐานข้อมูล
sqlnode1: ซึ่ง table และข้อมูลต่าง ๆ ภายใน table จะถูก
replicate เองโดยอัตโนมัติ


mysql -u root -p
USE test_db;
SELECT * FROM test_table;

ผลลัพธ์ที่ได้จากการ select ข้อมูลมีดังนี้

จากการทดสอบนี้แสดงให้เห็นว่าข้อมูลได้ถูก replicate จาก sqlnode1: มาที่ sqlnode2:

ลองเปลี่ยนให้มีการ replicate ข้อมูลจาก sqlnode2: ไปที่ sqlnode1: บ้าง


INSERT INTO test_table () VALUES (3);


mysql -u root -p
USE test_db;
SELECT * FROM test_table;

ผลลัพธ์ที่ได้จากการ select ข้อมูลมีดังนี้

แสดงให้เห็นว่าข้อมูลที่ storage node ทั้งสองเหมือนกันตลอด

ขั้นตอนที่ 3 : โดยในการทดสอบนี้ได้จำลองเครื่องของผู้เขียนเองเป็น web server โดยลงโปรแกรม AppServ

เริ่มต้นทำการ replicate ข้อมูลจาก storage node ไป API node (sqlload: ดังนี้


mysql -u root -p
USE test_db;
SELECT * FROM test_table;

ผลลัพธ์ที่ได้จากการ select ข้อมูลมีดังนี้




Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  เปลี่ยนแปลง )

Google+ photo

You are commenting using your Google+ account. Log Out /  เปลี่ยนแปลง )

Twitter picture

You are commenting using your Twitter account. Log Out /  เปลี่ยนแปลง )

Facebook photo

You are commenting using your Facebook account. Log Out /  เปลี่ยนแปลง )


Connecting to %s