1. 程式人生 > >MYSQL 的集群

MYSQL 的集群

java sys 不可用 ada gtid_mode innodb odi fma lis

核心架構

  • MySQL 5.7 引入了 Group Replication 功能,可以在一組 MySQL 服務器之間實現自動主機選舉,形成一主多從結構。經過高級配置後,可以實現多主多從結構。
  • MySQL Router 是一個輕量級透明中間件,可以自動獲取上述集群的狀態,規劃 SQL 語句,分配到合理的 MySQL 後端進行執行。
  • MySQL Shell 是一個同時支持 JavaScript 和 SQL 的交互程序,可以快速配置 InnoDB Cluster。
    MySQL InnoDB Cluser | Mysql 5.7 集群

部署

本次共3臺機器,設置主機名及hosts | 配置每臺服務 my.cnf 中report_host 字段,為自己的 hostname

192.168.10.123 db1
192.168.10.124 db2
192.168.10.125 db3
安裝 mysql5.7.20 ,可以參考下面的安裝基本,我搭建的時候就是用的這個。
http://blog.51cto.com/hequan/1982428
安裝mysql-shell mysql-route
wget https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm

yum install mysql57-community-release-el7-11.noarch.rpm
yum install mysql-shell -y

yum install mysql-router -y
設置相關用戶的權限,生產環境 可以不是 root用戶
grant all privileges on . to ‘root‘@‘%‘ identified by ‘123456‘;
GRANT ALL PRIVILEGES ON mysql_innodb_cluster_metadata. TO root@‘%‘ WITH GRANT OPTION;
GRANT RELOAD, SHUTDOWN, PROCESS, FILE, SUPER, REPLICATION SLAVE, REPLICATION CLIENT, \
CREATE USER ON
. TO root@‘%‘ WITH GRANT OPTION;
GRANT SELECT ON
.* TO root@‘%‘ WITH GRANT OPTION;
flush privileges;
mysqlsh

[root@db1 ~]# mysqlsh

檢查mysql 配置文件 (3臺主機都要操作此步驟)

dba.checkInstanceConfiguration(‘root@db1:3306‘)

+----------------------------------+---------------+----------------+--------------------------------------------------+
| Variable | Current Value | Required Value | Note |
+----------------------------------+---------------+----------------+--------------------------------------------------+
| binlog_checksum | CRC32 | NONE | Update the server variable or restart the server |
| binlog_format | MIXED | ROW | Update the server variable or restart the server |
| enforce_gtid_consistency | OFF | ON | Restart the server |
| gtid_mode | OFF | ON | Restart the server |
| log_slave_updates | 0 | ON | Restart the server |
| master_info_repository | FILE | TABLE | Restart the server |
| relay_log_info_repository | FILE | TABLE | Restart the server |
| transaction_write_set_extraction | OFF | XXHASH64 | Restart the server |
+----------------------------------+---------------+----------------+--------------------------------------------------+

修復mysql 配置文件, 必須用 root(3臺主機都要操作此步驟)

dba.configureLocalInstance(‘root@db1:3306‘)

Please provide the password for ‘root@db1:3306‘:
Detecting the configuration file...
Found configuration file at standard location: /etc/my.cnf
Do you want to modify this file? [Y|n]: [Y|n]: Y

重啟mysql

重新檢查 (3臺主機都要操作此步驟)

dba.checkInstanceConfiguration(‘root@db1:3306‘)
Please provide the password for ‘root@db1:3306‘:
Validating instance...

The instance ‘db1:3306‘ is valid for Cluster usage
{
"status": "ok"
}

登陸

mysqlsh --uri root@db1:3306

創建集群 main

mysql-js> var cluster = dba.createCluster(‘main‘)
A new InnoDB cluster will be created on instance ‘hequan@db1:3306‘.

Creating InnoDB cluster ‘main‘ on ‘hequan@db1:3306‘...
Adding Seed Instance...

Cluster successfully created. Use Cluster.addInstance() to add MySQL instances.
At least 3 instances are needed for the cluster to be able to withstand up to
one server failure.

添加子節點

mysql-js> cluster.addInstance(‘root@db2:3306‘)
mysql-js> cluster.addInstance(‘root@db3:3306‘)

查看節點信息

mysql-js> cluster.status()

將配置 持久化,寫入到 my.cnf

mysql-js> \connect db1
mysql-js> dba.configureLocalInstance(‘db1:3306‘)

查看基本信息

mysql-js> cluster.describe();

退出之後,再查看節點信息

var cluster = dba.getCluster();
cluster.status();
Mysql-route 設置

此命令會更新 /etc/mysqlrouter/mysqlrouter.conf 中的配置信息, 可以是別的機器 這裏選擇的為db2

[root@db2 ~]# mysqlrouter --bootstrap root@db1:3306 --user mysqlrouter

Please enter MySQL password for root:
WARNING: The MySQL server does not have SSL configured and metadata used by the router may be transmitted unencrypted.

