为什么要用docker搭建mysql?


1.资源有限


2.虚拟机搭建对机器配置有要求,并且安装mysql步骤繁琐


3.一台机器上可以运行多个Docker容器


4.Docker容器之间相互独立,有独立ip,互不冲突


5.Docker使用步骤简便,启动容器在秒级别



为什么要用主从复制模式?


1.数据自动备份,解决单台节点宕机后数据丢失问题


2.读写分离。在业务复杂的系统中,有这么一个情景,有一句sql语句需要锁表,导致暂时不能使用读的服务,那么就很影响运行中的业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作


3.架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。



主从复制原理


1.在主库上把数据更高记录到二进制日志:


            

binlog线程——记录下所有改变了数据库数据的语句,放进master上的binlog中;


2.从库将主库的日志复制到自己的中继日志


            

io线程——在使用start slave 之后,负责从master上拉取 binlog 内容,放进自己的relay log中;


3.从库读取中继日志的事件,将其重放到从库数据中


            

sql执行线程——执行relay log中的语句;



既然要搭建mysql主从复制,那就需要多个节点的Mysql,我这里是3个节点

IP

节点角色

mysql版本

192.168.0.201


mysql 5.7

192.168.0.202


mysql 5.7

192.168.0.203


mysql 5.7

这里要注意的是,各个节点的Mysql版本需要一致,并且各个节点的操作系统也要一致

一.docerk搭建mysql主从复制集群

1.docker安装

首先在服务器上装好docker,我的服务器是centos7
docker的安装十分简单,具体参考

另外,解决拉取镜像很慢的问题:

##使用阿里云镜像加速器
[root@localhost ~]# mkdir -p /etc/docker
[root@localhost ~]# tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://9cpn8tt6.mirror.aliyuncs.com"]
}
EOF
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker

直接一步一步的复制操作,就完事了。

2.docker拉取Mysql镜像,创建mysql容器

docker pull mysql:5.7

然后用此镜像启动容器

docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

每个节点都执行上述操作,端口都是3306就可以,密码根据实际情况输入。mysql的版本指定为5.7.

docker 搭建sqlib靶场 docker搭建mysql集群_数据库


docker ps 查看容器是否启动成功

docker 搭建sqlib靶场 docker搭建mysql集群_mysql_02


使用Navicat 分别连接各个节点的Mysql,查看mysql是否搭建成功

(ps:注意如果连接失败,请检查防火墙,端口映射,或mysql是否开启远程访问等原因)

3.配置Master主节点

1.配置my.cnf

通过docker exec -it mysql /bin/bash命令进入到masql内部,mysql是创建容器时设置好的容器名称

首先,检查容器是否有vim命令,如果没有,则执行apt-get install vim,
会出现以下问题:

Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package vim

遇到这个问题,需执行apt-get update,然后再执行apt-get install vim,即可解决此问题。
下面我们在容器内执行 cd /etc/mysql 进入到mysql目录下,vim my.cnf,添加如下配置:

[mysqld]
##同局域网唯一ID
server-id=201
## 开启二进制日志功能,可以随便取(关键)
log-bin=mysql-bin

配置完毕,执行service mysql restart重启mysql服务。因为这是在docker里面,重启后会自动退出容器,容器也会自动停止,所以这里要执行docker start mysql来启动容器

2.创建master数据库同步用户

授权用户slave用户REPLICATION SLAVE权限和REPLICATION CLIENT权限,用于在主从库之间同步数据。
首先进入mysql内部命令行

mysql -uroot -p
输入密码:

进入mysql命令行后,开始创建同步用户以及权限

CREATE USER ‘slave’@’%’ IDENTIFIED BY ‘123456’;

GRANT REPLICATION SLAVE, REPLICATION CLIENT ON . TO ‘slave’@’%’;

docker 搭建sqlib靶场 docker搭建mysql集群_docker_03


配置完毕后,再次用Navicat数据库连接工具,用这个同步用户slave测试一下是否可以连接

4.配置从节点(所有从节点都配置)

准备工作和上述master节点一样,先确保vim命令可用
然后相同的步骤,进入mysql的容器,进入mysql目录,vim my.cnf,添加如下配置

[mysqld]
## 设置server_id,注意要唯一
server-id=202
## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-slave-bin   
## relay_log配置中继日志
relay_log=edu-mysql-relay-bin

配置完毕,依旧按照master的步骤,重启Mysql服务,然后启动容器

5.链接主从节点

1.master主节点

master进入mysql容器,然后进入Mysql命令行,执行show master status;

docker 搭建sqlib靶场 docker搭建mysql集群_docker_04


记录File和Position的值,后面要用到。注意,这里,master节点不要做任何操作了,否则变化后,会影响设置主从数据同步的操作,等从节点都设置完毕,再做操作。

2.Slave从节点

进入从节点的mysql容器,再进入mysql命令行,执行:

change master to master_host='192.168.0.201', 
master_user='slave', master_password='123456',
master_port=3306, 
master_log_file='mysql-bin.000001', 
master_log_pos= 2830, master_connect_retry=30;

上述命令代表含义:
master_host:主节点的IP。这里我们主节点的IP是192.168.0.201。
如果不对,就改成容器的独立IP,也就是201节点的mysql容器内的独立IP,可以通过
docker inspect --format=’{{.NetworkSettings.IPAddress}}’ 容器名称|容器id
查看容器的IP
master_user: 同步主节点数据的用户名
master_password:同步主节点数据用户的密码
master_port:主节点端口号
master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值
master_log_pos:从哪个 Position 开始读,即上文中提到的 Position 字段的值
master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒

这条同步命令执行完毕后,依然是在mysql命令行,执行show slave status \G;

来查看同步状态;

docker 搭建sqlib靶场 docker搭建mysql集群_docker 搭建sqlib靶场_05


此时,如上图圈出的地方所示,SlaveIORunning 和SlaveSQLRunning 都是No,因为现在还没有开启主从复制的功能。现在再执行start slave; 来开启主从复制功能。开启后,再次查看状态

docker 搭建sqlib靶场 docker搭建mysql集群_docker 搭建sqlib靶场_06


此时,如上图红圈中所示,都变为了Yes,说明主从复制已经开启。

这一步会博主遇到了个问题,就是SlaveIORunning 一直显示正在启动中…

(1) 是因为上面一步设置同步复制命令里的master_log_pos和master_log_file这2个参数和master的不一致,然后又执行了一次后正常。

(2) 其次还可能有一个原因,就是节点的server-id重复,出现冲突。

(3) IO问题,网通不同,防火墙问题,账号密码不匹配等

以上是出现频率比较高的几个原因。

6.测试主从复制

下面我们用Navicat数据库连接工具,分别连接3个节点mysql

docker 搭建sqlib靶场 docker搭建mysql集群_linux_07


201作为主节点,其他作为从节点

然后在201主节点,创建一个数据库,再创建一张表

docker 搭建sqlib靶场 docker搭建mysql集群_mysql_08


此时,202和203从节点没有做任何操作,但是打开一看,已经有了和201主节点一模一样的数据库和表

然后再在201主节点,随便加几行什么数据。刷新各个从节点,从节点也都有相同数据了。