拉取镜像
首先搞个服务器,装好docker
可以用
docker search mysql
查看有哪些mysql的镜像,列表中第一个是官方镜像
然后使用
docker pull mysql:5.7.29
拉取mysql5.7版本的镜像,本文以mysql5.7版本为例
准备配置文件
之后我们需要分别启动主从两个容器,因主从配置项有区别,我更推荐将配置文件外挂出来的方式,否则我们要在启动容器后进入容器中对配置项进行vim编辑,这样会有两个问题,一个是mysql默认的镜像中使用的Linux系统非常精简,是不带vim和vi指令的,需要安装,而且直接安装也是装不上的,需要先
apt-get update
之后再
apt-get install vim
才能安装vim
这样会导致我们的容器变大,众所周知虽然大部分时候变大挺好但对容器来说变大不是什么好事,更不要说这句install需要翻墙才能链接到debian.org这个域名
第二个问题是我们本身就不应当在容器里面做修改,容器应当是轻量型的,随用随启,随删随走的,而启动容器后还需要进去改设置这种行为本身不符合docker的轻量化思想
综上,我们采用配置文件外挂的方式
建议专门建一个文件夹在你的常用目录中,用来存放容器中mysql的配置文件
新建一个格式为.cnf的文件,作为主库的配置文件,写入以下内容
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
[mysqld]
## 同一局域网内注意要唯一
server-id=001
## 开启二进制日志功能,可以随便取(关键)
log-bin=mysql-bin
其中server-id在一个mysql集群中不可重复
然后我们再新建一个格式同样为.cnf的文件,作为备库的配置文件,写入以下内容
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
[mysqld]
## 设置server_id,注意要唯一
server-id=010
## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-slave-bin
## relay_log配置中继日志
relay_log=edu-mysql-relay-bin
保存好,这样,我们就完成了mysql主备的配置文件的准备
启动容器
先启动主库
docker run -p 3339:3306 --name master-node -e MYSQL_ROOT_PASSWORD=123456 --restart="always" -v /home/dockermysqlconf/masterconf.cnf:/etc/mysql/my.cnf -v 宿主机存储路径:/var/lib/mysql -v /etc/localtime:/etc/localtime -d mysql:5.7.29
参数 | 作用 |
---|---|
-p 宿主机ip:容器内ip | 设置端口 |
--name 容器名 | 设置容器名,随便起 |
-e 环境变量key=环境变量value | 设置环境变量,本句中设置了mysql的密码 |
--restart="always" | 自动持久化,死了自动拉起来 |
-v 宿主机绝对路径:容器内绝对路径 | 文件挂载,本句中先将配置文件挂载进容器,然后将数据库的文件存储文件夹挂载出来,最后是将时区文件挂载进去 |
-d | 跑起来以后不打印镜像日志/类似于nohup跑 |
mysql:5.7.29 | 使用的镜像为mysql:5.7.29 |
后启动从库
docker run -p 3340:3306 --name slave-node -e MYSQL_ROOT_PASSWORD=123456 --restart="always" -v /home/dockermysqlconf/slaveconf.cnf:/etc/mysql/my.cnf -v 宿主机存储路径:/var/lib/mysql -v /etc/localtime:/etc/localtime -d mysql:5.7.29
主库是3339端口,从库是3340端口
现在可以先用navicat连接一下数据库,确认一下数据库服务是否正常
主从配置
配置主库
docker ps
查看主库的容器id,或着使用刚才命名的容器名来指定也可以
docker exec -it 主库容器id/容器名 /bin/bash
进入主库的容器
mysql -uroot -p
123456/你的密码
进入主库容器中的mysql
然后执行下列两个指令
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
如果使用的是mysql8.0以上版本的话,需要指定密码插件,执行
CREATE USER slave@'%'IDENTIFIED WITH 'mysql_native_password' BY '123456';
grant replication slave on *.* to slave@'%';
flush privileges;
在Master数据库创建数据同步用户,授予用户 slave REPLICATION SLAVE权限和REPLICATION CLIENT权限,用于在主从库之间同步数据
接着在主库的mysql中执行
show master status;
查看主库的binlog进度,用于待会告诉从库从主库的binlog的哪里开始进行同步
从现在开始到主从设置好之前,主库不要有变动,否则会影响Position的值,同步前就需要重新查询
获取主库容器ip
配置从库前,我们需要先查询一下主库的容器ip
在宿主机执行
docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称/容器id
可以知道指定容器的ip,配置从库的时候需要用到
配置从库
现在进入从库,同上流程进入容器后进入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 |
master_port | Master的端口号,容器内端口号 |
master_user | 用于同步的账号 |
master_password | 同步用账号的密码 |
master_log_file | 指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值 |
master_log_pos | 从哪个 Position 开始读,即上文中提到的 Position 字段的值 |
master_connect_retry | 如果连接失败,重试的时间间隔,单位是秒,默认是60秒 |
然后我们再在从库执行
show slave status \G;
查看主从同步状态
正常情况下,SlaveIORunning 和 SlaveSQLRunning 都是No,因为我们还没有开启主从同步过程
执行
start slave;
开启主从同步,之后我们再次执行
show slave status \G;
查看主从同步状态
SlaveIORunning 和 SlaveSQLRunning 都是Yes,说明主从复制已经开启。此时可以测试数据同步是否成功
测试就很简单啦,在主库建个数据库建个表写个数据什么的都可以
参考文章
- 基于Docker的Mysql主从复制搭建