为什么基于 Docker 搭建?
资源有限
虚拟机搭建对机器配置有要求, 并且安装 mysql 步骤繁琐
一台机器上可以运行多个 Docker 容器
Docker 容器之间相互独立, 有独立 ip, 互不冲突
Docker 使用步骤简便, 启动容器在秒级别
利用 Docker 搭建主从服务器
首先拉取 docker 镜像, 我们这里使用 5.7 版本的 mysql:
docker pull mysql:5.7
然后使用此镜像启动容器, 这里需要分别启动主从两个容器
- Master(主):
- docker run -p 3339:3306 --name mymysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
- Slave(从):
- docker run -p 3340:3306 --name mymysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
Master 对外映射的端口是 3339,Slave 对外映射的端口是 3340. 因为 docker 容器是相互独立的, 每个容器有其独立的 ip, 所以不同容器使用相同的端口并不会冲突. 这里我们应该尽量使用 mysql 默认的 3306 端口, 否则可能会出现无法通过 ip 连接 docker 容器内 mysql 的问题.
使用 docker ps 命令查看正在运行的容器:
此时可以使用 Navicat 等工具测试连接 mysql
配置 Master(主)
通过
docker exec -it 627a2368c865 /bin/bash
命令进入到 Master 容器内部, 也可以通过
docker exec -it mysql-master /bin/bash
命令进入. 627a2368c865 是容器的 id, 而 mysql-master 是容器的名称.
cd /etc/mysql 切换到 / etc/mysql 目录下, 然后 vi my.cnf 对 my.cnf 进行编辑. 此时会报出
bash: vi: command not found
, 需要我们在 docker 容器内部自行安装 vim. 使用 apt-get install vim 命令安装 vim
会出现如下问题:
- Reading package lists... Done
- Building dependency tree
- Reading state information... Done
- E: Unable to locate package vim
执行 apt-get update, 然后再次执行 apt-get install vim 即可成功安装 vim. 然后我们就可以使用 vim 编辑 my.cnf, 在 my.cnf 中添加如下配置:
- [mysqld]
- ## 同一局域网内注意要唯一
- server-id=100
- ## 开启二进制日志功能, 可以随便取 (关键)
- log-bin=mysql-bin
配置完成之后, 需要重启 mysql 服务使配置生效. 使用
service mysql restart
完成重启. 重启 mysql 服务时会使得 docker 容器停止, 我们还需要
docker start mysql-master
启动容器.
下一步在 Master 数据库创建数据同步用户, 授予用户 slave REPLICATION SLAVE 权限和 REPLICATION CLIENT 权限, 用于在主从库之间同步数据.
- CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
- GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
配置 Slave(从)
和配置 Master(主) 一样, 在 Slave 配置文件 my.cnf 中添加如下配置:
- [mysqld]
- ## 设置 server_id, 注意要唯一
- server-id=101
- ## 开启二进制日志功能, 以备 Slave 作为其它 Slave 的 Master 时使用
- log-bin=mysql-slave-bin
- ## relay_log 配置中继日志
- relay_log=edu-mysql-relay-bin
配置完成后也需要重启 mysql 服务和 docker 容器, 操作和配置 Master(主) 一致.
链接 Master(主) 和 Slave(从)
在 Master 进入 mysql, 执行 show master status;
File 和 Position 字段的值后面将会用到, 在后面的操作完成之前, 需要保证 Master 库不能做任何操作, 否则将会引起状态变化, File 和 Position 字段的值变化.
在 Slave 中进入 mysql, 执行 change master to master_host='172.17.0.2', master_user='slave', master_password='123456', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos= 2830, master_connect_retry=30;
命令说明:
master_host :Master 的地址, 指的是容器的独立 ip, 可以通过
docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称 | 容器 id
查询容器的 ip
master_port:Master 的端口号, 指的是容器的端口号
master_user: 用于数据同步的用户
master_password: 用于同步的用户的密码
master_log_file: 指定 Slave 从哪个日志文件开始复制数据, 即上文中提到的 File 字段的值
master_log_pos: 从哪个 Position 开始读, 即上文中提到的 Position 字段的值
master_connect_retry: 如果连接失败, 重试的时间间隔, 单位是秒, 默认是 60 秒
在 Slave 中的 mysql 终端执行
show slave status \G;
用于查看主从同步状态.
正常情况下, SlaveIORunning 和 SlaveSQLRunning 都是 No, 因为我们还没有开启主从复制过程. 使用 start slave 开启主从复制过程, 然后再次查询主从同步状态
- show slave status \G;
- .
SlaveIORunning 和 SlaveSQLRunning 都是 Yes, 说明主从复制已经开启. 此时可以测试数据同步是否成功.
主从复制排错:
使用 start slave 开启主从复制过程后, 如果 SlaveIORunning 一直是 Connecting, 则说明主从复制一直处于连接状态, 这种情况一般是下面几种原因造成的, 我们可以根据 Last_IO_Error 提示予以排除.
网络不通
检查 ip, 端口
密码不对
检查是否创建用于同步的用户和用户密码是否正确
pos 不对
检查 Master 的 Position
测试主从复制
测试主从复制方式就十分多了, 最简单的是在 Master 创建一个数据库, 然后检查 Slave 是否存在此数据库.
Master:
Slave:
来源: http://www.linuxidc.com/Linux/2018-07/153268.htm