[Mysql] 建立叢集式資料庫3/4 -- DB1設置及DB PROXY

URL Link //n.sfs.tw/11042

2017-05-07 23:37:30 By 張○○

建立Mysql的叢集式資料庫可以讓Mysql的可用性更大,提昇服務的能量和質量。在以下的設定中,防火牆和selinux都是enabled,細節比較多,此文分幾個部分:

[Mysql] 建立叢集式資料庫1/4 -- 安裝及設定DB1

[Mysql] 建立叢集式資料庫2/4 -- DB2、DB3設定及測試

[Mysql] 建立叢集式資料庫3/4 -- DB1設置及DB PROXY

[Mysql] 建立叢集式資料庫4/4--觀察及測試

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

wsrep_cluster_address='gcomm://192.168.1.251,192.168.1.252,192.168.1.253'

[Mysql] 建立叢集式資料庫2/3 -- DB2、DB3設定及測試@新精讚 步驟八法三設定

設定完畢後啟動 SELINUX

# setenforce 1

重啟mysql

# systemctl restart mysql

< 正常情況沒有回應 >

十二、測試

若先不進行測試,請直接跳第十三步驟

測試一 資料庫的同步

再來是可怕的測試,我會在 DB1寫入一筆資料,再看看DB2、DB3能不能讀得出來。

[DB1] 建立一個空表格

MariaDB [(none)]> use test;
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 [(none)]> use test;

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,代表結點已離線。

MariaDB [test]> show status like 'wsrep%';
| wsrep_cluster_size           | 2                      <==結點少1                       |
| wsrep_incoming_addresses     | 192.168.1.252:3306,192.168.1.251:3306       <==該IP消失  |

在DB2新增完表格後,將DB3啟動,出現錯誤,但事實上有啟動成功,資料也同步完成

# systemctl start mysql
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: It may not be safe to bootstrap the cluster from this node. It was not the last one to leave the cluster and may not contain all the updates. To force cluster bootstrap with this node, edit the grastate.dat file manually and set safe_to_bootstrap to 1 .
[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]的方式解決

[ERROR] WSREP: failed to open gcomm backend connection: 131: invalid UUID
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

[4] 富人用 L4 Switch,窮人用 Linux HAProxy!

[5] https://www.mankier.com/8/haproxy_selinux