启动

  • 启动主库
docker run --name mysql-master -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql
  • 启动从库
docker run --name mysql-slave01  -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql

查看主库和从库的ip

docker inspect --format='{.NetworkSettings.IPAddress}' containerId

配置主库

  • 进入主库容器,编辑配置文件
docker exec -it mysql-master /bin/bash

# 进入到 /etc/mysql 编辑配置文件
root@be2a4406ffd6:/# cd /etc/mysql/
root@be2a4406ffd6:/etc/mysql# ls
conf.d	my.cnf	my.cnf.fallback
  • 在使用vi /vim 时提示 command not found, 则进行如下操作安装, 该操作比较慢,可以开vpn或者从镜像获取
apt-get update
apt-get install -y vim
  • 打开 /etc/mysql/my.cnf 文件,进行如下编辑
[mysqld]
## 设置server_id,一般设置为IP,同一局域网内注意要唯一
server_id=100  

## 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
binlog-ignore-db=mysql  

## 开启二进制日志功能,可以随便取,最好有含义(关键就是这里了)
log-bin=test-mysql-bin  

## 为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存
binlog_cache_size=1M  

## 主从复制的格式(mixed,statement,row,默认格式是statement)
binlog_format=mixed  

## 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
expire_logs_days=7  

## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
  • 在主库中创建同步账号
docker exec -it mysql-master /bin/bash
mysql -uroot -proot

CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';   

flush privileges;
// 查看主库状态
show master status
  • 完成后重启容器
docker restart mysql-master

从库配置

  • 进入容器
docker exec -it mysql-slave01 /bin/bash
  • 编辑配置文件 /etc/mysql/my.cnf
[mysqld]
## 设置server_id,一般设置为IP,注意要唯一
server_id=101  

## 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
binlog-ignore-db=mysql  

## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-slave01-bin  

## 为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存
binlog_cache_size=1M  

## 主从复制的格式(mixed,statement,row,默认格式是statement)
binlog_format=mixed  

## 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
expire_logs_days=7  

## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062 

## relay_log配置中继日志
relay_log=edu-mysql-relay-bin 

## log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1  

## 防止改变数据(除了特殊的线程)
read_only=1
  • 完成后重启slave容器

master 和 slave 连接

  • 进入master 容器,查看binlog的状态
docker exec -it mysql-master /bin/bash

mysql -uroot -p123456

mysql> show master status;

+-----------------------+----------+--------------+------------------+-------------------+
| File                  | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------------+----------+--------------+------------------+-------------------+
| test-mysql-bin.000002 |      156 |              | mysql            |                   |
+-----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)
  • 进入到slave的mysql命令行,执行下面命令建立master和slave的连接
change master to master_host='172.17.0.2', master_user='slave', master_password='123456', master_port=3306, master_log_file='test-mysql-bin.000002', master_log_pos=929, master_connect_retry=30;
  • 查看 slave 状态:在slave mysql命令行键入:
show slave status\G;

如果出现下图中两个都是 Yes 证明连接成功

docker mysql5.7主从 docker mysql 主从配置_docker

  • 注: 在mysql8.0以上,可能会出现如下错误

这是由于mysql8.0以上,slave连接master时增加了认证,具体没弄明白,解决方法是进入slave容器执行以下命令

mysql --ssl-mode=DISABLED -h 172.17.0.2 -uslave -p123456 --get-server-public-key

进入mysql,重启slave

stop slave;

start slave;

show slave status\G;

此时应该已经可以了,可以用navicat连接主从库,在主库新建一个库,在从库刷新之后可以看到从库也已经同步过来了。

常见问题

  • 如果编辑了mysql配置文件后,发现mysql容器启动不了,也没办法进入容器重新编辑,则解决方法:
    将docker容器的配置文件拷贝到宿主机内,在宿主机内修改完配置文件后,再采用相同的方式拷贝或容器内进行配置文件覆盖,即可重新启动容器
docker cp mysql-master:/etc/mysql/my.cnf /usr/local