MySQL InnDB 集羣搭建

1.集羣組件

mysql官方提供的集羣方案有InnoDB Cluster 和 NDB Cluster 兩種

1.1 InnoDB Cluster

InnoDB Cluster 基於 Group Replication 協議

總體架構:

InnoDB Cluster 通常以單主模式運行,但實際上也能實現多主

1.2 NDB Cluster

現在我們要搭建的是單主結構的InnoDB Clutser,所需組件有:

  • MySQL Shell
  • MySQL Server(8.0),需要安裝好 Group Replication 插件
  • MySQL Router,輕量級路由

2. 安裝前提

2.1 用例及防火牆說明

hostname 用途 端口 防火牆規則
mysql-s1 primary 節點 客戶端訪問端口3306,集羣端口33061 能夠訪問mysql-s2,mysql-s3的3306,33061端口
mysql-s2 secondary節點 客戶端訪問端口3306,集羣端口33061 能夠訪問mysql-s1,mysql-s3的3306,33061端口
mysql-s3 secondary節點 客戶端訪問端口3306,集羣端口33061 能夠訪問mysql-s1,mysql-s2的3306,33061端口
app 應用服務器 能夠訪問mysql-s1,mysql-s2,mysql-s3的3306端口

2.2 整體步驟說明

  1. 現在各節點上安裝好mysql shellmysql server 8.0
  2. 爲所有節點安裝並配置group application
  3. 使用mysql shellgroup application轉換爲InnoDB Cluster
  4. 在應用服務器上安裝配置mysql router

3. 安裝MySQL Shell

3.1 在線安裝

如果服務器沒有MySQL的倉庫,需要先安裝倉庫。

Ubuntu/Debian:從 https://dev.mysql.com/downloads/repo/apt/ 找到對應deb包的下載鏈接,使用wget下載後,sudo dpkg -i 包名 安裝

CentOS/RedHat:如果系統中使用了過老的倉庫,應當先進行卸載,命令:sudo yum remove mysql-community-release。然後從 https://dev.mysql.com/downloads/repo/yum/ 找到對應rpm包的下載鏈接,使用wget下載後,sudo rpm -i 包名sudo yum localinstall 包名安裝

接下來直接進行安裝

Ubuntu/Debian

sudo apt-get update
sudo apt-get install mysql-apt-config
sudo apt-get install mysql-shell

CentOS/RedHat

sudo yum install mysql-shell

3.2 離線安裝

直接從 https://dev.mysql.com/downloads/shell/ 找到對應發行版的安裝包並下載,上傳到服務器後,使用dpkg/ rpm/ yum安裝

4. 安裝MySQL Server 並配置 Group Replication

4.1 yum在線安裝

沒有如果服務器沒有MySQL yum倉庫,需參考上一節中的方案進行安裝。確保倉庫可用後,執行以下步驟:

# 禁用5.7倉庫,啓用8.0倉庫
sudo yum-config-manager --disable mysql57-community
sudo yum-config-manager --enable mysql80-community

也可以直接修改/etc/yum.repos.d/mysql-community.repo文件中的enabled

sudo yum install mysql-community-server
sudo systemctl enable mysqld

4.2 apt在線安裝

同樣地,需要按照前面的步驟確保倉庫可用。然後執行:

sudo apt-get update && sudo apt-get install mysql-server
sudo systemctl enable mysqld

4.3 離線安裝

https://dev.mysql.com/downloads/mysql/ 下載對應發行版的安裝包並下載,上傳到服務器解壓後,使用dpkg/ rpm/ yum安裝

包名:

Ubuntu/Debian: mysql-server_MySQL版本號-操作系統版本號_CPU架構.deb-bundle.tar

CentOS/RedHat: mysql-MySQL版本號-el版本號.CPU架構.rpm-bundle.tar

bundle壓縮包包含了安裝所需的所有組件,解壓後全部安裝即可

安裝完成之後配置自啓動

sudo systemctl enable mysqld

4.4 Caching SHA-2 Pluggable Authentication與密鑰處理的說明

在開始配置前,需要先確定對Caching SHA-2 Pluggable Authentication密鑰的處理方式

默認情況下,mysql 8中會開啓Caching SHA-2 Pluggable Authentication,包括用於集羣同步的用戶(本文將使用rpl_user)。此處有兩種解決方案

  1. /etc/my.cnf中添加配置

    group_replication_recovery_get_public_key=ON
    

    在有節點加入時,第一個節點會提供公鑰。但這樣無法識別加入的節點是否合法。所以一定要在節點全部加入後,設爲OFF。後者直接採用第二種方式

  2. 手動將第一個節點的公鑰並複製到各個節點(默認的公鑰路徑爲/var/lib/mysql/public_key.pem),並在其餘節點的/etc/my.cnf中配置group_replication_recovery_public_key_path 指定公鑰位置。

    密鑰也可以自行創建。使用mysql提供的mysql_ssl_rsa_setup命令,或者其它方式均可

