🌐 使用 Docker 部署 MySQL InnoDB Cluster 高可用方案(带 Router 和持久数据)
-
🧱 使用 Docker 在四台服务器上部署 MySQL InnoDB Cluster + Router 高可用集群
🖥️ 节点规划
基础配置,安装docker,配置hosts解析就不进行演示了,但是这个很重要必须进行配置
服务器 角色 主机名 IP地址 容器名称 MySQL 端口 Router 端口 A MySQL 节点A master 192.168.0.101 mysql1 3306 33061 无 B MySQL 节点B node1 192.168.0.102 mysql2 3306 33061 无 C MySQL 节点C node2 192.168.0.103 mysql3 3306 33061 无 D Router router 192.168.0.104 mysqlrouter 无 6446 (读写) / 6447 (读) 🔧 每台 MySQL 节点配置(A/B/C)
- 创建目录结构(以 A 节点为例)
mkdir -p /usr/local/mysql/data vim /usr/local/mysql/my.cnf- 配置
my.cnf
[mysqld] # ========== 插件配置 ========== # 组复制插件加载(官方镜像已内置 recovery 功能,无需单独加载) plugin_load_add=group_replication.so # ========== 组复制核心配置 ========== # 松散参数前缀确保兼容性(服务启动时不验证参数有效性) loose-group_replication_group_name="7801cdc9-fc1c-4c1d-bf0b-88d2a35c7d8c" # 集群唯一标识UUID loose-group_replication_group_seeds="192.168.0.101:33060,192.168.0.102:33060,192.168.0.103:33060" # 集群成员地址 loose-group_replication_local_address="192.168.0.101:33060" # 当前节点通信地址 loose-group_replication_start_on_boot=OFF # 禁止自动启动组复制 loose-group_replication_bootstrap_group=1 # 仅首节点启动时需要设为1 # ========== 复制基础配置 ========== # GTID 全局事务标识(现代复制架构基础) gtid_mode=ON enforce_gtid_consistency=ON # 写集提取算法(组复制必需配置) transaction_write_set_extraction=XXHASH64 # 默认使用XXHASH64算法 # 让错误日志输出到 Docker 可捕获的 stderr log-error=/var/lib/data/stderr # ========== 实例基础配置 ========== server_id=1 # 必须保证集群内唯一 report_host=192.168.0.101 # 供集群其他节点识别 binlog_format=ROW # 组复制强制要求ROW格式 # ========== 系统参数 ========== port=3006 lower_case_table_names=1 # 表名大小写不敏感 datadir=/var/lib/data innodb_file_per_table=1 # 启用独立表空间 # SQL严格模式(推荐生产环境配置) sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_ENGINE_SUBSTITUTION' # 存储引擎兼容模式(仅旧系统需要) innodb_strict_mode=0 # 禁用InnoDB严格检查 # ========== 网络与性能 ========== max_allowed_packet=1024M # 最大网络传输包大小 max_connections=1000 # 最大客户端连接数 max_connect_errors=10 # 连接错误阈值 # ========== 二进制日志配置 ========== log-bin=mysql-bin # 启用二进制日志 binlog_expire_logs_seconds=864000 # 日志保留周期(10天) # ========== 字符集与存储引擎 ========== character-set-server=utf8mb4 # 默认字符集 collation-server=utf8mb4_0900_ai_ci # 默认排序规则 default-storage-engine=INNODB # 默认存储引擎⚠️ B/C 节点只需改
server_id、report_host、group_replication_local_address,并删除或注释group_replication_bootstrap_group=1- 启动容器(使用 docker-compose)
services: mysql1: image: mysql:8.0.42-debian container_name: mysql1 # B/C 节点依次递增 #cap_add: # - SYS_ADMIN security_opt: - seccomp:unconfined environment: - TZ=Asia/Shanghai - MYSQL_ROOT_PASSWORD=123456 # 设置 root 密码 volumes: - /usr/local/mysql/my.cnf:/etc/mysql/my.cnf # 自定义配置文件挂载 - /usr/local/mysql/data:/var/lib/data # 数据目录挂载 - /etc/localtime:/etc/localtime:ro # 保证容器时间一致 - /usr/share/zoneinfo:/usr/share/zoneinfo:ro # 保证时区一致 - /etc/hosts:/etc/hosts:ro #ports: # - "3306:3306" # 数据库端口 # - "33060:33060" # 组复制通信端口 # privileged: true # 特权模式,获取更多的服务器资源 restart: always network_mode: host🟢 建议:统一目录结构、配置命名与挂载路径,便于维护和批量部署。
🔄 配置 InnoDB Cluster
在任意一台节点(建议 A)中安装MySQL shell:
sudo apt update sudo apt install mysql-shell执行mysqlsh命令登录数据库进行操作
sudo mysqlsh root@192.168.0.101:3006进入 Shell 后执行:
// 初始化当前实例,注册到 MySQL Shell dba.configureInstance('root@192.168.0.101:3306') // 创建集群(首次执行) cluster = dba.createCluster('myCluster') // 初始化其他节点 dba.configureInstance('root@192.168.0.102:3306') dba.configureInstance('root@192.168.0.103:3306') // 加入到集群当中 cluster.addInstance('root@192.168.0.102:3306') cluster.addInstance('root@192.168.0.103:3306')⚠️ 添加节点时目标实例必须可连通,并且配置无误。
初始化节点报错,可能是权限没授权,输入下方SQL语句授权并且刷新权限:
GRANT CLONE_ADMIN, CONNECTION_ADMIN, CREATE USER, EXECUTE, FILE, GROUP_REPLICATION_ADMIN, PERSIST_RO_VARIABLES_ADMIN, PROCESS, RELOAD, REPLICATION CLIENT, REPLICATION SLAVE, REPLICATION_APPLIER, REPLICATION_SLAVE_ADMIN, ROLE_ADMIN, SELECT, SHUTDOWN, SYSTEM_VARIABLES_ADMIN ON *.* TO 'root'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES;🚦 部署MySQL Router(D 节点)
创建对应文件目录:
mkdir -p /usr/local/mysqlrouter配置docker-compose文件:
services: mysql-router: image: mysql/mysql-router:8.0 container_name: mysql-router user: root # 防止文件夹权限报错 environment: MYSQL_HOST: "192.168.0.101" MYSQL_PORT: "3306" MYSQL_USER: "root" MYSQL_PASSWORD: "123456" MYSQL_INNODB_CLUSTER_MEMBERS: "3" volumes: - ./router-config:/tmp/mysqlrouter # 挂载配置文件目录 - ./router-data:/var/lib/mysqlrouter # 挂载数据目录 - ./router-logs:/var/log/mysqlrouter # 挂载日志目录 - /etc/hosts:/etc/hosts:ro restart: always network_mode: hostRouter 会自动连接集群,创建两个端口:6446 写入路由、6447 只读负载均衡。
✅ 常见注意事项
- 🔴
group_replication_bootstrap_group=1仅用于集群首次启动第一个节点 - 🟢
33061端口仅用于节点间通信,应限制外部访问 - 🟢 每个节点
server_id和group_replication_local_address必须唯一 - 🟡 推荐由第一个节点提供初始数据,其它节点自动 clone
- 🟢 参数建议统一写入
my.cnf,减少人为失误 - 🟡 遇故障可使用
RESET PERSIST清除持久化参数后重新配置
✅ Navicat链接测试
![image-20250428141910790]()
Navicat连接集群需要在SSL配置那勾选✔使用SSL
🔌 Java 应用连接示例
// 写连接(自动指向主库) String url = "jdbc:mysql://192.168.0.104:6446/yourdb?serverTimezone=UTC"; Connection conn = DriverManager.getConnection(url, "root", "rootpwd"); // 读连接(负载均衡从库) String readUrl = "jdbc:mysql://192.168.0.104:6447/yourdb?serverTimezone=UTC";
✅ 常见注意事项
- ✅
group_replication_bootstrap_group=1仅限用于首次启动第一个节点,后续节点必须禁用,否则集群异常 - ✅ 建议关闭
33060的外部访问,仅供节点间通信 - ✅ 各节点必须使用唯一的
server_id和group_replication_local_address - ✅ 初始数据建议由第一个节点提供,后续节点加入时会自动 clone 数据
- ✅ 配置推荐全部写入
my.cnf,使用docker-compose启动,避免冗余命令 - ✅ 若多次重启失败,可通过
RESET PERSIST清理持久化配置后再尝试重新配置

浙公网安备 33010602011771号