集群规划
三台服务器 的相同路径下(如 /data/mysql-cluster)建立如下结构:
bash
mkdir -p /data/mysql-cluster/{conf,scripts}
cd /data/mysql-cluster
结构如下:
/data/mysql-cluster/
├── docker-compose.yml
├── conf/
│ └── my.cnf
├── mysql_data/ # 启动后自动生成,无需手动创建
└── scripts/ # 存放脚本(仅服务器 A 需要存放具体脚本文件)
├── reboot_cluster.js
└── check_health.js
节点概述
| 节点IP | 主机名 | 运行服务 |
|---|---|---|
| 172.16.0.101 | mgr-node1 | Mysql、Router |
| 172.16.0.102 | mgr-node2 | Mysql、Router |
| 172.16.0.103 | mgr-node3 | Mysql、Router |
Mysql配置文件
mgr-node1
ini
cd /data/mysql-cluster
cat > conf/my.cnf << EOF
[client]
port = 3306
socket = /var/log/mysql/mysqld.sock
[mysqld]
# ==============================================================================
# 1. 基础与网络配置 (Basic & Network)
# ==============================================================================
user = mysql
port = 3306
skip-name-resolve
datadir = /var/lib/mysql
socket = /var/log/mysql/mysqld.sock
pid-file = /var/log/mysql/mysqld.pid
log_error = /var/log/mysql/error.log
slow_query_log_file = /var/log/mysql/slow.log
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
authentication_policy = mysql_native_password
autocommit = 1
max_connections = 1024
max_user_connections = 1024
back_log = 512
# ==============================================================================
# 2. 内存与缓存调优 (Memory & Buffer Pool)
# ==============================================================================
innodb_buffer_pool_size = 4G
innodb_buffer_pool_instances = 4
innodb_buffer_pool_load_at_startup = 1
innodb_buffer_pool_dump_at_shutdown = 1
# ==============================================================================
# 3. 磁盘 I/O 与日志调优 (I/O & Logging)
# ==============================================================================
log_bin = bilog
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
binlog_checksum = CRC32
binlog_expire_logs_seconds = 604800
replica_parallel_type = LOGICAL_CLOCK
replica_parallel_workers = 8
replica_preserve_commit_order = ON
innodb_log_buffer_size = 16M
innodb_redo_log_capacity = 1G
innodb_page_cleaners = 4
# ==============================================================================
# 4. MGR & 复制核心配置 (MGR & Replication)
# ==============================================================================
server_id = 1
gtid_mode = ON
enforce_gtid_consistency = ON
log_replica_updates = ON
binlog_transaction_dependency_tracking = WRITESET
plugin_load_add='group_replication.so'
loose-group_replication_group_name = "8f6d7d5e-1b7d-4d3a-9c6e-2f4b8a7c91de"
loose-group_replication_local_address = "mgr-node1:33061"
loose-group_replication_group_seeds = "mgr-node1:33061,mgr-node2:33061,mgr-node3:33061"
loose-group_replication_single_primary_mode = OFF ##在单主模式中为ON,在多主模式中为OFF
loose-group_replication_start_on_boot = OFF #默认关闭, 防止重启后自动创建新的Group
loose-group_replication_bootstrap_group = OFF #默认关闭, 防止自动创建新的Group
EOF
mgr-node2
ini
cd /data/mysql-cluster
cat > conf/my.cnf << EOF
[client]
port = 3306
socket = /var/log/mysql/mysqld.sock
[mysqld]
# ==============================================================================
# 1. 基础与网络配置 (Basic & Network)
# ==============================================================================
user = mysql
port = 3306
skip-name-resolve
datadir = /var/lib/mysql
socket = /var/log/mysql/mysqld.sock
pid-file = /var/log/mysql/mysqld.pid
log_error = /var/log/mysql/error.log
slow_query_log_file = /var/log/mysql/slow.log
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
authentication_policy = mysql_native_password
autocommit = 1
max_connections = 1024
max_user_connections = 1024
back_log = 512
# ==============================================================================
# 2. 内存与缓存调优 (Memory & Buffer Pool)
# ==============================================================================
innodb_buffer_pool_size = 4G
innodb_buffer_pool_instances = 4
innodb_buffer_pool_load_at_startup = 1
innodb_buffer_pool_dump_at_shutdown = 1
# ==============================================================================
# 3. 磁盘 I/O 与日志调优 (I/O & Logging)
# ==============================================================================
log_bin = bilog
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
binlog_checksum = CRC32
binlog_expire_logs_seconds = 604800
replica_parallel_type = LOGICAL_CLOCK
replica_parallel_workers = 8
replica_preserve_commit_order = ON
innodb_log_buffer_size = 16M
innodb_redo_log_capacity = 1G
innodb_page_cleaners = 4
# ==============================================================================
# 4. MGR & 复制核心配置 (MGR & Replication)
# ==============================================================================
server_id = 2
gtid_mode = ON
enforce_gtid_consistency = ON
log_replica_updates = ON
binlog_transaction_dependency_tracking = WRITESET
plugin_load_add='group_replication.so'
loose-group_replication_group_name = "8f6d7d5e-1b7d-4d3a-9c6e-2f4b8a7c91de"
loose-group_replication_local_address = "mgr-node2:33061"
loose-group_replication_group_seeds = "mgr-node1:33061,mgr-node2:33061,mgr-node3:33061"
loose-group_replication_single_primary_mode = OFF ##在单主模式中为ON,在多主模式中为OFF
loose-group_replication_start_on_boot = OFF #默认关闭, 防止重启后自动创建新的Group
loose-group_replication_bootstrap_group = OFF #默认关闭, 防止自动创建新的Group
EOF
mgr-node3
ini
cd /data/mysql-cluster
cat > conf/my.cnf << EOF
[client]
port = 3306
socket = /var/log/mysql/mysqld.sock
[mysqld]
# ==============================================================================
# 1. 基础与网络配置 (Basic & Network)
# ==============================================================================
user = mysql
port = 3306
skip-name-resolve
datadir = /var/lib/mysql
socket = /var/log/mysql/mysqld.sock
pid-file = /var/log/mysql/mysqld.pid
log_error = /var/log/mysql/error.log
slow_query_log_file = /var/log/mysql/slow.log
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
authentication_policy = mysql_native_password
autocommit = 1
max_connections = 1024
max_user_connections = 1024
back_log = 512
# ==============================================================================
# 2. 内存与缓存调优 (Memory & Buffer Pool)
# ==============================================================================
innodb_buffer_pool_size = 4G
innodb_buffer_pool_instances = 4
innodb_buffer_pool_load_at_startup = 1
innodb_buffer_pool_dump_at_shutdown = 1
# ==============================================================================
# 3. 磁盘 I/O 与日志调优 (I/O & Logging)
# ==============================================================================
log_bin = bilog
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
binlog_checksum = CRC32
binlog_expire_logs_seconds = 604800
replica_parallel_type = LOGICAL_CLOCK
replica_parallel_workers = 8
replica_preserve_commit_order = ON
innodb_log_buffer_size = 16M
innodb_redo_log_capacity = 1G
innodb_page_cleaners = 4
# ==============================================================================
# 4. MGR & 复制核心配置 (MGR & Replication)
# ==============================================================================
server_id = 3
gtid_mode = ON
enforce_gtid_consistency = ON
log_replica_updates = ON
binlog_transaction_dependency_tracking = WRITESET
plugin_load_add='group_replication.so'
loose-group_replication_group_name = "8f6d7d5e-1b7d-4d3a-9c6e-2f4b8a7c91de"
loose-group_replication_local_address = "mgr-node3:33061"
loose-group_replication_group_seeds = "mgr-node1:33061,mgr-node2:33061,mgr-node3:33061"
loose-group_replication_single_primary_mode = OFF ##在单主模式中为ON,在多主模式中为OFF
loose-group_replication_start_on_boot = OFF #默认关闭, 防止重启后自动创建新的Group
loose-group_replication_bootstrap_group = OFF #默认关闭, 防止自动创建新的Group
EOF
Docker编排文件
- 数据全部采用同级
./mysql_data相对路径挂载。 - 部分系统启动报错, 需要设置目录权限(MySQL 容器内部通常会使用
uid:gid = 999:999)。
mgr-node1
yaml
export node1=172.16.0.101
export node2=172.16.0.102
export node3=172.16.0.103
export root_pwd="mysq1&R00t_Passw0rd!"
cd /data/mysql-cluster
cat > docker-compose.yml << EOF
services:
mgr-node1:
image: mysql:8.0
container_name: mgr-node1
hostname: mgr-node1
restart: always
extra_hosts:
- "mgr-node1:${node1}"
- "mgr-node2:${node2}"
- "mgr-node3:${node3}"
environment:
MYSQL_ROOT_PASSWORD: "${root_pwd}"
MYSQL_ROOT_HOST: "%"
ports:
- "3306:3306"
- "33061:33061"
volumes:
- ./conf/my.cnf:/etc/mysql/my.cnf
- ./mysql_data/data:/var/lib/mysql
- ./mysql_data/logs:/var/log/mysql
- ./scripts:/scripts
mysql-router1:
image: mysql/mysql-router:8.0
container_name: mysql-router1
restart: always
extra_hosts:
- "mgr-node1:${node1}"
- "mgr-node2:${node2}"
- "mgr-node3:${node3}"
ports:
- "6446:6446"
- "6447:6447"
environment:
MYSQL_HOST: "mgr-node1" # 数据库的 IP 或容器名
MYSQL_PORT: "3306"
MYSQL_USER: "root"
MYSQL_PASSWORD: "${root_pwd}"
MYSQL_INNODB_CLUSTER_MEMBERS: "3"
MYSQL_NEVER_FAIL_ROUTER_BOOTSTRAP: "true"
MYSQL_ROUTER_BOOTSTRAP_HOST: "mgr-node1"
MYSQL_ROUTER_BOOTSTRAP_USER: "root"
MYSQL_ROUTER_BOOTSTRAP_PASSWORD: "${root_pwd}"
MYSQL_CREATE_ROUTER_USER: "root"
EOF
mgr-node2
yaml
export node1=172.16.0.101
export node2=172.16.0.102
export node3=172.16.0.103
export root_pwd="mysq1&R00t_Passw0rd!"
cd /data/mysql-cluster
cat > docker-compose.yml << EOF
services:
mgr-node2:
image: mysql:8.0
container_name: mgr-node2
hostname: mgr-node2
restart: always
extra_hosts:
- "mgr-node1:${node1}"
- "mgr-node2:${node2}"
- "mgr-node3:${node3}"
environment:
MYSQL_ROOT_PASSWORD: "${root_pwd}"
MYSQL_ROOT_HOST: "%"
ports:
- "3306:3306"
- "33061:33061"
volumes:
- ./conf/my.cnf:/etc/mysql/my.cnf
- ./mysql_data/data:/var/lib/mysql
- ./mysql_data/logs:/var/log/mysql
mysql-router2:
image: mysql/mysql-router:8.0
container_name: mysql-router2
restart: always
extra_hosts:
- "mgr-node1:${node1}"
- "mgr-node2:${node2}"
- "mgr-node3:${node3}"
ports:
- "6446:6446"
- "6447:6447"
environment:
MYSQL_HOST: "mgr-node1" # 数据库的 IP 或容器名
MYSQL_PORT: "3306"
MYSQL_USER: "root"
MYSQL_PASSWORD: "${root_pwd}"
MYSQL_INNODB_CLUSTER_MEMBERS: "3"
MYSQL_NEVER_FAIL_ROUTER_BOOTSTRAP: "true"
MYSQL_ROUTER_BOOTSTRAP_HOST: "mgr-node1"
MYSQL_ROUTER_BOOTSTRAP_USER: "root"
MYSQL_ROUTER_BOOTSTRAP_PASSWORD: "${root_pwd}"
MYSQL_CREATE_ROUTER_USER: "root"
EOF
mgr-node3
yaml
export node1=172.16.0.101
export node2=172.16.0.102
export node3=172.16.0.103
export root_pwd="mysq1&R00t_Passw0rd!"
cd /data/mysql-cluster
cat > docker-compose.yml << EOF
services:
mgr-node3:
image: mysql:8.0
container_name: mgr-node3
hostname: mgr-node3
restart: always
extra_hosts:
- "mgr-node1:${node1}"
- "mgr-node2:${node2}"
- "mgr-node3:${node3}"
environment:
MYSQL_ROOT_PASSWORD: "${root_pwd}"
MYSQL_ROOT_HOST: "%"
ports:
- "3306:3306"
- "33061:33061"
volumes:
- ./conf/my.cnf:/etc/mysql/my.cnf
- ./mysql_data/data:/var/lib/mysql
- ./mysql_data/logs:/var/log/mysql
mysql-router3:
image: mysql/mysql-router:8.0
container_name: mysql-router3
hostname: "${mgr-node1}-route"
restart: always
extra_hosts:
- "mgr-node1:${node1}"
- "mgr-node2:${node2}"
- "mgr-node3:${node3}"
ports:
- "6446:6446"
- "6447:6447"
environment:
MYSQL_HOST: "mgr-node1" # 数据库的 IP 或容器名
MYSQL_PORT: "3306"
MYSQL_USER: "root"
MYSQL_PASSWORD: "${root_pwd}"
MYSQL_INNODB_CLUSTER_MEMBERS: "3"
MYSQL_NEVER_FAIL_ROUTER_BOOTSTRAP: "true"
MYSQL_ROUTER_BOOTSTRAP_HOST: "mgr-node1"
MYSQL_ROUTER_BOOTSTRAP_USER: "root"
MYSQL_ROUTER_BOOTSTRAP_PASSWORD: "${root_pwd}"
MYSQL_CREATE_ROUTER_USER: "root"
EOF
管理集群
创建集群
- mgr-node1执行
javascript
// 登录
docker-compose exec mgr-node1 /bin/bash
mysqlsh root@mgr-node1 --js
// 状态检测
dba.checkInstanceConfiguration('root@mgr-node1:3306')
dba.checkInstanceConfiguration('root@mgr-node2:3306')
dba.checkInstanceConfiguration('root@mgr-node3:3306')
// 初始化实例
dba.configureInstance('root@mgr-node1:3306')
dba.configureInstance('root@mgr-node2:3306')
dba.configureInstance('root@mgr-node3:3306')
// 进入主节点创建集群, 创建一个 cluster,命名为 'mysql-cluster'
var cluster = dba.createCluster('mysql-cluster');
// 创建成功后,查看cluster状态
cluster.status();
// 实例加入集群
cluster.addInstance('root@mgr-node2:3306');
cluster.addInstance('root@mgr-node3:3306');
// 查看cluster状态
cluster.status();
常用排错命令
bash# 查看id是否重名 show variables like 'server_id'; # 查看group_replication插件是否开启 show plugins; # 查看group_replication配置细节 show variables like 'group_replication%';
运维集群
javascript
docker-compose exec mgr-node1 /bin/bash
mysqlsh root@mgr-node1 --js
// 重启集群
dba.rebootClusterFromCompleteOutage('mysql-cluster');
// 连接集群
var cluster = dba.getCluster('mysql-cluster');
//查看集群状态
cluster.status();
自动化脚本
- 在经常操作的节点的
/opt/mysql-cluster/scripts/编写l两个 JavaScript 脚本和一个shell脚本。 - 之前脚本之前在容器内连过集群, 保存过session
重启集群-js
JavaScript
cd /data/mysql-cluster
cat > scripts/reboot_cluster.js << EOF
try {
// 1. 重启处于完全停机状态的集群
// 注意:这里会尝试通过当前连接的节点重新引导集群
print("正在尝试重启集群 'mysql-cluster'...");
dba.rebootClusterFromCompleteOutage('mysql-cluster');
print("重启指令执行完毕。\n");
// 2. 获取集群对象
// 重启后需要重新获取该对象,否则后续 status() 可能会报错
var cluster = dba.getCluster('mysql-cluster');
// 3. 打印集群状态
if (cluster) {
print("--- [当前集群状态] ---");
// 必须使用 print() 才能在非交互模式下看到输出
print(cluster.status());
} else {
print("错误:重启后无法获取集群对象。");
}
} catch (e) {
// 捕捉错误并打印,防止脚本静默退出
print("执行过程中发生错误: " + e.message);
}
EOF
集群状态-sj
JavaScript
cd /data/mysql-cluster
cat > scripts/check_health.js << EOF
// 1. 获取集群对象
var cluster = dba.getCluster('mysql-cluster');
// 2. 检查集群是否存在
if (cluster) {
print("\n--- [集群当前状态] ---\n");
print(cluster.status());
print("\n----------------------\n");
} else {
print("错误:找不到指定的集群!");
}
EOF
执行脚本-shell
bash
cd /data/mysql-cluster
cat > cluster.sh << 'EOF'
#!/bin/bash
# 获取当前脚本所在目录
BASE_DIR=$(cd "$(dirname "$1")"; pwd)
SHELL_CONTAINER="mgr-node1"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
function check_container() {
if ! docker ps | grep -q "$SHELL_CONTAINER"; then
echo -e "${RED}错误: 容器 $SHELL_CONTAINER 未启动,请先执行 docker compose up -d${NC}"
exit 1
fi
}
function do_start() {
echo -e "${YELLOW}正在尝试恢复/启动已有的集群...${NC}"
docker exec -it "$SHELL_CONTAINER" mysqlsh --file /scripts/reboot_cluster.js
}
function do_status() {
echo -e "${GREEN}--- 当前集群状态巡检 ---${NC}"
# 这里直接调用 check_health.js 脚本
docker exec -it "$SHELL_CONTAINER" mysqlsh --file /scripts/check_health.js
}
# 参数逻辑判断
ACTION=${1:-status} # 如果没有参数,默认为 status
case "$ACTION" in
init)
check_container
do_init
;;
start)
check_container
do_start
;;
status)
check_container
do_status
;;
*)
echo -e "${RED}用法: $0 {init|start|status}${NC}"
echo -e " start : 重启恢复集群使用"
echo -e " status : (默认) 查看当前集群健康状态"
exit 1
;;
esac
EOF
使用脚本
bash
# 启动集群
cd /data/mysql-cluster
./cluster.sh start
# 查看集群状态
cd /data/mysql-cluster
./cluster.sh
# 或者
./cluster.sh status
mysqlsh常用命令
#会列出dba相关指令 dba.help(); #列出详细指令的用法 dba.help('deploySandboxInstance'); #检查节点配置实例,用于加入cluster之前 dba.checkInstanceConfiguration("root@hostname:3306"); #节点初始化 dba.configureInstance('root@hostname:3306'); #重启集群 dba.rebootClusterFromCompleteOutage('myCluster'); #会列出集群相关指令 cluster.help(); #创建集群 var cluster = dba.createCluster('myCluster'); #获取当前集群实例 var cluster = dba.getCluster('myCluster'); 查看集群状态 cluster.status(); #检查cluster节点状态 cluster.checkInstanceState("root@hostname:3306") ; #增加节点 cluster.addInstance("root@hostname:3306") ; #删除节点 cluster.removeInstance("root@hostname:3306") ; #强制删除节点 cluster.removeInstance('root@hostname:3306',{force:true}); # 状态为missing的节点可以重新加入集群 cluster.rejoinInstance("root@hostname:3306") #解散集群 cluster.dissolve({force:true}) ; #集群描述 cluster.describe();