1、介紹
MySQL InnoDB Cluster(MIC)是基于 MySQL Group Replication(MGR)的高可用性解決方案,結合 MySQL Shell 和 MySQL Router,提供自動故障轉移和讀寫分離功能,非常適合生產環境
2、部署
2.1 環境準備
三臺 Ubuntu 20.04 服務器(IP 分別為 192.168.100.61、192.168.100.62 和 192.168.100.63)
修改主機名稱,添加域名解析
每臺服務器都要執行
hostnamectl set-hostname mysql1
cat >>/etc/hosts<<EOF
192.168.100.61 mysql1
192.168.100.62 mysql2
192.168.100.63 mysql3
EOF
2.2 mysql部署(所有節點都要執行)
MIC 依賴 MySQL 8.0 的特性,因此需要安裝 MySQL Server 8.0
2.2.1 安裝相關工具
apt update
#部署mysql
apt install mysql-server -y#MySQL Shell 是 MIC 的管理工具,提供集群創建和維護的功能
apt install mysql-shell -y#
apt install mysql-router -y
2.2.2 修改root用戶密碼
ALTER USER 'root'@'localhost' IDENTIFIED WITH 'mysql_native_password' BY 'Admin@2025!';
CREATE USER 'root'@'%' IDENTIFIED WITH 'mysql_native_password' BY 'Admin@2025!';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
2.2.3 修改配置文件
/etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
#每臺服務器的唯一標識符,必須不同(例如 1、2、3)
server_id = 1
#允許遠程連接
bind-address = 0.0.0.0
#gtid_mode = ON 和 enforce_gtid_consistency = ON:啟用全局事務 ID(GTID),確保事務一致性
gtid_mode = ON
enforce_gtid_consistency = ON
#設置為行格式,支持 Group Replication
binlog_format = ROW
#啟用二進制日志,記錄數據庫變更
log_bin = mysql-bin
#從節點記錄主節點的更新
log_slave_updates = ON
#master_info_repository = TABLE 和 relay_log_info_repository = TABLE:將主從信息存儲在表中,提高可靠性
master_info_repository = TABLE
relay_log_info_repository = TABLE#加載 Group Replication 插件
plugin_load_add = group_replication.so
#定義集群組名,需一致
group_replication_group_name = "my_group"
#避免服務啟動時自動加入集群
group_replication_start_on_boot = off
#本節點的 MGR 通信地址
group_replication_local_address = "192.168.100.61:33061"
#集群所有節點的通信地址列表
group_replication_group_seeds = "192.168.100.61:33061,192.168.100.62:33061,192.168.100.63:33061"
#僅在首次創建集群時啟用
group_replication_bootstrap_group = off
systemctl restart mysql
其他節點僅修改 server_id,group_replication_local_address即可
2.2.4 配置集群
mysqlsh --uri root@192.168.100.61:3306#檢查和配置每個實例以支持 Group Replication,可能需要輸入root賬號 密碼
dba.configureInstance('root@192.168.100.61:3306')
dba.configureInstance('root@192.168.100.62:3306')
dba.configureInstance('root@192.168.100.63:3306')#創建并擴展集群
var cluster = dba.createCluster('my_cluster')
cluster.addInstance('root@192.168.100.62:3306')
cluster.addInstance('root@192.168.100.63:3306')#驗證集群狀態
cluster.status()
2.2.4 測試集群數據同步功能
在mysql1上寫一些測試數據,然后觀察mysql2 mysql3是有有同步數據
CREATE DATABASE test_db;
USE test_db;
CREATE TABLE test_table (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50));
INSERT INTO test_table (name) VALUES ('test1');
2.2.5 router配置
功能
- 讀寫分離:客戶端連接6446端口訪問主節點(讀寫),連接6447端口訪問從節點(只讀)。
- 高可用性:若主節點故障,Router自動將請求路由到新的主節點(依賴集群的故障轉移機制)。
- 負載均衡:在只讀模式下,Router可將請求分發到多個從節點
這里部署在mysql2主機上,用于測試功能,大家有時間可以改成Keepalived 和 HAProxy 組合實現router的高可用
# 初始化和配置MySQL Router,使其能夠與MySQL InnoDB Cluster(或其他高可用架構)集成
mysqlrouter --bootstrap root@192.168.100.61:3306 --directory /etc/mysqlrouter --user=rootcat >>/etc/systemd/system/mysqlrouter.service<<EOF
[Unit]
Description=MySQL Router Service
Documentation=https://dev.mysql.com/doc/mysql-router/8.0/en/
After=network.target mysql.service[Service]
Type=simple
ExecStart=/usr/bin/mysqlrouter --config /etc/mysqlrouter/mysqlrouter.conf
ExecReload=/bin/kill -HUP
Restart=on-failure
RestartSec=5s
PIDFile=/var/run/mysqlrouter/mysqlrouter.pid
PrivateTmp=true
LimitNOFILE=65535
StandardOutput=journal
StandardError=journal[Install]
WantedBy=multi-user.target
EOFsystemctl daemon-reload && systemctl enable mysqlrouter && systemctl start mysqlrouter
mysql -h 192.168.100.62 -P 6446 -u root -p
2.2.5 驗證高可用
1、停止mysql1的服務
systemctl stop mysql
2、查看變化
mysqlsh --uri root@192.168.100.62:3306
var cluster = dba.getCluster(‘my_cluster’);
cluster.status()
{"clusterName": "my_cluster", "defaultReplicaSet": {"name": "default", "primary": "mysql3:3306", "ssl": "REQUIRED", "status": "OK_NO_TOLERANCE_PARTIAL", "statusText": "Cluster is NOT tolerant to any failures. 1 member is not active.", "topology": {"mysql1:3306": {"address": "mysql1:3306", "memberRole": "SECONDARY", "mode": "n/a", "readReplicas": {}, "role": "HA", "shellConnectError": "MySQL Error 2003: Could not open connection to 'mysql1:3306': Can't connect to MySQL server on 'mysql1:3306' (111)", "status": "(MISSING)"}, "mysql2:3306": {"address": "mysql2:3306", "memberRole": "SECONDARY", "mode": "R/O", "readReplicas": {}, "replicationLag": "applier_queue_applied", "role": "HA", "status": "ONLINE", "version": "8.0.41"}, "mysql3:3306": {"address": "mysql3:3306", "memberRole": "PRIMARY", "mode": "R/W", "readReplicas": {}, "replicationLag": "applier_queue_applied", "role": "HA", "status": "ONLINE", "version": "8.0.41"}}, "topologyMode": "Single-Primary"}, "groupInformationSourceMember": "mysql3:3306"
}
可以看到mysql1 的狀態變成MISSING ,mysql3 變成主節點了
3、測試是否可以寫入數據
mysql -h 192.168.100.62 -P 6446 -u root -p’Admin@2025!’
mysql> create database test_ha;
mysql> show databases;
結果可以成功寫入
現在恢復mysql1
systemctl start mysql
重復步驟2再次查看集群狀態,發現mysql1的狀態變成ONLINE, "replicationLag"表示復制延遲狀態,applier_queue_applied 表示數據已同步完成。如果有延遲,可能會顯示具體的時間差
查看mysql1丟失的數據是否存在
root@mysql1:~# mysql -u root -p'Admin@2025!'mysql> show databases;
發現已經成功同步了之前丟失的數據