4.5 配置 Group Replication

首先配置第一個節點。按照以下內容修改結合實際情況修改/etc/my.cnf文件

初始配置文件:

[mysqld]
port=3306
# 數據存儲路徑
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# 日誌路徑
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

# mysql集羣配置
# Group Replication只支持InnoDB引擎,需要禁用其它引擎
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
# 每個節點擁有唯一的server_id
server_id=1
# 開啓全局事務ID
gtid_mode=ON
enforce_gtid_consistency=ON

#binlog_checksum=NONE  #8.0.21之前的版本不支持binlog_checksum,需要設爲NONE
################## 8.0.3 以前的版本需要以下配置 #################
#log_bin=binlog
#log_slave_updates=ON
#binlog_format=ROW
#master_info_repository=TABLE
#relay_log_info_repository=TABLE
#transaction_write_set_extraction=XXHASH64
################## 8.0.3 以前的版本需要以上配置 #################

# 部分版本不允許在初始化數據庫的時候加載插件,需要註釋Group Replication相關的配置
# 待數據庫初始化完畢後,再取消註釋,重啓mysqld服務

按照以上內容修改配置後,先啓動第一個節點的mysqld服務

sudo systemctl start mysqld

然後取消註釋Group Replication相關的配置

# 加載Group Replication 插件
plugin_load_add='group_replication.so'
# Group名稱必須使用UUID。shell中使用uuidgen命令即可生成UUID
group_replication_group_name="438a57b2-a260-41a2-a72c-374bb66c7fdc"
# 配置Group的時候要先關閉開機自啓,配置完成之後可以打開
group_replication_start_on_boot=off
# 注意此處只用於Group內部連接,需要和客戶端連接端口區分開
group_replication_local_address= "mysql-s1:33061"
group_replication_group_seeds= "mysql-s1:33061,mysql-s2:33061,mysql-s3:33061"
# 可以使用獨立的hostname,並在/etc/hosts中配置
report_host=mysql-s1
# 第一次引導Group時,確保只有一個節點開啓此項,引導之後要全部保持爲off
group_replication_bootstrap_group=off

重啓第一個節點的mysqld服務

sudo systemctl restart mysqld

如果不想重啓,可以直接執行SQL

# 安裝插件
INSTALL PLUGIN plugin_name SONAME 'group_replication.so';
# 使用"set global 屬性=屬性值"設置上面配置文件中的所有屬性
set global group_replication_group_name="438a57b2-a260-41a2-a72c-374bb66c7fdc";
...

查詢root密碼

sudo grep 'temporary password' /var/log/mysqld.log

shell登陸數據庫

mysql -uroot -p

修改root密碼

# 關閉 binlog
mysql> SET SQL_LOG_BIN=0; #關閉
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '密碼';

創建集羣同步用戶

# 如果先要將以下過程通過binlog同步到其它節點上,則可以開啓binlog
# 也可以繼續保持關閉,然後在各個節點上分別創建集羣同步用戶
mysql> SET SQL_LOG_BIN=1;
mysql> CREATE USER rpl_user@'%' IDENTIFIED BY '密碼';	# 若要顯示指定使用SSL,可以添加 REQUIRE SSL
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
mysql> GRANT BACKUP_ADMIN ON *.* TO rpl_user@'%';
mysql> FLUSH PRIVILEGES;

接下來設置用戶憑據。這裏有兩種方式

  1. 永久設置:使用 CHANGE MASTER TOCHANGE REPLICATION 永久保存憑據

    mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='密碼' FOR CHANNEL 'group_replication_recovery';
    
    # 對於8.0.23及以上的版本,使用:
    mysql> CHANGE REPLICATION SOURCE TO SOURCE_USER='rpl_user', SOURCE_PASSWORD='密碼' FOR CHANNEL 'group_replication_recovery';
    
  2. 每次啓動時設置:每次啓動集羣時,使用 START GROUP_REPLICATION 設置憑據。這樣憑據只會保存在內存中,重啓後需要重新設置。

    mysql> START GROUP_REPLICATION USER='rpl_user', PASSWORD='密碼';
    

最後,如果還沒有開啓binlog,此時必須開啓

mysql> SET SQL_LOG_BIN=1;

4.6 引導集羣

根據使用的憑據類型不同,有兩種引導方式

  1. 使用永久憑據

    mysql> SET GLOBAL group_replication_bootstrap_group=ON;
    mysql> START GROUP_REPLICATION;
    mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
    
  2. 使用非永久憑據

    mysql> SET GLOBAL group_replication_bootstrap_group=ON;
    mysql> START GROUP_REPLICATION USER='rpl_user', PASSWORD='密碼';
    mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
    

