Docker搭建mysql主从复制(各种踩坑经验)

5 篇文章 4 订阅
3 篇文章 0 订阅

一. 前言

写这篇博客,小编吃尽了裤头,把坑几乎踩了个遍,最后还是有惊无险的把这篇文章写完,与其说是教程,不如说是经验总结,感谢大家的阅读,如果觉得有用可以给小编点个赞。
下面是演示使用的软件版本

Mysql 8.0.31
Docker 20.10.18
Cemntos7_Minimal

二. 主服务器实例搭建

1. 环境准备

首先要准备数据卷的存放目录,已经mysql配置文件。

// 主服务器容器卷创建
mkdir -p /mydata/mysql-master/conf

创建好目录后在 mydata/mysql-master/conf 目录下创建一个mysql配置文件 my.cnf

cd /mydata/mysql-master/conf
touch my.cnf

将以下内容加入到 my.cnf 配置文件中

[client]
default_character_set=utf8

[mysql]
default-character-set=utf8mb4

[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=101 
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql  
## 开启二进制日志功能
log-bin=mall-mysql-bin  
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M  
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed  
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7  
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
## 设置编码
collation_server = utf8_general_ci
character_set_server = utf8
##解决 mysql 2059 错误,没有此问题的不加
default_authentication_plugin=mysql_native_password

2. 拉取镜像

可以到DockerHub官网查询想要的mysql版本点击跳转,这里小编演示的是当前最新版本8.0.31,使用如下命令进行拉取。

docker pull mysql

拉取完成后使用以下命令检查是否拉取成功

docker images

在这里插入图片描述

3. 启动实例

PS:小编下面提出了三个启动指令,不同的指令可能会出现不同的bug,也可以根据数据卷的需要选择,也作为小编记录踩坑,所以我选择记录下来,希望我以后技术更好的时候回来为自己解答。

全体注意:这里小编踩了个坑,使用命令1启动不挂载这个数据卷/mydata/mysql-master/mysql-files:/var/lib/mysql-files 容器启动后自动会停止 Exited (1)查看日志会有这个错误Failed to access directory for --secure-file-priv,但是5.7的版本貌似不会有这个bug。

// 命令1 不推荐使用 记录bug作用
docker run --privileged=true  -p 3307:3306 --name mysql-master -v /mydata/mysql-master/log:/var/log/mysql -v/mydata/mysql-master/data:/var/lib/mysql -v /mydata/mysql-master/conf:/etc/mysql -v /mydata/mysql-master/mysql-files:/var/lib/mysql-files  -e MYSQL_ROOT_PASSWORD=123456 --restart=unless-stopped -d  mysql

// 命令2 只是比命令3多挂了个数据卷 推荐使用
docker run -d -p 3307:3306 --privileged=true -v /mydata/mysql-master/log:/var/log/mysql -v /mydata/mysql-master/data:/var/lib/mysql -v /mydata/mysql-master/conf:/etc/mysql/conf.d -v /mydata/mysql-master/mysql-files:/var/lib/mysql-files -e MYSQL_ROOT_PASSWORD=123456  --name mysql-master mysql

// 命令3 推荐使用
docker run -d -p 3307:3306 --privileged=true -v /mydata/mysql-master/log:/var/log/mysql -v /mydata/mysql-master/data:/var/lib/mysql -v /mydata/mysql-master/conf:/etc/mysql/conf.d  -e MYSQL_ROOT_PASSWORD=123456  --name mysql-master mysql
  • –privileged=true 容器内的 root 拥有真正的 root 权限
  • -v /mydata/mysql-master/conf:/etc/mysql 配置文件
  • -v /mydata/mysql-master/log:/var/log/mysql 日志目录
  • -v/mydata/mysql-master/data:/var/lib/mysql 数据存储目录
  • -e MYSQL_ROOT_PASSWORD=123456
  • 这个可加可不加 --restart=unless-stopped 容器挂载后自动重启
  • MYSQL_ROOT_PASSWORD=123456 指定root密码

执行完成后使用以下命令检查一下是否启动成功

docker ps

在这里插入图片描述

4. 配置

然后我们执行以下命令进入容器内部

docker exec -it mysql-master /bin/bash

再执行以下命令回车输入密码,进入mysql

mysql -uroot -p 

5. 密码失效小bug

全体注意:这里本人又踩了个坑输入密码后回车密码竟然失效了会报出这样的错误Access denied for user 'root'@'localhost' (using password: YES) 没有这个问题的同学可以跳过这个。
解决办法:
修改我们容器卷里面的配置文件

// 编辑配置文件
vim /mydata/mysql-master/conf/my.cnf

将以下内容添加到配置文件,这两行的意思就是登陆不需要密码

skip-grant-tables
skip-networking

在这里插入图片描述
添加完成后执行以下命令重启一下容器

docker restart mysql-master

再用上面的命令进入容器,然后使用 mysql -uroot -p 命令登陆mysql(注意这样它提示你输入密码直接回车),然后刷新一下权限,再执行以下命令设置密码,

// 刷新权限
flush privileges;
// 修改root密码
alter user 'root'@'localhost' identified by '123456';

在这里插入图片描述
然后我们再使用 exit 命令退出容器,去把配置文件里面添加的那两个设置的绕过密码的给删了,再使用下面命令重启一下容器,这个问题就解决了。

docker restart mysql-master

6. 远程登陆小bug

想要远程登陆我们刚刚启动好的mysql容器,首先要保证服务器对应端口已经对外开放了,如果没有可以用下面的命令开放,最后不要忘记重启一下防火墙,如果没遇到的话就跳过

firewall-cmd --zone=public --list-ports // 查看防火墙所有开放的端口
firewall-cmd --zone=public --add-port=3070/tcp --permanent  // 放开3070端口
firewall-cmd --reload // 重启防火墙

可能是版本问题我们使用的是mysql 8 会出现一个远程连接工具无法连接的问题,远程连接工具会报出这个错误 [HY000][1130] null, message from server: “Host ‘192.168.56.1‘ is not allowed
可以用下面的发方法解决,先使用下面的命令进入容器,再进入mysql。

docker exec -it [容器名]/[容器ID] bash
mysql -uroot -p // 回车输入密码登录

再依次执行以下命令

use mysql;
update user set host='%' where user='root';
Grant all privileges on root.* to 'root'@'%';  //执行两次
alter user root identified with mysql_native_password by '123456';
FLUSH PRIVILEGES;
show variables like 'character%'; // 查看字符编码

6. 容器实例内创建数据同步用户

登录到mysql服务后,执行以下命令,创建数据同步用户

// 创建用户名为 slave,后面从库需要连接到这个用户上,by 后面的密码和数据库密码没有关系
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
 
// 授权表示可以从任意 ip 使用此用户名和密码连接到主数据库
GRANT REPLICATION SLAVE ON *.* to 'slave'@'%';
 
// 刷新配置
flush privileges;
 
// 查看日志文件 这个可以不执行
show master status;

三. 从服务器实例搭建

上面一些bug在搭建从服务器实例时也可能会出现,所以如果遇到问题可以到上面翻一下。
那小编就不废话了,直接运行下面的命令启动从服务器实例,采用的mysql版本镜像和上面搭建主服务器实例是一样的。

docker run -d -p 3308:3306 --privileged=true -v /mydata/mysql-slave/log:/var/log/mysql -v /mydata/mysql-slave/data:/var/lib/mysql -v /mydata/mysql-slave/conf:/etc/mysql/conf.d -v /mydata/mysql-slave/mysql-files:/var/lib/mysql-files -e MYSQL_ROOT_PASSWORD=123456  --name mysql-slave mysql

1. 新建配置文件

接着启动完后我们就要开始新建从数据库的数据卷配置文件了,方便我们在容器外容器进行配置。
使用如下命令进入从数据库数据卷配置文件存放地,新建一个配置文件 my.cnf

cd /mydata/mysql-slave/conf
touch my.cnf

将以下内容加入到刚创建的 my.cnf 配置文件中

[client]
default_character_set=utf8

[mysql]
default-character-set=utf8mb4

[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=102
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql  
## 开启二进制日志功能,以备Slave作为其它数据库实例的Master时使用
log-bin=mall-mysql-slave1-bin  
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M  
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed  
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7  
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062  
## relay_log配置中继日志
relay_log=mall-mysql-relay-bin  
## log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1  
## slave设置为只读(具有super权限的用户除外)
read_only=1
## 设置编码
collation_server = utf8_general_ci
character_set_server = utf8
##解决 mysql 2059 错误,没有此问题的不加
default_authentication_plugin=mysql_native_password

添加完成后要执行以下命令重启这个从服务器的实例

docker restart mysql-slave

2. 在主数据库中查看主从同步状态

重新进入主数据库中,执行以下命令可以看到同步状态

show master status;

在这里插入图片描述
记录好file的参数和Position的参数,下面要用到的我这里是 mall-mysql-bin.000015 和 820

四. 配置主从复制

终于到了这一步,开始配置主从复制,首先执行以下命令进入到从数据库文件,再登陆mysql。

// 进入从数据库
docker exec -it mysql-slave /bin/bash
// 登陆mysql
mysql -uroot -p

1. 配置主从连接关系

执行以下命令配置主从连接关系 ,执行以下命令注意:现在是在从数据库的mysql环境下。

change master to master_host='主机ip', master_user='slave', master_password='123456', master_port=3307, master_log_file='主机信息获取', master_log_pos= 1033, master_connect_retry=30;

相关参数说明

  • master_host:主数据库的IP地址
  • master_port:主数据库的运行端口
  • master_user:在主数据库创建的用于同步数据的用户账号
  • master_password:在主数据库创建的用于同步数据的用户密码
  • master_log_file:指定从数据库要复制数据的日志文件,通过查看主数据的状态,获取File参数
  • master_log_pos:指定从数据库从哪个位置开始复制数据,通过查看主数据的状态,获取Position参数
  • master_connect_retry:连接失败重试的时间间隔,单位为秒。
    在这里插入图片描述

2. 在从数据库中查看主从同步状态

执行下面的命令在从数据库中查看主从同步状态,注意:是在从数据库中。
下面两条命令都可以,只是显示信息的格式不同

show slave status \G; 
show master status;

在这里插入图片描述
都是No证明还没开始,因为主数据库还没配置。

3. 在从数据库中开启主从同步

执行以下命令即可,注意:是在从数据库中

// 开启主从同步
start slave;

执行完成后再执行下面的命令查看是否配置成功。

show slave status \G; 

如果成功的话 Slave_IO_Running: 和 Slave_SQL_Running 都会是 Yes如下
在这里插入图片描述

4. 一个小bug

全体注意:这里又有个小bug执行完会发现: Slave_IO_Running为No
在这里插入图片描述
出现这种情况的原因有好几种,有可能是两个主从容器mysql的UUID不同,也有可能是上面配置主从连接关系时,master_log_file 和 master_log_pos 没有使用主数据库的信息的问题。

五. 结尾

最后的最后,不知道各位读者朋友是否配置成功,有问题的小伙伴可以在评论区提出来,如果文章有错误或者知道那几个莫名奇妙的bug怎么来的的小伙伴,可以评论区写出,最后感谢大家的阅读,如果对你有帮助,可以给小编点个免费的赞,谢谢大家!!!
最后奉上上面常用到的命令

stop slave; // 停止主从连接
firewall-cmd --reload // 重启防火墙
firewall-cmd --zone=public --add-port=3070/tcp --permanent  // 放行防火墙3070端口
firewall-cmd --zone=public --list-ports // 查看防火墙所有开放的端口
docker inspect --format '{{ .NetworkSettings.IPAddress }}' [容器id] //查看容器ip地址
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值