構建MySQL集羣
一、目標
1.安裝MySQL-Cluster相關軟件包。
2.依次配置管理/數據/SQL節點。
3.啓動並測試MySQL-Cluster集羣架構。
二、方案
使用6臺RHEL 6.5虛擬機,如圖所示。其中sql1和sql2作爲SQL節點,ndb1和ndb2作爲數據節點,mgmsvr作爲管理節點,這5個節點構成MySQL Cluster體系;而另一臺虛擬機192.168.4.1作爲測試客戶機。
構成MySQL集羣體系的5個節點應安裝Cluster版的MySQL相關軟件包;測試用的Linux客戶機只需安裝普通版的MySQL-client即可。
三、實現
1、準備工作
1)確認各節點服務器的IP地址,使各節點能互通,防火牆和selinux處於關閉狀態。
關閉防火牆:
# iptables -F //清空防火牆條目
# service iptables stop //關閉防火牆
# chkconfig iptables off //開機不自啓
關閉selinux:
vim打開 /etc/selinux/config修改SELINUX=disabled
# getenforce 0
2)卸載所有節點上的衝突包
官方提供的MySQL-Cluster相關軟件包(可在這裏獲得 http://pan.baidu.com/s/1sjsILAX)已集成數據庫服務端/客戶端程序,因此可直接用來替換普通的MySQL服務端/客戶端程序。如果已安裝有普通版的mysql-server、mysql、MySQL-server、MySQL-client包,先將其卸載(若沒有則忽略):
# rpm -qa | grep -i mysql //檢查有沒有安裝普通版的mysql軟件
對於RHEL自帶的mysql-libs暫時保留(如果直接卸載會因爲依賴關係刪除許多重要的包,比如crontab、postfix等),但在安裝MySQl-Cluster相關包的時候採用“-U”升級的方式執行替換。
# rpm -e --nodeps MySQL-client
如果有殘留的/etc/my.cnf文件,確保已轉移備用或直接刪除。
# mv /etc/my.cnf /etc/my.cnf.bak
3)在所有節點上,解壓下載的MySQL-Cluster集合包
# tar xvf MySQL-Cluster-gpl-7.3.3-1.el6.x86_64.rpm-bundle.tar
MySQL-Cluster-shared-gpl-7.3.3-1.el6.x86_64.rpm
MySQL-Cluster-shared-compat-gpl-7.3.3-1.el6.x86_64.rpm //安裝共享庫和兼容包
MySQL-Cluster-server-gpl-7.3.3-1.el6.x86_64.rpm //安裝服務端程序
MySQL-Cluster-client-gpl-7.3.3-1.el6.x86_64.rpm //安裝客戶端程序
MySQL-Cluster-test-gpl-7.3.3-1.el6.x86_64.rpm
MySQL-Cluster-devel-gpl-7.3.3-1.el6.x86_64.rpm
MySQL-Cluster-embedded-gpl-7.3.3-1.el6.x86_64.rpm
在SQL節點(sql1、sql2)服務器上,修改MySQL數據庫的root密碼:
[root@sql1 ~]# service mysql start //啓動MySQL服務程序
Starting MySQL... [確定]
[root@sql2 ~]# cat /root/.mysql_secret
# The random password set for the root user at Wed Sep 3 21:04:20 2014 (local time): msA7Bq2B
[root@sql1 ~]# mysql –u root –pmsA7Bq2B //以上述默認密碼登錄
mysql> set password=password("123456");
Query OK, 0 rows affected (0.17 sec)
在數據節點(ndb1、ndb2)和管理節點(mgmsvr)上,實際上並不需要啓動MySQL服務程序,因此建議將mysql服務的自啓狀態設爲關閉
[root@ndb1 ~]# chkconfig mysql off
4)在sql節點添加授權數據庫用戶
在SQL節點(sql1、sql2)服務器上,添加相應的授權數據庫用戶,以方便客戶端使用數據庫服務。以用戶user爲例,允許其從192.168.4.0/24網段訪問:
mysql> grant all on *.* to user@'192.168.4.%' identified by "123456";
Query OK, 0 rows affected (0.03 sec)
2、配置管理節點mgmsvr(192.168.4.3)
1)創建工作文件夾
爲管理節點提供一個工作目錄,方便記錄mysql集羣相關的日誌消息:
[root@mgmsvr ~]# mkdir /var/log/mysql-cluster
2)創建配置文件
在管理節點的配置文件中,應涵蓋所有節點的設置,主要包括各節點的ID號、主機名或IP地址、工作目錄等信息。
針對本實驗,管理節點的配置參考如下:
[root@mgmsvr ~]# cat /etc/config.ini //文件名可以隨意
[ndbd default] //爲所有的節點指定默認配置
NoOfReplicas=2//保留2份數據拷貝
DataMemory=80M//數據緩存大小
IndexMemory=18M//索引緩存大小
[ndb_mgmd]//指定一個管理節點的配置,可以有多個管理節點
nodeid=3//節點的id號,作爲節點的唯一識別碼,不可以與其他節點相同
hostname=192.168.4.3 //節點的ip地址
datadir=/var/log/mysql-cluster //該管理節點的工作目錄
[ndbd]//指定數據節點的配置,每個數據節點對應一個ndbd配置
nodeid=4
hostname=192.168.4.4
datadir=/var/log/mysql-cluster/data
[ndbd]
nodeid=5
hostname=192.168.4.5
datadir=/var/log/mysql-cluster/data
[mysqld]//指定SQL節點的配置,每個SQL節點對應一個配mysqld置
nodeid=6
hostname=192.168.4.6
[mysqld]
nodeid=7
hostname=192.168.4.7
3、配置數據節點,分別在ndb1 (192.168.4.4)、ndb2(192.168.4.5)上做下面的操作
1)創建工作文件夾
爲各數據節點提供一個工作目錄,用來存放實際的數據庫表記錄等相關數據:
[root@ndb1~]# mkdir -p /var/lib/mysql-cluster/data
2)創建配置文件
指定一個數據存儲目錄,管理服務器的IP地址、採用ndbcluster存儲引擎,以便支持集羣特性;並添加[mysql_cluster]配置段,同樣指定管理地址。
針對本實驗,2個數據節點的配置參考如下:
[root@ndb1 ~]# cat /etc/my.cnf
[mysqld]
datadir=/var/log/mysql-cluster/data //指定數據存儲目錄
ndb-connectstring=192.168.4.3 //要連接的管理服務器的ip地址
Ndbcluster//指定運行的存儲引擎
[mysql_cluster]//集羣連接配置
ndb-connectstring=192.168.4.3 //管理服務器的地址
4、配置SQL節點,分別在sql1(192.168.4.6)、sql2(192.168.4.7)上做下面的操作
調整my.cnf配置,指定運行的存儲引擎、默認存儲引擎,並通過[mysql_cluster]配置段指定管理地址。在MySQL-Cluster集羣環境中,若某個數據庫未採用ndbcluster引擎(而是InnoDB、MyISAM等其他引擎),則當更新數據庫表時,可能無法同步到其他節點。
[root@sql1 ~]# cat /etc/my.cnf
[mysqld]
ndbcluster //指定運行的存儲引擎
default-storage-engine=ndbcluster //指定默認的存儲引擎
[mysql_cluster]
ndb-connectstring=192.168.4.3 //管理服務器的地址
5、啓動MySQL集羣
正確的啓動順序:管理節點 --> 數據節點 --> SQL節點。
關閉順序:SQL節點 --> 數據節點 --> 管理節點。
1)啓動管理節點
MySQL Cluster管理節點的對應服務程序爲ndb_mgmd,通過選項-f指定建立的集羣配置文件。
[root@mgmsvr ~]# ndb_mgmd -f /etc/config.ini
關於管理節點的啓動,有以下幾個需要注意的地方:
ndb_mgmd默認以後臺模式運行(--daemon),調試過程中可添加選項--nodaemon來禁用後臺模式。
ndb_mgmd初次啓動成功以後,會自動保存集羣配置,以後再啓動時會忽略-f指定的配置文件,除非添加--initial選項(比如向集羣中添加新的節點時,就應該重新初始化)。
若希望每次開機後自動運行ndb_mgmd,可將上述啓動操作寫入到/etc/rc.local配置文件內,例如:
[root@mgmsvr ~]# cat /etc/rc.local
.. ..
ndb_mgmd -f /etc/my-cluster.ini
啓動完成後查看監聽狀態:
[root@svr3 ~]# netstat -anpt | grep ndb
tcp 0 0 0.0.0.0:1186 0.0.0.0:* LISTEN 3809/ndb_mgmd
tcp 0 0 127.0.0.1:1186 127.0.0.1:54902 ESTABLISHED 3809/ndb_mgmd
tcp 0 0 127.0.0.1:54902 127.0.0.1:1186 ESTABLISHED 3809/ndb_mgmd
2)啓動數據節點ndb1、ndb2
MySQL Cluster數據節點的對應服務程序爲ndbd(單線程的)、ndbmtd(多線程的),首次啓動或重新初始化時加 --initial選項,以後不用加。
啓動ndb1:
[root@ndb1 ~]# ndbd --initial
2014-09-05 20:15:17 [ndbd] INFO -- Angel connected to '192.168.4.3:1186'
2014-09-05 20:15:17 [ndbd] INFO -- Angel allocated nodeid: 4
啓動ndb2;
[root@ndb2 ~]# ndbd --initial
2014-09-05 20:15:44 [ndbd] INFO -- Angel connected to '192.168.4.3:1186'
2014-09-05 20:15:44 [ndbd] INFO -- Angel allocated nodeid: 5
在ndb1和ndb2服務器上,修改/etc/rc.local配置文件,以便每次開機後能自動啓動數據節點服務:
[root@ndb1 ~]# cat /etc/rc.local
.. ..
ndbd
3)啓動SQL節點sql1、sql2
對於MySQL Cluster的SQL節點來說,對應的服務程序就是mysqld,正常通過mysql腳本重新啓動服務就可以了。啓動sql1:
[root@sql1~]# service mysql restart
Shutting down MySQL..... SUCCESS!
Starting MySQL................................ SUCCESS!
[root@sql1~]# chkconfig mysql on //開機自啓
啓動sql2:
[root@sql2 ~]# service mysql restar
Shutting down MySQL..... SUCCESS!
Starting MySQL.........SUCCESS
[root@sql2 ~]# chkconfig mysql on
成功啓動後,可在本機登入mysql>環境,檢查默認的存儲引擎,確保已支持ndbcluster且作爲默認存儲引擎:
[root@sql1 ~]# mysql -uuser -p123456
... ...
mysql> show engines\G;
*************************** 1. row ***************************
Engine: ndbcluster
Support: DEFAULT
Comment: Clustered, fault-tolerant tables
Transactions: YES
XA: NO
Savepoints: NO
*************************** 2. row ***************************
Engine: MRG_MYISAM
Support: YES
Comment: Collection of identical MyISAM tables
Transactions: NO
XA: NO
Savepoints: NO
... ...
4)在管理節點上查看集羣狀態
[root@mgmsvr 桌面]# ndb_mgm
-- NDB Cluster -- Management Client --
ndb_mgm> show //查看當前各節點的狀態
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]2 node(s) //兩個數據節點
id=4@192.168.4.4 (mysql-5.6.14 ndb-7.3.3, Nodegroup: 0, *)
id=5@192.168.4.5 (mysql-5.6.14 ndb-7.3.3, Nodegroup: 0)
[ndb_mgmd(MGM)]1 node(s) //一個管理節點
id=3@192.168.4.3 (mysql-5.6.14 ndb-7.3.3)
[mysqld(API)]2 node(s)//兩個SQL節點
id=6@192.168.4.6 (mysql-5.6.14 ndb-7.3.3)
id=7 @192.168.4.7 (mysql-5.6.14 ndb-7.3.3)
6.MySQL集羣的高可用性測試
1)數據同步測試
從客戶機訪問sql1,執行寫數據庫、表相關操作:
[root@client~]# mysql -u user -h 192.168.4.6 -p
Enter password: //驗證口令
.. ..
mysql> CREATE DATABASE testdb; //新建testdb庫
Query OK, 1 row affected (0.04 sec)
mysql> USE testdb; //切換到testdb庫
Database changed
mysql> CREATE TABLE tab1(id int(4)); //新建tab1表
Query OK, 0 rows affected (0.14 sec)
mysql> INSERT INTO testdb.tab1 VALUES(1234),(5678); //插入測試記錄
Query OK, 2 rows affected (0.02 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM tab1; //確認添加的表記錄
+------+
| id |
+------+
| 1234 |
| 5678 |
+------+
2 rows in set (0.02 sec)
然後從客戶機訪問sql2,確認結果(能看到從sql1上所建的庫、表、表記錄):
[root@client~]# mysql -u user -h 192.168.4.7 -p
Enter password: //驗證口令
.. ..
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| ndbinfo |
| performance_schema |
| test |
| testdb | //確認可看到testdb庫
+--------------------+
6 rows in set (0.13 sec)
mysql> USE testdb; //切換到testdb庫
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> SELECT * FROM tab1; //查看錶記錄也一致
+------+
| id |
+------+
| 1234 |
| 5678 |
+------+
2 rows in set (0.09 sec)
反過來從sql2上所作的數據庫表操作,從sql1上也能獲得相同的結果。
2)高可用性測試(關閉一臺數據節點)
關閉數據節點ndb1上的ndbd進程:
[root@ndb1 ~]# netstat -anpt | grep ndbd //正常運行時
tcp 0 0 192.168.4.4:37869 0.0.0.0:* LISTEN 2092/ndbd
tcp 0 0 192.168.4.4:45945 0.0.0.0:* LISTEN 2092/ndbd
tcp 0 0 192.168.4.4:38305 0.0.0.0:* LISTEN 2092/ndbd
tcp 0 0 192.168.4.4:45945 192.168.4.5:51824 ESTABLISHED 2092/ndbd
tcp 0 0 192.168.4.4:38305 192.168.4.6:44646 ESTABLISHED 2092/ndbd
tcp 0 0 192.168.4.4:37869 192.168.4.7:53096 ESTABLISHED 2092/ndbd
tcp 0 0 192.168.4.4:33238 192.168.4.3:1186 ESTABLISHED 2091/ndbd
tcp 0 0 192.168.4.4:33239 192.168.4.3:1186 ESTABLISHED 2092/ndbd
[root@ndb1 ~]# killall -9 ndbd //強制結束ndbd進程
[root@ndb1 ~]# netstat -anpt | grep ndbd //確認已結束
此時從管理節點上查看集羣狀態,會發現ndb1已斷開連接:
ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)]2 node(s) //兩個數據節點
id=4@192.168.4.4 (not connected, accepting connect from 192.168.4.4)
id=5@192.168.4.5 (mysql-5.6.14 ndb-7.3.3, Nodegroup: 0, *)
[ndb_mgmd(MGM)]1 node(s) //一個管理節點
id=3@192.168.4.3 (mysql-5.6.14 ndb-7.3.3)
[mysqld(API)]2 node(s)//兩個SQL節點
id=6@192.168.4.6 (mysql-5.6.14 ndb-7.3.3)
id=7 @192.168.4.7 (mysql-5.6.14 ndb-7.3.3)
然後從客戶機訪問sql1或sql2,仍然可讀、寫數據庫。比如可向mydb.mytb表中再添加一條記錄:
mysql> INSERT INTO testdb.tab1 VALUES(1236); //添加一條表記錄
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM testdb.tab1; //確認結果
+------+
| id |
+------+
| 1234 |
| 1236 |
| 5678 |
+------+
3 rows in set (0.00 sec)
以上測試成立說明:只要還有一臺數據節點可用,MYSQL數據庫整體就仍然可用。
接下來可進一步驗證故障恢復過程。重新啓動ndb1上的ndbd服務進程,稍待片刻後強制關閉ndb2上的ndbd服務進程。然後再次訪問sql1或sql2節點,查詢tab1表的記錄,發現與前面添加的結果一致:
[root@ndb1 ~]# ndbd
2014-09-05 21:15:17 [ndbd] INFO -- Angel connected to '192.168.4.3:1186'
2014-09-05 21:15:17 [ndbd] INFO -- Angel allocated nodeid: 4
[root@ndb2 ~]# killall -9 ndbd
[root@ndb2 ~]# netstat -anptu | grep ndb
[root@client ~]# mysql -uuser -h 192.168.4.7 -p123456
mysql> SELECT * FROM testdb.tab1; //確認結果
+------+
| id |
+------+
| 1234 |
| 1236 |
| 5678 |
+------+
3 rows in set (0.00 sec)
以上測試成立說明:因故障中斷的數據節點(ndb1)恢復後,會立即從正常的數據節點(sql2)同步數據,確保數據一致性。
3)高可用性測試(關閉一臺SQL節點)
當MySQL集羣內有多個SQL節點時,只要有一臺SQL節點可用,就可以通過它來訪問MySQL數據庫中保存的表數據。
比如說,關閉sql1、sql2中的任何一臺以後,還可以通過另外一臺來訪問mydb庫。
[root@sql1 ~]# netstat -anptu | grep mysql
tcp 0 0 192.168.4.6:44646 192.168.4.4:38305 ESTABLISHED 1545/mysqld
tcp 0 0 192.168.4.6:38400 192.168.4.3:1186 ESTABLISHED 1545/mysqld
tcp 0 0 192.168.4.6:35859 192.168.4.5:43959 ESTABLISHED 1545/mysqld
tcp 0 0 :::3306 :::* LISTEN
[root@sql1 ~]# service mysql stop
Shutting down MySQL.... SUCCESS!
[root@sql1 ~]# netstat -anptu | grep mysql
[root@client ~]# mysql -uuser -h192.168.4.6 -p
Enter password:
ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.4.6' (111) //sql1出故障,不能登錄
[root@client ~]# mysql -uuser -h192.168.4.7 -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.6.14-ndb-7.3.3-cluster-gpl MySQL Cluster Community Server (GPL)
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases; //sql2可以正常訪問
+-------------------------+
| Database |
+-------------------------+
| information_schema |
| mysql |
| ndbinfo |
| performance_schema |
| test |
| testdb |
+------------------------+
6 rows in set (0.00 sec)
四、問題和經驗總結
測試的過程中會出現各種問題,要耐心調試才行。所有問題的出現都是有原因的,出現問題後看報錯,找日誌可以快速定位造成問題的地方,然後根據提示信息,找到原因。不看日誌,盲目地重啓服務,重啓電腦,即使偶爾解決了,也不會從中得到什麼。
下面是我測試過程中,收集的一些問題:
問題1:
[root@sql2 ~]# /etc/init.d/mysql restart
MySQL server PID file could not be found! [失敗]
Starting MySQL..........................................................................................................................................................................................................................^C //實在等不下去了,只能ctrl+c中斷
這個問題經常出現,而且造成這種情況的原因比較多,在強制殺掉mysqld進程的時候會出現,在沒有關閉mysql服務的情況下修改hostname的時候也會出現,等等情況。我做法是先查看是否有mysqld的殘留進程,然後統統殺掉,再重啓服務,一般的情況下會奏效,不奏效只能去看錯誤日誌了。
問題2
如果管理節點上顯示下面的數據節點後面兩個都沒有“*”,有可能是數據節點的selinux沒有關掉。
ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)]2 node(s)
id=4@192.168.4.4 (mysql-5.6.14 ndb-7.3.3, Nodegroup: 0)
id=5@192.168.4.5 (mysql-5.6.14 ndb-7.3.3, Nodegroup: 0)
問題3
出現數據節點連接不上管理節點,如下
[root@ndb1 mysql]# ndbd --initial
2014-09-05 22:59:29 [ndbd] INFO -- Angel connected to '192.168.4.3:1186'
2014-09-05 23:00:00 [ndbd] ERROR -- Failed to allocate nodeid, error: 'Error: Could not alloc node id at 192.168.4.3 port 1186: No free node id found for ndbd(NDB).'
這是可能是因爲你的ndbd進程已經在運行,在管理節點上已經沒有可以供分配的節點id了。
在數據節點上查看進程正常就可以了,這個錯誤可以忽略。