拉取镜像
搞个服务器,装好docker
输入
docker pull mysql:5.7.29
拉取mysql官方镜像,本文以mysql5.7.29版本为例
准备配置文件
本文推荐将mysql配置文件挂载出来,便于查看和统一管理
新建一个格式为.cnf的文件,作为主库的配置文件,写入以下内容
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
[mysqld]
## 同一局域网内注意要唯一
server-id=001
## 开启二进制日志功能,可以随便取(关键)
log-bin=mysql-bin
gtid_mode=on
enforce_gtid_consistency=on
relay-log=relay-log.log
binlog_format=ROW
#MySQL5.7可以不启用此参数,5.7版本使用了gtid_executed表记录同步复制的信息,避免两次写入relay-log和binlog,降低了从库磁盘I/O
#log_slave_updates=true
master_info_repository=TABLE
relay_log_info_repository=TABLE
sync_master_info=1
slave_parallel_workers=2
binlog_checksum=CRC32
master_verify_checksum=1
slave_sql_verify_checksum=1
binlog_rows_query_log_events=1
#replicate_do_db=tt
#MySQL5.7新增加的值,配置基于表的组提交并行复制,默认值为database(基于库进行多线程复制,MySQL5.6是基于库的方式进行多线程方式复制)建议改为logical_clock,基于表的组方式复制,提高复制的效率
slave_parallel_type=logical_clock
#设置mysql连接未被使用的话多久超时失效,默认为8小时,这里设置为24小时,单位为秒
wait_timeout=86400
其中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配置中继日志
gtid_mode=on
enforce_gtid_consistency=on
relay-log=relay-log.log
binlog_format=ROW
#log_slave_updates=true
master_info_repository=TABLE
relay_log_info_repository=TABLE
sync_master_info=1
slave_parallel_workers=2
binlog_checksum=CRC32
master_verify_checksum=1
slave_sql_verify_checksum=1
binlog_rows_query_log_events=1
#replicate_do_db=tt
slave_parallel_type=logical_clock
#设置mysql连接未被使用的话多久超时失效,默认为8小时,这里设置为24小时,单位为秒
wait_timeout=86400
保存好,这样,我们就完成了mysql主备的配置文件的准备
启动容器
先启动主库
docker run -p 3339:3306 --name gtid-master -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 | 使用的镜像为mysql:5.7 |
后启动从库
docker run -p 3340:3306 --name gtid-slave -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连接一下数据库,确认一下数据库服务是否正常
主从配置
配置主库
查看主库容器id,进入容器,进入mysql
docker ps
docker exec -it 主库容器id/容器名 /bin/bash
mysql -uroot -p
123456/你的密码
然后执行下列两个指令在Master数据库创建数据同步用户,授予用户 slave REPLICATION SLAVE权限和REPLICATION CLIENT权限,用于在主从库之间同步数据
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
这两句中的%也可以替换为从库的id,这样此账号就会只允许指定从库访问,优点是账号比较安全,缺点是等会我们还需要创建另一个同步账号用于现在的主库向从库同步,而如果像现在这样直接写%不限制访问ip的话,我们只要建一个同步账号就好了
如果使用的是mysql8.0以上版本的话,需要指定密码插件,执行
CREATE USER slave@'%'IDENTIFIED WITH 'mysql_native_password' BY '123456';
grant replication slave on *.* to slave@'%';
flush privileges;
获取主库容器ip
配置从库前,我们需要先查询一下主库的容器ip
在宿主机执行
docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称/容器id
可以知道指定容器的ip,配置从库的时候需要用到
当然因为我们是要部署双主,所以这时候可以把两个容器的ip都查一下
配置从库
现在进入从库,同上流程进入容器后进入mysql,执行
change master to master_host='172.18.0.5', master_user='slave', master_password='123456', master_port=3306, master_auto_position=1, master_connect_retry=30;
参数 | 作用 |
---|---|
master_host | Master的地址,就是刚才我们查到的容器ip |
master_port | Master的端口号,容器内端口号 |
master_user | 用于同步的账号 |
master_password | 同步用账号的密码 |
master_auto_position | 开启自动定位,mysql将会通过gitd自动定位主库和从库的进度 |
master_connect_retry | 如果连接失败,重试的时间间隔,单位是秒,默认是60秒 |
然后我们再在从库执行
show slave status \G;
查看主从同步状态
都是No是因为我们还没有开启主从同步
执行
start slave;
开启同步
再次执行
show slave status \G;
可以看到,已经开始正常的主从同步了
至此,gtid主从部署完成
配置双主
如果前面创建同步账号的时候你创建的账号是限制登录ip的,那现在你需要创建另一个账号给现在的主库登陆从库同步用,注意,****创建账号这个行为需要在主库执行,不能往从库里写数据以免主从不同步
在主库创建了新的账号后从库会自动将这个账号同步过去
当然如果你像我一样直接写的%那就没这个问题
在主库执行
change master to master_host='172.18.0.6', master_user='slave', master_password='123456', master_port=3306, master_auto_position=1, master_connect_retry=30;
将目前的从库指定为目前的主库的主库
与之前一样,执行
show slave status \G;
查看同步状态,会看到
现在同步还没开始
执行
start slave;
开启同步
再次执行
show slave status \G;
可以看到,已经开始主从同步
至此,完成Docker部署Mysql gtid模式双主
可以自己创建一些数据库、表,写点数据进去什么的进行测试
错误处理
如果出现下图情况
Slave_IO_Running的状态一直在连接中,一般是因为设置主库的时候有什么参数写错了,比如图中我这个情况,我把主库ip写错了
这个时候我们先停掉同步
stop slave;
然后重新执行设置主库的命令,注意执行前仔细检查各参数,主库ip、主库端口、主库同步账号、主库同步账号密码、开启自动定位
change master to master_host='172.18.0.6', master_user='slave', master_password='123456', master_port=3306, master_auto_position=1, master_connect_retry=30;
修正了参数之后再执行
start slave;
重新开启主从同步,就可以了
参考文章
- MySQL5.7双主架构搭建(基于GTID方式)
- Docker部署Mysql主从