引導完畢後,創建一個測試數據庫,用於稍後驗證集羣是否同步成功

CREATE DATABASE test;
CREATE TABLE `test`.t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);
INSERT INTO `test`.t1 VALUES (1, 'test');

4.7 添加節點

同樣地,由於部分版本不允許初始化時加載插件,所以/etc/my.cnf 中先添加與Group Replication 插件無關的配置即可

[mysqld]
port=3306
# 數據存儲路徑
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# 日誌路徑
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

# mysql集羣配置
# Group Replication只支持InnoDB引擎,需要禁用其它引擎
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
# 每個節點擁有唯一的server_id,注意修改
server_id=2
# 開啓全局事務ID
gtid_mode=ON
enforce_gtid_consistency=ON

#binlog_checksum=NONE  #8.0.21之前的版本不支持binlog_checksum,需要設爲NONE
################## 8.0.3 以前的版本需要以下配置 #################
#log_bin=binlog
#log_slave_updates=ON
#binlog_format=ROW
#master_info_repository=TABLE
#relay_log_info_repository=TABLE
#transaction_write_set_extraction=XXHASH64
################## 8.0.3 以前的版本需要以上配置 #################

配置修改好後,啓動mysqld服務

sudo systemctl start mysqld

關於第4節中提到的密鑰問題,本文采用複製公鑰的節點上的方式解決。將第一個節點上的/var/lib/mysql/public_key.pem 複製爲第二個節點上的 /var/lib/mysql/rpl_public_key.pem,然後配置路徑

group_replication_recovery_public_key_path=/var/lib/mysql/rpl_public_key.pem

取消其它Group Replication插件配置,完整內容如下:

# 加載Group Replication 插件
plugin_load_add='group_replication.so'
# Group名稱必須使用UUID。shell中使用uuidgen命令即可生成UUID
group_replication_group_name="438a57b2-a260-41a2-a72c-374bb66c7fdc"
# 配置Group的時候要先關閉開機自啓,配置完成之後可以打開
group_replication_start_on_boot=off
# 注意此處只用於Group內部連接,需要和客戶端連接端口區分開
group_replication_local_address= "mysql-s2:33061"
group_replication_group_seeds= "mysql-s1:33061,mysql-s2:33061,mysql-s3:33061"
# 可以使用獨立的hostname,並在/etc/hosts中配置
report_host=mysql-s2
# 第一次引導Group時,確保只有一個節點開啓此項,引導之後要全部保持爲off
group_replication_bootstrap_group=off
# 第一個節點上的公鑰,需提前複製到本機
group_replication_recovery_public_key_path=/var/lib/mysql/rpl_public_key.pem

重啓服務

sudo systemctl restart mysqld

同樣地,如果不想重啓,也可以參照前面的方法執行sql

查詢root密碼,然後登陸

sudo grep 'temporary password' /var/log/mysqld.log
mysql -uroot -p

!!!爲了避免全局事務ID(GTID)衝突,請務必先關閉binlog,再進行操作

# 關閉binlog
mysql> SET SQL_LOG_BIN=0;
# 重置密碼
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '密碼';

前面創建集羣同步用戶時,如果關閉了binlog,此處要手動創建一下,如果開啓了binlog,則跳過這一步

mysql> CREATE USER rpl_user@'%' IDENTIFIED BY '密碼';
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
mysql> GRANT BACKUP_ADMIN ON *.* TO rpl_user@'%';
mysql> FLUSH PRIVILEGES;

下面配置集羣用戶憑證並加入集羣

  1. 如果使用的是永久憑證,則按此步操作

    mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='密碼' FOR CHANNEL 'group_replication_recovery';
    
    # 對於8.0.23及以上的版本,使用:
    mysql> CHANGE REPLICATION SOURCE TO SOURCE_USER='rpl_user', SOURCE_PASSWORD='密碼' FOR CHANNEL 'group_replication_recovery';
    
    # 開啓binlog
    mysql> SET SQL_LOG_BIN=1;
    mysql> START GROUP_REPLICATION;
    
  2. 如果使用的是非永久憑證,則按此步操作:

    # 開啓binlog
    mysql> SET SQL_LOG_BIN=1;
    mysql> START GROUP_REPLICATION USER='rpl_user', PASSWORD='密碼';
    

查看集羣成員

SELECT * FROM performance_schema.replication_group_members;
CHANNEL_NAME MEMBER_ID MEMBER_HOST MEMBER_PORT MEMBER_STATE MEMBER_ROLE MEMBER_VERSION
group_replication_applier 1d8e198e-9788-11eb-834e-00163e14d350 mysql-s2 3306 ONLINE SECONDARY 8.0.23
group_replication_applier d3385830-9776-11eb-9575-00163e046c25 mysql-s1 3306 ONLINE PRIMARY 8.0.23

