基于Docker部署MYSQL主从复制
基于Docker部署MYSQL主从复制
本文基于MYSQL 8.0.32 部署
一. Docker创建子网
docker network create mysql-net
二. 配置主节点服务器
2.1 创建要挂载的目录和配置文件
#日志
mkdir /mydata/mysql-ms/mysql-master/log
#数据
mkdir /mydata/mysql-ms/mysql-master/data:/var/lib/mysql
#配置
mkdir /mydata/mysql-ms/mysql-master/conf.d:/etc/mysql/conf.d
#配置文件
touch /mydata/mysql-ms/mysql-master/conf.d:/etc/mysql/conf.d/my.cnf
/mydata/mysql-m/mysql-master/conf.d/my.cnf
配置如下:
要注意的点:
- server-id 要唯一
[client]
#设置客户端默认字符集utf8mb4
default-character-set=utf8mb4
[mysql]
#设置服务器默认字符集为utf8mb4
default-character-set=utf8mb4
[mysqld]
#配置服务器的服务号,具备日后需要集群做准备
server-id=1
#不需要同步的库
#binlog-ignore-db=mysql
#设置的二进制日志格式
#binlog_format=mixed
#二进制日志的过期清除时间
#expire_logs_days=7
#跳过主从复制中的错误,防止主从复制失败
#slave_skip_errors=1062
#开启MySQL数据库的二进制日志,用于记录用户对数据库的操作SQL语句,具备日后需要集群做准备
log-bin=mysql-bin
#设置清理超过30天的日志,以免日志堆积造过多成服务器内存爆满。2592000秒等于30天的秒数
#binlog_expire_logs_seconds = 2592000
#解决MySQL8.0版本GROUP BY问题
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
#允许最大的连接数
max_connections=1000
# 禁用符号链接以防止各种安全风险
symbolic-links=0
# 设置东八区时区
default-time_zone = '+8:00'
2.2 docker启动主容器
docker run -d -p 3406:3306 \
--privileged=true \
--net mysql-net \
-v /mydata/mysql-ms/mysql-master/log:/var/log/mysql \
-v /mydata/mysql-ms/mysql-master/data:/var/lib/mysql \
-v /mydata/mysql-ms/mysql-master/conf.d:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 \
--name MYSQL3406 mysql:8.0.32
2.3 登录验证
进入该主节点容器
docker exec -it MYSQL3406 /bin/bash
第一次登录的时候密码为空
mysql -uroot -p
登录成功
2.4 创建root用户并授权
#修改当前登录的密码
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
#创建root用户(用于远程连接)
CREATE USER 'root'@'%' IDENTIFIED BY '123456';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
2.5 创建允许从服务器同步的用户并进行授权
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
FLUSH PRIVILEGES;
三. 配置从节点服务器
3.1 创建要挂载的目录和配置文件
#日志
mkdir /mydata/mysql-ms/mysql-slave/log
#数据
mkdir /mydata/mysql-ms/mysql-slave/data:/var/lib/mysql
#配置
mkdir /mydata/mysql-ms/mysql-slave/conf.d:/etc/mysql/conf.d
#配置文件
touch /mydata/mysql-ms/mysql-slave/conf.d:/etc/mysql/conf.d/my.cnf
配置相对于主服务器的配置,有如下不同:
server-id
不同- 二进制文件名
log-bin
最好不同 - 新增了中继日志的配置
relay_log
,从节点复制事件的日志记录log_slave_update
完整配置如下:
[client]
#设置客户端默认字符集utf8mb4
default-character-set=utf8mb4
[mysql]
#设置服务器默认字符集为utf8mb4
default-character-set=utf8mb4
[mysqld]
#配置服务器的服务号,具备日后需要集群做准备
server-id=1111
#不需要同步的库
#binlog-ignore-db=mysql
#设置的二进制日志格式
#binlog_format=mixed
#二进制日志的过期清除时间
#expire_logs_days=7
#跳过主从复制中的错误,防止主从复制失败
#slave_skip_errors=1062
#开启MySQL数据库的二进制日志,用于记录用户对数据库的操作SQL语句,具备日后需要集群做准备
log-bin=mysql-slave-bin
#设置清理超过30天的日志,以免日志堆积造过多成服务器内存爆满。2592000秒等于30天的秒数
#binlog_expire_logs_seconds = 2592000
#解决MySQL8.0版本GROUP BY问题
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
#允许最大的连接数
max_connections=1000
# 禁用符号链接以防止各种安全风险
symbolic-links=0
# 设置东八区时区
default-time_zone = '+8:00'
#中继日志
relay_log=mall-mysql-relay-bin
#复制事件也写进二进制文件
log_slave_updates=1
3.2 docker启动从容器
从主节点服务器复制的命令,别忘了修改映射的端口、从容器的容器名、映射的路径
docker run -d -p 3407:3306 \
--privileged=true \
--net mysql-net \
-v /mydata/mysql-ms/mysql-slave/log:/var/log/mysql \
-v /mydata/mysql-ms/mysql-slave/data:/var/lib/mysql \
-v /mydata/mysql-ms/mysql-slave/conf.d:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 \
--name MYSQL3407 mysql:8.0.32
3.3 创建root用户并授权
#修改当前登录的密码
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
#创建root用户(用于远程连接)
CREATE USER 'root'@'%' IDENTIFIED BY '123456';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
3.4 配置主从复制
查看主服务器
的ip地址
docker inspect MYSQL3406 | grep IPAddress
查看主服务器
的二进制文件名和二进制日志偏移
docker exec -it MYSQL3406 mysql -uroot -p123456
show master status;
将对应参数写入下面的命令,在从库
执行执行:
-
master_host:
主数据库
的IP地址; -
master_port:
主数据库
的运行端口,是Docker容器的运行端口!! -
master_user:在
主数据库
创建的用于主数据库同步的用户名; -
master_password:在
主数据库
创建的用于主数据库同步的密码; -
master_log_file:指定
主数据库
的二进制日志文件,即上述的File -
master_log_pos:指定
主数据库
的数据偏移,即上述的Position -
master_connect_retry:连接失败重试的时间间隔,单位为秒,默认60s。
change master to master_host='172.18.0.2', master_user='slave', master_password='123456', master_port=3306, master_log_file='mysql-bin.000004', master_log_pos=2198
四. 启动主从复制
从服务器
上开始同步
docker exec -it MYSQL3407 mysql -uroot -p123456
start slave;
查看从服务器同步状态
show slave status;
发现同步失败:
最后发现是两个服务器配置的server_id相同,但是我明明配置了不同的,可能是不能加空格(我删掉空格之后,将从服务器的server_id改成上述的1111就好了)。如果仍然失败,排查一下网络、防火墙、主服务器的my.cnf配置是否正确、主服务器的二进制日志和偏移量是否改变了,网上有很多教程。
修改完之后,成功
五. 测试主从复制
测试,在主库建表并插入数据看看从库是否有
主库
docker exec -it MYSQL3406 mysql -uroot -p123456
use mysql;create table testSyn(id int, name varchar(20));
insert into testSyn values(1,'xiaoming')
从库
docker exec -it MYSQL3407 mysql -uroot -p123456
use mysql;
select * from testSyn;
同步成功: