在Docker中部署mysql主从复制集群
环境准备
- 启动一个mysql容器并将 mysql 的配置文件复制到宿主机
# 创建一个容器
docker run -d -p 3306:3306 --name mysql57 -eMYSQL_ROOT_PASSWORD=123456 mysql:5.7
# 复制容器mysql57目录 /etc/mysql 到 宿主机的 /root 目录下
# 是将 /etc/mysql 目录 复制到 /root 目录下,也就是将 /etc/mysql 目录下的东西复制到 /root/mysql 目录下
docker cp mysql57:/etc/mysql /root
# 下面的命令是将 /etc/mysql 复制到 /root/mysql 目录下,也就是将 /etc/mysql 目录下的东西复制到 /root/mysql/mysql 目录下
# 反正这几个复制感觉有很复杂的逻辑,像 scp 的复制就不是这种效果
# scp /root/mysql root@remote:/root/mysql 这个命令的执行就很有意思,如果目标位置 /root/mysql 存在这个目录,则会创建一个 mysql 目录,并将里面的内容复制到 /root/mysql/mysql 里面,如果不存在,则会创建 mysql 目录,并将内容复制到 /root/mysql 里面
# docker cp mysql57:/etc/mysql /root/mysql
- 准备主从mysql服务的配置文件
# 在宿主机中复制几份刚才从容器中拷贝出来的 mysql 配置文件
cp /root/mysql /root/master
cp /root/mysql /root/slave1
cp /root/mysql /root/slave2
- 修改主从服务的配置
# 修改 master 服务的配置文件
vi /root/master/mysql.conf.d/mysqld.cnf
vi /root/slave1/mysql.conf.d/mysqld.cnf
vi /root/slave2/mysql.conf.d/mysqld.cnf
master 的配置文件中在 [mysqld] 节点添加以下内容
## 同一局域网内注意要唯一
server-id=100
## 开启二进制日志功能,可以随便写(关键)
log-bin=mysql-bin
# 需要同步的库
binlog-do-db=user_db
# 屏蔽系统库同步,要忽略的库
# binlog‐ignore‐db=mysql
# binlog‐ignore‐db=information_schema
# binlog‐ignore‐db=performance_schema
要注意:
- binlog-do-db 和 binlog‐ignore‐db 这两个配置只能存在一个
- log-bin 这个的配置要和 binlog-do-db 配合使用,如果配置 log-bin 和 binlog‐ignore‐db 会报错:
2021-04-27 05:42:20+00:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
command was: mysqld --verbose --help
2021-04-27T05:42:20.832071Z 0 [ERROR] unknown variable ‘binlog‐ignore‐db=mysql‘
slave 的配置文件中在 [mysqld] 节点添加以下内容
## 同一局域网内注意要唯一
server-id=101
# 不能使用 log-bin 配置
# log‐bin=mysql‐bin
## relay_log 配置中继日志
relay_log=edu-mysql-relay-bin
# 设置需要同步的数据库
replicate_wild_do_table=user_db.%
# 屏蔽系统库同步
# replicate_wild_ignore_table=mysql.%
# replicate_wild_ignore_table=information_schema.%
# replicate_wild_ignore_table=performance_schema.%
# 估计 replicate_wild_do_table 和 replicate_wild_ignore_table 也是互斥关系
要这么准备的目的是,启动的容器没有 vi 命令,如果容器已经启动,再修改配置,是比较复杂的,所以干脆把配置文件放在宿主机,要是宿主机都没有 vi ,那就没办法了,宿主机根本运行不了docker。
创建并启动主从mysql服务的容器
# 启动容器,并将宿主机的 /root/master 目录挂载到容器的 /etc/mysql 目录,这样宿主机上的配置就和容器中的配置一样的,修改宿主机的配置,也会修改容器中的配置
docker run -v /root/master:/etc/mysql -p 3310:3306 --name master -eMYSQL_ROOT_PASSWORD=123456 mysql:5.7
docker run -v /root/slave1:/etc/mysql -p 3311:3306 --name slave1 -eMYSQL_ROOT_PASSWORD=123456 mysql:5.7
docker run -v /root/slave2:/etc/mysql -p 3312:3306 --name slave2 -eMYSQL_ROOT_PASSWORD=123456 mysql:5.7
启动主从连接
- 进入 master 容器并登录mysql
[root@localhost ~]# docker exec -it master bash
root@f6befc6ce7be:/# mysql -h localhost -u root -p
- 查看 master 的状态并创建同步用户
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000004 | 1584 | user_db | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql> GRANT REPLICATION SLAVE ON *.* TO ‘db_sync‘@‘%‘ IDENTIFIED BY ‘db_sync‘;
记住 File 和 Position 的值,配置 slave 的时候要用
- 进入 slave 容器并登录 mysql
[root@localhost ~]# docker exec -it master bash
root@f6befc6ce7be:/# mysql -h localhost -u root -p
- 创建 slave 与 master 的连接
mysql> stop slave;
> OK
> 时间: 0.002s
mysql> CHANGE MASTER TO
> master_host = ‘192.168.220.128‘,
> master_port = 3310,
> master_user = ‘db_sync‘,
> master_password = ‘db_sync‘,
> master_log_file = ‘mysql-bin.000004‘,
> master_log_pos = 1584;
> OK
> 时间: 0.006s
mysql> start slave;
注意,master_log_file 和 master_log_pos 就是前面查询的 master 的状态。
- 最后执行 show slave status,只要结果的 Slave_IO_Running 和 Slave_SQL_Running 都是 yes 表示配置成功
一个取巧的办法,启动完主从服务器之后,使用工具连接mysql,比如 navicat,利用这个工具执行 sql 语句,比登录容器,通过 mysql 命令行登录要方便一些.