系列文章
使用Docker 实现 MySQL 循环复制(一)
 使用Docker 实现 MySQL 循环复制(二)
目录
- 系列文章
- 1. 在主机上安装MySQL客户端
- 2. 配置循环复制拓扑
- 2.1 进入容器
- 2.2 创建复制用户并授予复制权限
- 2.3 复位二进制日志
- 2.4 配置环形复制拓扑
- 2.5 导入测试数据并测试复制功能
- 2.6 研究一下 GTID 在 MySQL 复制中的重要作用
 
- 3. 常见出错与解决方法
1. 在主机上安装MySQL客户端
dnf install -y mysql

在主机验证三个 mysql 容器,功能正常:
mysql -uroot -poracle -hdocker-host --port=3306 -e "show variables like 'server_id';" 
mysql -uroot -poracle -hdocker-host --port=3307 -e "show variables like 'server_id';"
mysql -uroot -poracle -hdocker-host --port=3308 -e "show variables like 'server_id';"
- 通过命令行连接到 MySQL 数据库并查询 server_id 参数的值
- -h docker-host表示连接到本地主机,- docker-host是主机名
- --port=3308表示使用 3308 端口连接
- -e后面跟的是 SQL 查询语句,这里是- show variables like 'server_id',用于查看 server_id 参数的值
  
2. 配置循环复制拓扑
分别进入三个 MySQL 容器内,配置循环复制拓扑。循环复制拓扑里,每个主机既是主服务器又是从属服务器。 要在主服务器上做的操作是:
- 创建用于执行复制的 repl 数据库用户
- 授予用户
replacation slave权限要在从属服务器上做的操作是:
- 修改角色为slave
- 启动复制线程
2.1 进入容器
分别进入三个 MySQL 容器内:
docker exec -it mysql-3-mysql1-1 /bin/bash
docker exec -it mysql-3-mysql2-1 /bin/bash
docker exec -it mysql-3-mysql3-1 /bin/bash

 然后连接MySQL服务器,并修改提示符:
mysql -uroot -p
prompt mysql-1>;	

2.2 创建复制用户并授予复制权限
在三个 mysql 上分别创建用于执行复制的 repl 数据库用户,口令为 oracle,并授予replacation slave权限。
- 每个从服务器需要一个合法的账户来连接主服务器并拉取二进制日志(binlog)事件。创建一个专用的复制用户可以提供一个安全的身份验证机制,确保只有授权的从服务器可以连接到主服务器
- REPLICATION SLAVE权限是必要的,因为它允许复制用户从主服务器读取二进制日志,这是复制过程的基础。没有这个权限,从服务器将无法从主服务器获取更新
CREATE USER 'repl' IDENTIFIED WITH mysql_native_password BY 'oracle';
GRANT REPLICATION SLAVE ON *.* TO 'repl';

2.3 复位二进制日志
然后分别在三个 mysql 数据库上执行 reset master;复位二进制日志,以防止重复创建 repl 用户:
RESET MASTER;

2.4 配置环形复制拓扑
配置mysql2 为 mysql1 的从属服务器;mysql3 为 mysql 2 的从属服务器;mysql1 为 mysql 3 的从属服务器。这样就形成了一个环形的复制拓扑结构。
所以要分别在三个MySQL里执行语句去修改角色为slave并启动复制线程。
mysql 1:
CHANGE MASTER TO 
master_host='192.168.30.128', 
MASTER_PORT=3308, 
MASTER_AUTO_POSITION=1; 
START SLAVE USER='repl' PASSWORD='oracle';

mysql 2:
CHANGE MASTER TO 
master_host='192.168.30.128', 
MASTER_PORT=3306, 
MASTER_AUTO_POSITION=1; 
START SLAVE USER='repl' PASSWORD='oracle';

mysql 3:
CHANGE MASTER TO 
master_host='192.168.30.128', 
MASTER_PORT=3307, 
MASTER_AUTO_POSITION=1; 
START SLAVE USER='repl' PASSWORD='oracle';

启动线程后检查从属服务器的状态:
show slave status\G

 
 
2.5 导入测试数据并测试复制功能
在 mysql-3-mysql1-1 容器上创建 world 库:
 
 因为复制拓扑已经建立,所以另外两个容器上的MySQL数据库会同步数据,所以现在三个容器上都有world数据库了,下面在 mysql-3-mysql2-1 容器上导入 world 数据库,下载 world.sql 转储文件,在第三个容器(3308 端口)导入,并在三个数据库中检查数据是都同步。
 我们先退出容器,然后下载world.sql 转储文件:
wget https://github.com/memories198/mysql-3/releases/download/mysql/world.sql

 在第三个容器(3308 端口)导入:
mysql -u root -poracle -hdocker-host --port=3308 world < world.sql;

 然后分别进入3个容器中查看数据是否同步:
 
 在第二个容器中删除大于 4070 的行,检查三个数据库的数据一致性:
 
2.6 研究一下 GTID 在 MySQL 复制中的重要作用
GTID (Global Transaction ID) 是一种用于唯一标识数据库事务的方法。它由两部分组成:源服务器 ID 和一个递增的序列号。当一个事务被提交时,MySQL 自动为这个事务分配一个新的 GTID,并将其添加到 Executed_Gtid_Set 变量中。
 Retrieved_Gtid_Set 表示已经从其他服务器接收并应用的 GTID,而 Executed_Gtid_Set 则表示在这个服务器上已经执行过的 GTID。
使用GTID的好处;
- 简化复制配置:使用 GTID 后,不再需要手动跟踪二进制日志文件名和位置,只需要指定主从关系即可。这大大简化了复制配置过程。
- 支持复杂的复制拓扑:GTID 允许更灵活的复制拓扑结构,如多源复制、环形复制等。这是因为 GTID 能够确保每个事务在整个集群中都是唯一的。
- 提高故障恢复效率:如果某个节点发生故障,可以快速找到最后一个已处理的 GTID,从而确定需要重新同步的数据范围,提高故障恢复效率。

3. 常见出错与解决方法
IO线程未正常启动:
- 检查机器/容器之间的连通性
- 检查配置文件是否写错
- stop slave停掉复制线程,然后- resert master复位二进制日志,在此之前先使拓扑里的数据库数据一致。然后重新建立主从关系。
SQL线程未正常启动:
- 因为是学习环境,所以直接stop slave停掉复制线程,然后resert master复位二进制日志,然后重新建立主从关系。注意在此之前先使拓扑里的数据库数据一致。