可以看到節點2已經成功加入。如果MEMBER_STATE不是ONLINE,則需要查看日誌,進行相應處理。

查詢我們前面在第一個節點上創建的table

select * from test.t1;
+----+------+
| c1 | c2   |
+----+------+
|  1 | test |
+----+------+
1 row in set (0.00 sec)

可以看到,數據已成功同步。

接下來,只需要以同樣的方式添加剩餘節點,即可完成整個集羣的引導過程。

在左右節點均加入完成後,記得修改各節點/etc/my.cnf中的開機啓動設置

group_replication_start_on_boot=on

同時設置mysql開機自啓動

systemctl enable mysqld

安裝過程中可能會報ip不在白名單中的錯誤,在/etc/my.cnf中添加配置group_replication_ip_allowlist即可

# ip白名單。支持CIDR格式x.x.x.x/x,ipv4,ipv6

group_replication_ip_allowlist="x.x.x.x/x,x.x.x.x"

如果實例已經啓動,不想重啓,則直接執行sql:

set global group_replication_ip_allowlist="x.x.x.x/x,x.x.x.x"

5. 配置root權限

  • 允許root用戶遠程登陸
  • 賦予root用戶admin api相關權限
mysql -uroot -p
mysql> update mysql.user set host='%' where user='root';
mysql> GRANT BACKUP_ADMIN, CLONE_ADMIN, PERSIST_RO_VARIABLES_ADMIN, REPLICATION_APPLIER, SYSTEM_VARIABLES_ADMIN ON *.* TO 'root'@'%' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;

如果考慮安全問題,可以insert多條數據來實現指定特定網段可以登陸,需要添加的有:數據庫各節點所在網段,應用服務器所在網段,localhost. 假如數據庫和應用服務器所在網段均爲172.20.1.%,可以insert一條host爲172.20.1.%,其它字段均不變的數據庫。注意添加完之後,相應第也要GRANT賦予root用戶admin api相關權限。

+-------+------------+
| user  | host       |....
+-------+------------+
| root  | 172.20.1.% |....
| root  | localhost  |....
....
+-------+------------+

6. 將Group Replication轉換爲InnoDB CLuster

利用mysql shell將Group Replication轉換爲InnoDB CLuster. 步驟如下: 在mysql-s1上執行

mysqlsh -uroot -p
# prodCluster爲集羣名稱
mysql-js> var cluster = dba.createCluster('prodCluster', {adoptFromGR: true});
# 提示創建成功後,可以查看集羣狀態
mysql-js> cluster.status();
# 如有提示有異常,請按照提示修復,沒有則退出
mysql-js> \exit

常見報錯:

The required parallel-appliers settings are not enabled on the instance. Use dba.configureInstance() to fix it

在每個數據庫節點上使用mysql shell執行 dba.configureInstance() 即可

mysqlsh -uroot -p
mysql-js> dba.configureInstance()
# 再次檢查實例配置
mysql-js> dba.checkInstanceConfiguration()

也可以在一個節點上執行,然後讓其它節點退出並重新加入集羣。

7. 安裝MySQL Router

MySQL Router可以直接安裝在應用所在服務器上

1.在線安裝

參照上面安裝mysql-shell/mysql-server的方式,先在應用服務器上安裝好mysql的倉庫。然後

Ubuntu/Debian

sudo apt-get update 
sudo apt-get install mysql-router

CentOS/Redhat

 sudo yum install mysql-router

2.離線安裝

https://dev.mysql.com/downloads/router/ 下載對應版本的安裝包,上傳到服務器後,使用dpkg/ rpm/ yum安裝

3.配置MySQL Router

確保應用服務器可以以root權限登陸後,開始初始化MySQL Router

mysqlrouter --bootstrap root@mysql-s1:3306 --directory /tmp/myrouter --conf-use-sockets --account routerfriend --account-create always

--directory: 配置生成路徑

--account: Router用戶

--account-create always: Router啓動時,如果用戶不存在,則創建

該命令執行後,會生成mysql router的配置文件,路徑爲directory參數指定的路徑,此處爲 /tmp/myrouter

After this MySQL Router has been started with the generated configuration

    $ mysqlrouter -c /tmp/myrouter/mysqlrouter.conf

the cluster 'caiCluster' can be reached by connecting to:

## MySQL Classic protocol

- Read/Write Connections: localhost:6446, /tmp/myrouter/mysql.sock
- Read/Only Connections:  localhost:6447, /tmp/myrouter/mysqlro.sock

## MySQL X protocol

- Read/Write Connections: localhost:64460, /tmp/myrouter/mysqlx.sock
- Read/Only Connections:  localhost:64470, /tmp/myrouter/mysqlxro.sock

directory目錄下會同時生成啓動腳本和停止腳本,直接使用即可

參考資料:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章