Bootstrapping system MySQL Router instance...
MySQL Router has now been configured for the InnoDB cluster ‘main‘.

The following connection information can be used to connect to the cluster.

Classic MySQL protocol connections to cluster ‘main‘:

  • Read/Write Connections: localhost:6446 讀寫
  • Read/Only Connections: localhost:6447 只讀

X protocol connections to cluster ‘main‘:

  • Read/Write Connections: localhost:64460
  • Read/Only Connections: localhost:64470

Existing configurations backed up to /etc/mysqlrouter/mysqlrouter.conf.bak
[root@db2 ~]# systemctl start mysqlrouter

啟動

systemctl start mysqlrouter
systemctl enable mysqlrouter

查看端口

[root@db2 ~]# netstat -lntup
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:64460 0.0.0.0: LISTEN 2958/mysqlrouter
tcp 0 0 0.0.0.0:6446 0.0.0.0:
LISTEN 2958/mysqlrouter
tcp 0 0 0.0.0.0:6447 0.0.0.0: LISTEN 2958/mysqlrouter
tcp 0 0 0.0.0.0:64470 0.0.0.0:
LISTEN 2958/mysqlrouter

驗證

mysql -u root -h 127.0.0.1 -P 6446 -p

select @@port;
select @@hostname;
故障模擬

##關閉 db1 數據庫,自動切換如下:

"topology": {
"db1:3306": {
"address": "db1:3306",
"mode": "R/O",
"readReplicas": {},
"role": "HA",
"status": "(MISSING)"
},
"db2:3306": {
"address": "db2:3306",
"mode": "R/W",
"readReplicas": {},
"role": "HA",
"status": "ONLINE"
},
"db3:3306": {
"address": "db3:3306",
"mode": "R/O",
"readReplicas": {},
"role": "HA",
"status": "ONLINE"
}
##重啟db2 ,執行命令

mysql> show databases;
ERROR 2013 (HY000): Lost connection to MySQL server during query
mysql> show databases;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 20
Current database: NONE
mysql> select @@hostname;
+------------+
| @@hostname |
+------------+
| db1 |
+------------+

##重啟節點後,需要手動加入
"db2:3306": {
"address": "db2:3306",
"mode": "R/O",
"readReplicas": {},
"role": "HA",
"status": "(MISSING)"

cluster.rejoinInstance(‘root@db2:3306‘)
The instance ‘db2:3306‘ was successfully added to the MySQL Cluster.

所有節點都重啟了,重新加入

mysqlsh --uri root@db1:3306
mysql-js> var cluster = dba.rebootClusterFromCompleteOutage();

Reconfiguring the default cluster from complete outage...

The instance ‘db2:3306‘ was part of the cluster configuration.
Would you like to rejoin it to the cluster? [y|N]: y

The instance ‘db3:3306‘ was part of the cluster configuration.
Would you like to rejoin it to the cluster? [y|N]: y

The cluster was successfully rebooted.
報錯總結:

##如果節點在加入集群前,執行了寫操作,加入集群時會報錯
ERROR: Error joining instance to cluster: ‘db2:3306‘ - Query failed. MySQL Error (3092): The server is not configured properly to be an active member of the group. Please see more details on error log.. Query: START group_replication (RuntimeError)

##登陸 db2 數據庫 執行 reset master;

如果出現了 "status": "NO_QUORUM" 執行修復,重新加入

暫未測試

cluster.forceQuorumUsingPartitionOf("db1:3306")

mysql-js> cluster.rejoinInstance(‘root@db2:3306‘)
mysql-js> cluster.rejoinInstance(‘root@db3:3306‘)
附言:

官方文檔: https://dev.mysql.com/doc/refman/5.7/en/mysql-innodb-cluster-userguide.html
節點有哪狀態

* ONLINE  - 節點狀態正常。
* OFFLINE  -   實例在運行,但沒有加入任何Cluster。
* RECOVERING - 實例已加入Cluster,正在同步數據。
* ERROR  -  同步數據發生異常。
* UNREACHABLE -  與其他節點通訊中斷,可能是網絡問題,可能是節點crash。
* MISSING 節點已加入集群,但未啟動group replication

集群有哪些狀態

* OK – 所有節點處於online狀態,有冗余節點。
* OK_PARTIAL – 有節點不可用,但仍有冗余節點。
* OK_NO_TOLERANCE – 有足夠的online節點,但沒有冗余,例如:兩個節點的Cluster,其中一個掛了,集群就不可用了。
* NO_QUORUM – 有節點處於online狀態,但達不到法定節點數,此狀態下Cluster無法寫入,只能讀取。
* UNKNOWN – 不是online或recovering狀態,嘗試連接其他實例查看狀態。
* UNAVAILABLE – 組內節點全是offline狀態,但實例在運行,可能實例剛重啟還沒加入Cluster。

MYSQL 的集群