Docker 环境下 MySQL InnoDB Cluster 本地全自动高可用部署
·
环境准备:
docker和docker-compose已安装
第一步:编写docker-compose.yml
version: '3.8'
# 提取公共配置,保持代码优雅
x-mysql-common: &mysql-common
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: Root_Password123!
MYSQL_ROOT_HOST: '%'
services:
mysql1:
<<: *mysql-common
container_name: mysql1
hostname: mysql1
command: ["mysqld", "--server-id=1", "--gtid-mode=ON", "--enforce-gtid-consistency=ON", "--binlog-format=ROW", "--transaction-write-set-extraction=XXHASH64", "--binlog-transaction-dependency-tracking=WRITESET"]
networks:
- cluster_net
mysql2:
<<: *mysql-common
container_name: mysql2
hostname: mysql2
command: ["mysqld", "--server-id=2", "--gtid-mode=ON", "--enforce-gtid-consistency=ON", "--binlog-format=ROW", "--transaction-write-set-extraction=XXHASH64", "--binlog-transaction-dependency-tracking=WRITESET"]
networks:
- cluster_net
mysql3:
<<: *mysql-common
container_name: mysql3
hostname: mysql3
command: ["mysqld", "--server-id=3", "--gtid-mode=ON", "--enforce-gtid-consistency=ON", "--binlog-format=ROW", "--transaction-write-set-extraction=XXHASH64", "--binlog-transaction-dependency-tracking=WRITESET"]
networks:
- cluster_net
mysql-router:
image: mysql/mysql-router:8.0
container_name: mysql-router
hostname: mysql-router
restart: always
depends_on:
- mysql1
- mysql2
- mysql3
environment:
MYSQL_HOST: mysql1
MYSQL_PORT: 3306
MYSQL_USER: root
MYSQL_PASSWORD: Root_Password123!
MYSQL_INNODB_CLUSTER_MEMBERS: 3
ports:
- "6446:6446" # 读写分离:写端口 (永远指向 Primary 节点)
- "6447:6447" # 读写分离:读端口 (轮询指向 Secondary 节点)
networks:
- cluster_net
networks:
cluster_net:
driver: bridge
第二步:一键拉起 MySQL 基础节点
在 docker-compose.yml 所在的目录打开终端,先只启动 3 个 MySQL 节点(暂时不启动 Router,等集群建好再启):
docker-compose up -d mysql1 mysql2 mysql3
第三步:使用 MySQL Shell 一气呵成建集群
这里我们直接拉起一个一次性的 MySQL Shell 容器来执行操作。
1. 进入交互界面:
docker run -it --network mysql-cluster_cluster_net --rm mysql/mysql-server:8.0 mysqlsh root@mysql1:3306 -pRoot_Password123!
注意:请确保 --network 后面的网络名正确,通常是 当前目录名_cluster_net
2. 在 JS 终端中,依次执行以下命令:
// 1. 创建集群
var cluster = dba.createCluster('myCluster');
// 2. 加入 mysql2(强制指定 clone 模式)
cluster.addInstance('root@mysql2:3306', {password: 'Root_Password123!', recoveryMethod: 'clone'});
// 3. 加入 mysql3
cluster.addInstance('root@mysql3:3306', {password: 'Root_Password123!', recoveryMethod: 'clone'});
// 4. 查看集群完美状态
cluster.status();

看到三个节点全绿 ONLINE,输入 \q 退出
第四步:启动流量大管家 MySQL Router
集群建立完毕,启动 Router 代理层:
docker-compose up -d mysql-router
第五步:客户端连接与“拔网线”测试
-
打开 Windows 上的 Navicat。
-
新建 MySQL 连接:
-
主机:
localhost(如果在虚拟机跑 Docker,填虚拟机 IP) -
端口:
6446(千万别填 3306) -
用户名/密码:
root/Root_Password123!
-
点击确定,双击连接,成功连入
如果报错了
修改 MySQL 服务器的密码加密策略
进入主库容器
docker exec -it mysql1 mysql -uroot -pRoot_Password123!
在 MySQL 命令行中执行以下两条 SQL 把密码加密方式改回老版本:
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'Root_Password123!';
FLUSH PRIVILEGES;
在 Navicat 里建个库,插条数据。然后去终端把主库干掉:

关闭主库
docker stop mysql1

创建表没有问题
回到 Navicat,刷新一下或者继续写数据,你会发现业务毫无波澜,Router 已经把你的 SQL 悄悄送到了 mysql2 或 mysql3 的手中。
去连接 还在运行的节点
# 连接到存活的 mysql2
docker run -it --network mysql-cluster_cluster_net --rm mysql/mysql-server:8.0 mysqlsh root@mysql2:3306 -pRoot_Password123!
进入后再次执行:
var cluster = dba.getCluster();
cluster.status();

可以看到mysql3"memberRole": "PRIMARY",说明mysql3成为了新的主库
更多推荐


所有评论(0)