本文前提,需先安装好docker
如果直接linux上面搭建mysql主从,可看我的另外一篇文章:ubuntu22 mysql8.0如何搭建主从复制
拉取mysql
docker pull mysql:8.0.30
解释一下这条命令,相当于:docker 拉取 mysql:版本号
查看镜像:docker images
,图中第二行就是刚才拉取的sql镜像:
创建并运行容器
mysql的cnf配置文件,可以自己编写并载入容器,也可以在启动容器时作为参数传入。这里采用参数传入。
我是直接看的官网,官网有详细使用说明:https://hub.docker.com/_/mysql
主库的容器:
docker run -p 1306:3306 --name master_mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0.30 --server-id=1 --log-bin=bin-log --binlog-do-db=test_master
docker run
表示创建并运行容器
-p 1306:3306
字母 p 是 port 的首字母,代表端口,把宿主机的1306端口映射到容器的3306端口
--name master_mysql
表示给这个容器取个名字,叫 master_mysql
-e MYSQL_ROOT_PASSWORD=123456
这是 mysql 镜像的官方要求的参数,设置 root 用户的密码
-d mysql:8.0.30
字母d是detach的首字母,表示后台静默运行
后面两个减号的那种参数,是mysql的配置文件里的参数,可以直接把 .cnf里面的参数写成 --参数名=值
放到这里运行。具体都涉及到什么参数,以及它的含义,可以看我另外一篇文章。
--server-id=1
设置唯一id
--log-bin=bin-log
设置binlog日志文件名,因为主从复制是通过这个日志来传输
--binlog-do-db=test_master
对应要复制的数据名
从库的容器:
docker run -p 2306:3306 --name slave_mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0.30 --server-id=2 --relay-log=mysql-relay --read-only=1
--server-id=2
设置唯一id
--relay-log=mysql-relay
relay-log日志文件名,因为主从复制时去主库复制过来后,会先写入这个本机日志,然后再写入sql库里
--read-only=1
表示从库,只读不能写
现在查看一下,两个 mysql 镜像是否正在运行,这是我的两个实例,如图:
主库:创建账户并授权
(1) 在 linux 终端输入命令进行容器:docker exec -it master_mysql /bin/bash
如图,这里已经进入容器了,它也是一个linux终端。因为,容器类似于一个虚拟机,里面也有 linux 操作系统。
(3) 进入mysql终端:mysql -u root -p
,会要求输入密码,输入前面启动容器时设置的密码123456即可
(4) 创建用户并授权。
# 创建一个用户名slave1,密码123456
CREATE USER 'slave1'@'%' IDENTIFIED BY '123456';
# 授权
GRANT REPLICATION SLAVE ON *.* TO 'slave1'@'%';
#此语句必须执行。否则报错
ALTER USER 'slave1'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
# 使权限生效
flush privileges;
查询主库的状态,并记录下File和Position的值,下面从库连接主库时要用。
show master status;
注意:执行完此步骤后不要再操作主服务器MySQL,防止主服务器状态值变化。
从库:连接主库
(1) 主从复制的关键一步。登录从库sql终端,执行以下sql语句。
CHANGE MASTER TO MASTER_HOST='10.0.3.15', MASTER_PORT=1306,MASTER_USER='slave1', MASTER_PASSWORD='123456', MASTER_LOG_FILE='bin-log.000003', MASTER_LOG_POS=1145;
参数的含义从字面意思也看得出来了,全部是主容器的信息。
这里刚才我用宿主机的 ip port 调试很久,一直连不成功。后来把ip换成了主容器内的ip,连接成功了。然后又换回宿主机ip和port,也成功了。很郁闷。或许是熬夜太晚了,眼花了。
(2) 启动主从同步。
START SLAVE;
然后会提示成功。如果报错,可以执行如下操作,删除之前的relay_log信息,然后重新执行 CHANGE MASTER TO …语句
reset slave; #删除SLAVE数据库的relaylog日志文件,并重新启用新的relaylog文件
(3) 执行sql语句,检查主从同步是否搭建成功
SHOW SLAVE STATUS\G;
如果看到这两个yes,则大功告成。
接下来,可以自己去主库创建test_master库,再创建些数据,然后去从库查看是否也有相同的数据库和数据。
后注
有一个要注意点,实际在生产环境中,需要把数据库、日志等数据存放到宿主机,别把数据存到容器里。创建容器时增加参数即可:-v /home/data/mysqldata:/var/lib/mysql
,这意思是把 mysql 的数据目录 /var/lib/mysql 挂截到宿主机的 /home/data/mysqldata 目录。