写这篇博客,小编吃尽了裤头,把坑几乎踩了个遍,最后还是有惊无险的把这篇文章写完,与其说是教程,不如说是经验总结,感谢大家的阅读,如果觉得有用可以给小编点个赞。
下面是演示使用的软件版本
Mysql 8.0.31
Docker 20.10.18
Cemntos7_Minimal
首先要准备数据卷的存放目录,已经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
可以到DockerHub官网查询想要的mysql版本点击跳转,这里小编演示的是当前最新版本8.0.31,使用如下命令进行拉取。
docker pull mysql
拉取完成后使用以下命令检查是否拉取成功
docker images
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
执行完成后使用以下命令检查一下是否启动成功
docker ps
然后我们执行以下命令进入容器内部
docker exec -it mysql-master /bin/bash
再执行以下命令回车输入密码,进入mysql
mysql -uroot -p
全体注意
:这里本人又踩了个坑输入密码后回车密码竟然失效了会报出这样的错误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
想要远程登陆我们刚刚启动好的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%'; // 查看字符编码
登录到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
接着启动完后我们就要开始新建从数据库的数据卷配置文件了,方便我们在容器外容器进行配置。
使用如下命令进入从数据库数据卷配置文件存放地,新建一个配置文件 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
重新进入主数据库中,执行以下命令可以看到同步状态
show master status;
记录好file的参数和Position的参数,下面要用到的
我这里是 mall-mysql-bin.000015 和 820
终于到了这一步,开始配置主从复制,首先执行以下命令进入到从数据库文件,再登陆mysql。
// 进入从数据库
docker exec -it mysql-slave /bin/bash
// 登陆mysql
mysql -uroot -p
执行以下命令配置主从连接关系 ,执行以下命令注意
:现在是在从数据库的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;
相关参数说明
执行下面的命令在从数据库中查看主从同步状态,注意
:是在从数据库中。
下面两条命令都可以,只是显示信息的格式不同
show slave status \G;
show master status;
执行以下命令即可,注意:是在从数据库中
// 开启主从同步
start slave;
执行完成后再执行下面的命令查看是否配置成功。
show slave status \G;
如果成功的话 Slave_IO_Running: 和 Slave_SQL_Running 都会是 Yes如下
全体注意
:这里又有个小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地址