一直想要在测试环境模拟一下mysql的主从数据库搭建,但是又不想安装mysql环境,自然就想到了使用docker来完成两个mysql环境的搭建,直接启动两个mysql镜像的容器可是方便的很,简单记录一下搭建流程。
一、mysql镜像的拉取
由于电脑是mac,直接在docker官网下载docker desktop即可,传送门。也有人觉得mac端的docker环境很难用,起了linux虚拟机再用的,看个人选择,具体就不展开了。
docker启动后直接拉取mysql镜像即可,文章使用5.7版本:
docker pull mysql:5.7
拉取后可使用docker images 查看本地已有镜像。
二、mysql配置文件
启动之前先来看下主从同步的原理。这里使用下极客时间丁奇老师的图:
图中可以看到,两个数据库的同步主要依赖于master节点的binlog日志文件的同步,master节点在binlog有更新的时候就会主动推送到slave节点,而slave节点有一个io_thread 用于负责与主库建立连接,sql_thread用于读取中转日志并写入,这个线程已经演化成为了多个线程,做到了binlog的并行写入,本次使用的5.7版本mysql既如此,这部分感兴趣的同学可自行学习,不做展开了。
在了解完了主从同步的原理之后言归正传,要完成主从数据库配置肯定要启动两个mysql容器,在本地目录下写好两个配置文件用于做一些基础配置,在后续启动容器的时候挂载到docker目录下。
先来看master节点的配置文件:/etc/mysql/master/my.cnf
[mysqld]
user=root
port=3306
log-bin=mysql-bin
server-id=1
配置文件非常简单,
1、一条用于打开binlog文件,具体原因上面已经讲过。
2、配置server-id为1,server-id用于标志binlog是由哪个库产生的,所以主从数据库千万不能一样,不然可能导致主从数据库binlog的循环复制问题。
再看下salve节点的配置文件:/etc/mysql/slave/my.cnf
[mysqld]
user=root
port=3316
server-id=2
log-bin=mysql-bin
首先和master节点使用不同的端口,server-id配置为不同的值。
这里也打开了binlog的设置。如果说设计上为M-S结构,也就是只有一个master节点,slave节点只用于备库,那在slave节点的确是不用打开binlog的,但是在生产环境更多用到的是双M结构,也就是两个节点是互为主备的,这样在主节点突然断电或者不可用的时候,slave节点可以很快切换,所以slave节点的binlog也打开,在后续过程中配置两个节点互为主备。
三、docker容器启动
完成配置文件后,是时候启动docker容器啦。
docker run -p 3306:3306 --name mysql -v /etc/mysql/master/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
docker run -p 3316:3316 --name mysql_slave -v /etc/mysql/slave/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
启动两个docker容器,端口分别为3306和3316,并将上面写好的配置文件挂载到启动容器的/etc/mysql/my.cnf下面。
启动后使用 docker ps 查看
➜ /etc docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ad196f0ceca2 mysql:5.7 "docker-entrypoint.s…" 25 hours ago Up 3 seconds 3306/tcp, 33060/tcp, 0.0.0.0:3316->3316/tcp mysql_slave
d7e19ed66cba mysql:5.7 "docker-entrypoint.s…" 25 hours ago Up 22 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
可以看到两个容器都已经启动起来了。
查看两个docker容器的端口号:
➜ ~ docker inspect --format='{{.NetworkSettings.IPAddress}}' mysql
172.17.0.2
➜ ~ docker inspect --format='{{.NetworkSettings.IPAddress}}' mysql_slave
172.17.0.3
四、mysql配置
master节点配置
启动起来后可以直接使用下述命令来进入到mysql中,也可直接使用navicat等工具直接连接
➜ /etc docker exec -it mysql bash
root@d7e19ed66cba:/# mysql -uroot -p123456
进入master节点后为slave节点创建用于同步的账号并给到相应的权限:
mysql> CREATE USER 'rep'@'172.17.0.3' IDENTIFIED BY '123456';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'rep'@'172.17.0.3';
mysql> flush privileges;
查看当前主节点状态:
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000007 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
这里的File和Position 字段记录下来后续slave节点配置会使用到。
slave节点配置
使用同样的方式进入mysql容器内部:
➜ /etc docker exec -it mysql_slave bash
root@d7e19ed66cba:/# mysql -uroot -P3316 -p123456
将slave节点的master节点指定为上面配置的节点。
配置master的ip地址,端口号,登陆的用户名和密码,开始同步的binlog文件和pos位置信息。pos从0开始也是可以的。
mysql> CHANGE MASTER TO MASTER_HOST='172.17.0.2', MASTER_USER='rep', MASTER_PORT=3306, MASTER_PASSWORD='123456', MASTER_LOG_FILE='mysql-bin.000007', MASTER_LOG_POS=154;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
配置完成后启动slave节点。
使用show slave status\G来查看slave节点状态。
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.17.0.2
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000007
Read_Master_Log_Pos: 154
Relay_Log_File: ad196f0ceca2-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000007
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0
....
1 row in set (0.00 sec)
结果较长,展示了部分。
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0
上述三个字段展示了io_thread、sql_thread、延迟master节点的秒数,展示为上述三样基本就成功啦。
接下来用相同的操作,反过来操作一遍,将slave节点作为master的主节点,就成功将两个节点配置为双M配置,互为主备啦。
操作完成后修改master节点数据后,slave节点数据库很快同步数据,反过来修改slave节点数据,master节点也很快同步数据。
五、后文
值得一提的是,在生产环境一般会将备份节点设置为readonly的,也就是只读,防止有误操作,当然不用担心设置为readonly后binlog的写入也被组织,super节点依然拥有写入权限。在master发生异常需要主从切换的时候再将slave临时顶替上来。为了更好的做到主从同步,binlog 的类型建议使用row模式。
大多数线上数据库都会使用 row + read committed的配置模式。
好啦,文章到这里也就圆满结束了,主要讲述了如何使用docker在开发环境迅速的搭建两个mysql节点,并做双M结构主从配置。😊