建立Mysql的叢集式資料庫可以讓Mysql的可用性更大,提昇服務的能量和質量。在以下的設定中,防火牆和selinux都是enabled,細節比較多,此文分幾個部分:
[Mysql] 建立叢集式資料庫1/4 -- 安裝及設定DB1
[Mysql] 建立叢集式資料庫2/4 -- DB2、DB3設定及測試
DB1還是處於初始啟動的狀態,而且SELINUX也是關掉的,接下來要啟動SELINUX同時也得關閉DB1的初始狀態。
十、關閉DB1的初始設定狀態
# ps -aux | grep 'mysqld'
找到這行
root 3690 0.0 0.1 193328 2772 pts/0 S 21:39 0:00 sudo -u mysql mysqld --wsrep-new-cluster
mysql 3691 0.0 13.1 2009856 247680 pts/0 Sl 21:39 0:06 mysqld --wsrep-new-cluster
直接殺掉程序執行者是mysql的 3691
# kill 3691
十一、DB1修改及啟動SELINUX
# vi /etc/my.cnf.d/server.cnf
原本這行是空的加入節點IP
依 [Mysql] 建立叢集式資料庫2/3 -- DB2、DB3設定及測試@新精讚 步驟八法三設定
設定完畢後啟動 SELINUX
# setenforce 1
重啟mysql
# systemctl restart mysql
< 正常情況沒有回應 >
十二、測試
若先不進行測試,請直接跳第十三步驟
測試一 資料庫的同步
再來是可怕的測試,我會在 DB1寫入一筆資料,再看看DB2、DB3能不能讀得出來。
[DB1] 建立一個空表格
MariaDB [test]> CREATE TABLE IF NOT EXISTS `content` ( `nID` int(11) NOT NULL, `sn` varchar(16) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.01 sec)
MariaDB [test]> show tables;
+----------------+
| Tables_in_test |
+----------------+
| content |
+----------------+
1 row in set (0.00 sec)
[DB2,DB3] 查詢此表是否有建立
MariaDB [test]> show tables;
+----------------+
| Tables_in_test |
+----------------+
| content |
+----------------+
1 row in set (0.00 sec)
可以看到幾乎是同步的建立。接下來從DB3或DB2刪除這個表格,發現其他DB也是瞬間刪除(過程略)。
測試二 結點的運作
現在假設DB3突然離線,我把他stop,並在DB2新增表格,再將DB3啟動,查看DB3是否有自動回復內容。
結果
一旦關掉DB3,在DB2的狀態中,節點立刻變為2,代表結點已離線。
| wsrep_cluster_size | 2 <==結點少1 |
| wsrep_incoming_addresses | 192.168.1.252:3306,192.168.1.251:3306 <==該IP消失 |
在DB2新增完表格後,將DB3啟動,出現錯誤,但事實上有啟動成功,資料也同步完成
Job for mariadb.service failed because a fatal signal was delivered to the control process. See "systemctl status mariadb.service" and "journalctl -xe" for details.
查看記錄也沒有什麼錯誤??
總之運作很順利。
測試完畢後,在DB1, DB2, DB3... 分別設定開機啟動:
# systemctl enable mariadb
測試三 全部關機再啟動的程序
這個測試把三台DB都停機,再重開,來看看重開後能不能正常運作。原來三台都重開的話得進入bootstrap程序[1]
結果
三台全部關閉後再重開,自動啟動都會失敗,得進行DB1的初次啟動程序後再分別啟動DB2,DB3...
處理
[DB1]
# sudo -u mysql mysqld --wsrep-new-cluster &
[DB2,3...]
# systemctl start mysql
[DB1]
# kill <pid number>
# systemctl start mysql
結果頗出我意料,竟然全關再開這麼麻煩,如果啟動時出現錯誤,請參考下一篇#4的附錄5
測試四 手動關閉DB3,強制關閉DB2,保留DB1後再重開DB2,DB3
當部分DB失敗時,狀況又是如何,其中DB2是暴力關閉(模擬電源失效),DB3手動關機
結果
DB2,DB3重開機啟動後沒有自動加入,DB1運作中
DB1重啟mysql後出現錯誤
[ERROR] WSREP: wsrep::connect(gcomm://192.168.1.251,192.168.1.252,192.168.1.253) failed: 7
[ERROR] Aborting
處理
[DB1]
# vi /var/lib/mysql/grastate.dat
把數值改為1
safe_to_bootstrap: 1
# sudo -u mysql mysqld --wsrep-new-cluster &
[DB2] 因為電源失效,啟動上失敗,參考[2]的方式解決
at gcomm/src/pc.cpp:PC():267
[ERROR] WSREP: gcs/src/gcs_core.cpp:gcs_core_open():208: Failed to open b
[ERROR] WSREP: gcs/src/gcs.cpp:gcs_open():1404: Failed to open channel 'm
[ERROR] WSREP: gcs connect failed: State not recoverable
# cd /var/lib/mysql/
# mv grastate.dat grastate.dat.bk
# mv gvwstate.dat gvwstate.dat.bk
# systemctl start mysql
[DB3]
# systemctl start mysql
十三、建立 HAPROXY
以上建立的 mysql cluster可以作為平行擴展的用途,也就是一個Web配合一個DB,倘若要設定單一Web配多個DB,就得要設定一個單一入口,由此入口分配決定交由哪個資料庫來執行,HAPROXY就是這個目的。
HAPROXY是TCP層級的,並不是SQL層級的,接下來安裝並使用HAPROXY,我把他裝在這台叫作HA的機器上
安裝
[HA]
# yum install haproxy -y
# vi /etc/haproxy/haproxy.cfg
#--------------------------------------------------------------------- # Global settings #--------------------------------------------------------------------- global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon # turn on stats unix socket stats socket /var/lib/haproxy/stats defaults # 如果伺服器掛了要 retry 的次數 retries 2 #--------------------------------------------------------------------- # Load Balancing for Galera Cluster #--------------------------------------------------------------------- listen galera *:3306 balance source mode tcp option tcpka # option mysql-check user haproxy server node1 192.168.1.251:3306 check weight 1 server node2 192.168.1.252:3306 check weight 1 server node3 192.168.1.253:3306 check weight 1 #--------------------------------------------------------------------- # HAProxy stats web gui #--------------------------------------------------------------------- listen stats *:8088 mode http stats enable stats uri / stats realm HAProxy\ Statistics stats auth username:yourpassword stats admin if TRUE
第25行設定平衡的方式,有 roundrobin, static-rr, leastconn, first, source等幾種方式[3]:
roundrobin 由權重輪巡
static-rr 由權重輪巡,無法動態改變權重外,和 roundrobin相同
leastconn 連接數最小的優先
first 先把一台灌爆再換下一台,由id數小的選到最大的
source 由來源的IP來分組,確保每個IP來源會連到同一個DB
第29行設定mysql-check,才能有效率的查看連線的情況,先註解,待運作順利後再打開,詳細請參看附錄一[3]
第37~43行是管理介面,其中第38行是設定進入的帳密
十四、設定防火牆及SELINUX
開啟防火牆
# firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="3306" protocol="tcp" accept' --permanent
# firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="8080" protocol="tcp" accept' --permanent
另外這台也是網頁伺服器
# firewall-cmd --zone=public --add-port=80/tcp --permanent
因為是由HAPROXY來開啟服務,因此SELINUX設定[5]
# setsebool -P haproxy_connect_any 1
十五、啟動HAPROXY
啟動
# systemctl start haproxy
關閉
# systemctl stop haproxy
開機啟動
# systemctl enable haproxy
重啟
# systemctl restart haproxy
查看狀態
# systemctl status haproxy
參考資料
[1] http://galeracluster.com/documentation-webpages/restartingcluster.html
[2] https://github.com/codership/galera/issues/354
[3] http://galeracluster.com/documentation-webpages/haproxy.html