前置要求
需要安装并大致了解Docker与MySQL
环境信息
- Docker Client Version: 19.03.12
- Docker Server Version: 20.10.16
- MySQL Version:5.7
主从复制
二进制日志文件为主从复制的基础,Slave实例需要通过读取Master实例的二进制日志文件,将发送在Master实例上面的DDL、DML、DCL语句复制到Slave实例上,以此实现主从复制,原理如下图:
实现主从复制后从库不得进行写入操作只能查询,因此可以在这基础上实现读写分离
配置环境
Dokcer拉取MySQL 5.7镜像
docker pull mysql:5.7
Docker启动MySQL
实现主从复制需要至少两个MySQL实例
分别启动名称为Master和Slave的实例
Docker网络配置
为了便于两个实例之间通过网络连接,配置Docker Network
docker network create mysql-network
启动Master实例
docker run --network mysql-network --network-alias master -p 2021:3306 --name master -e MYSQL_ROOT_PASSWORD=admin -d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --log-bin=mysql-bin --server-id=2021
Docker相关参数解析:
- --network:选定此实例所属的网络组,同一个网络组的实例可以通过network-alias访问
- --network-alias:网络组内部实例的Host名
- -p:端口映射,将实例内部的3306端口映射到宿主机的2021端口
- --name:实例名
- -e MYSQL_ROOT_PASSWORD:配置环境变量, MYSQL_ROOT_PASSWORD可以配置MySQL实例的初始root用户密码
- -d: 后台运行此实例
- mysql:5.7:实例所属的具体镜像
MySQL相关参数解析:
可以通过下列命令查看启动实例可用的参数,当然也可以通过配置cnf文件来达到同样效果。
docker run -it --rm mysql:5.7 --verbose --help
- --character-set-server --collation-server: 指定MySQL Server的字符集为UTF-8
- --log-bin:MySQL二进制日志的BaseName,MySQL5.7默认不开启二进制文件,只有显示加上此参数才会开启此功能
- --server-id:此实例的id,在一个集群内部,各个MySQL实例的server-id必须保持唯一
启动Slave实例
docker run --network mysql-network --network-alias slave -p 2022:3306 --name slave -e MYSQL_ROOT_PASSWORD=admin -d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --log-bin=mysql-bin --server-id=2022
参数含义和Master类似,不再赘述
查看实例状态
docker ps
配置MySQL主从复制
配置Master实例
以交互bash模式进入Master实例
docker exec -it master bash
进入数据库,输入下列命令后输入密码
mysql -uroot -p
创建reply用户供Slave实例访问Master实例的二进制日志文件
create user 'reply'@'%' identified by '666666';
将复制所需要的权限给予reply用户
grant replication slave,replication client on *.* to 'reply'@'%';
刷新权限
flush privileges;
查看Master实例的二进制日志状况
show master status;
从图中可以看出目前再使用的二进制日志文件是mysql-bin.000003,写入位置为769
配置Slave实例
以交互bash模式进入Slave实例
docker exec -it slave bash
进入数据库,输入下列命令后输入密码
mysql -uroot -p
查看Slave实例的Slave状况
show slave status\G;
可以发现目前还没有启动复制功能
接下来开启Slave实例的复制功能
change master to master_host='master', master_port=3306, master_user='reply', master_password='666666', master_log_file='mysql-bin.000003', master_log_pos=769;
参数解析(注意后面两个参数得自己查询得到):
可以通过下列命令查看启动实例可用的参数,当然也可以通过配置cnf文件来达到同样效果
- master_host:主实例的Host地址或IP地址或域名,由于使用了Docker Network,直接设置为主实例的alias
- master_port:主实例的MySQL服务的端口,注意:此端口为实例内部的端口号而不是宿主机的端口号,所以还是3306
- master_user:复制用户的用户名
- master_password:复制用户的密码
- master_log_file:主实例目前的二进制文件(通过在主实例里面
show master status;
查看) - master_log_pos:主实例目前的二进制文件写入的位置(同上)
查看Slave实例的Slave状况
show slave status\G;
可以发现目前Slave成功指向主实例,但是Slave_IO和Slave_SQL 还没有启动,说明Slave实例还没有开始复制
开始复制
start slave;
可以发现Slave_IO_State是正在等待Master实例发送事务,说明Slave实例已经成功连接上主实例
到此Docker环境下的MySQL的主从复制配置完成!
测试
查看Master实例数据库
show databases;
查看Slave实例数据库
show databases;
在Master实例创建test数据库
查看Slave实例数据库,可以发现多了一个test数据库,说明主从复制正常运行
注意事项
- 在Slave实例使用change master语句前需在Master实例使用,
show master status;
语句查看其目前在使用的二进制日志文件和写入的位置,并且在使用此命令后不得对Master实例进行任何DDL、DML、DCL操作,因为这样会对二进制日志文件进行写入,其位置就发生变更 - Slave实例配置完成后不得执行DDL、DML、DCL语句,只能执行DQL即查询语句。如若误执行相关语句可以通过下列命令重置Slave状态
stop slave;
reset slave;
然后通过binlog或者直接复制数据库将从数据库复制到和主数据库一样的状态后重新执行change master命令即可。所以最好使用只有查询权限的用户访问Slave实例