主从架构背景
- 数据安全,可以进行数据的备份;
- 读写分离,对于大部分的业务系统而言,都是读多写少,若访问压力过大时,可以把请求分发给从服务器,从而缓解数据库访问的压力;
- 故障转移(高可用),当主节点宕机之后,将从服务切换为主节点继续提供服务。
同步原理
Mysql的主从架构一般都是通过binlog日志实现的,binlog日志会记录主库的每一次操作。从库和主库建立TCP连接之后,请求主库将binlog传输过来,这时主库又一个dump线程把binlog传输给主库。从库将读取到的binlog日志写入自己的relaylog,另外一个线程读取relaylog里面的内容进行重放。
一、Docker搭建的好处
- 资源有限,需要更多宿主机;
- 虚拟机搭建对机器配置有要求,并且安装mysql的步骤繁琐;
- 一台机器上可以安装并运行多个Docker容器;
- Docker容器相互独立,有各自的IP,互相不影响;
- Docker使用步骤简便,启动容器在秒级别;
二、Docker搭建步骤
2.1 安装mysql
docker pull mysql
默认最新版本
2.2 启动主从容器
使用msyql镜像启动容器,分别启动主从两个容器;
- -p:映射端口
- --name:表示容器的名字
- -e MYSQL_ROOT_PASSWORD:设置mysql密码,必须设定的参数;
- -d mysql Tag:Tag表示镜像id;
- Master (主)
docker run -p 3339:3306 --name mysql-master -e MYSQL_ROOT_PASSWORD=123456
-d mysql:latest
- Slave(从)
docker run -p 3340:3306 --name mysql-slave1 -e MYSQL_ROOT_PASSWORD=123456
-d mysql:latest
- Master对外映射的端口是3339,Slave对外映射的端口是3340。因为docker容器是相互独立的,每个容器有独立的IP,因此不同容器使用相同的端口并不会冲突。
Navicat测试工具:连接成功!
2.3 配置Master(主)
1)进入容器
- 通过docker exec -it mysql-master /bin/bash命令进入;
- mysql-master:容器名称或者id也行;
2)切换目录
- cd /etc/mysql
3)编辑my.cnf文件
- vim my.cnf
若报错,
bash: vim: command not found
执行以下命令,
- apt-get install vim
若还报错,需更新apt-get,执行以下命令
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package vim
- apt-get update,再执行上步即可完成安装;
4)在my.cnf添加如下配置
[mysqld]
## 同一局域网内要唯一
server-id=100
## 开启二进制日志功能,可以随时取消
log-bin=mysql-bin
5)重启mysql-master容器
- docker restart mysql-master
- docker exec -it mysql-master /bin/bash:运行mysql
6)配置从库,同步数据
- 进入mysql: mysql -u root -p,输入密码;
- create user 'slave'@'%' identified by '123456';
- grant replication slave,replication client on *.* to 'slave'@'%';
- flush privileges;刷新
成功!
语法格式:CREATE USER <用户名> [ IDENTIFIED ] BY [ PASSWORD ] <口令>
<用户名> | 指定创建用户账号,格式为 'user_name'@'host_name'。这里 |
PASSWORD | 密码,可选项,用于指定散列口令,即若使用明文设置口令,则需忽略PASSWORD 关键字。 |
IDENTIFIED BY | 用于指定用户账号对应的口令,若该用户账号无口令,则可省略此子句。 |
<口令> | 指定用户账号的口令,在IDENTIFIED BY 关键字或PASSWOED 关键字之后。给定的口令值可以是只由字母和数字组成的明文,也可以是通过 PASSWORD() 函数得到的散列值。 |
语法格式:grant replication
对于新建的 MySQL 用户,必须给它授权,可以用 GRANT 语句来实现对新建用户的授权。
- replication slave:拥有此权限可以查看从服务器,从主服务器读取二进制日志;授予此权限,复制才能真正工作;
- replication client:拥有此权限可以查询master server、slave server状态;授予此权限,复制才能真正工作;
2.4 配置Slave(从)
同Maser(主)配置,前面省略!
1)在Slave配置文件my.cnf中添加
[mysqld]
## 同一局域网内要唯一
server-id=101
## 开启二进制日志功能,以备份Slave作为其他Slave的Master时使用
log-bin=mysql-slave-bin
## 配置中继日志
relay_log=edu-mysql-relay-bin
2)重启mysql-slave1
2.5 连接Master(主)和Slave(从)
1)进入mysql-master
执行命令:
show master status;
File和Position字段的值后面将会用到;
2)进入mysql-slave1
执行命令:
change master to master_host='172.17.0.3',master_user='slave',
master_password='123456',master_port=3306,
master_log_file='mysql-bin.000005',
master_log_pos=0,master_connect_retry=10,
get_master_public_key=1;
- master_host:Master的地址,是容器的对立IP,可以通过以下命令查看
docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称|容器id
- master_port:Master的端口号,是容器的端口号;
- master_user:用于数据同步的用户;
- master_password:用于同步用户的密码;
- master_log_file:指定Slave从哪个日志文件开始复制数据,即上文中提到的File字段值;
- master_log_pos:从哪个Position开始读,即上文中提到的Position字段的值;
- master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒;
注意记得加上get_master_public_key=1,因为mysql8.0以上需要使用RSA加密来传输密码。
注意:
如果使用容器的IP(master_host)和PORT(master_port)即应当换为主机的IP以及映射到外面的端口,这样就可以避免报错。比如
3)查看主从同步状态
- 进入Slave中的mysql终端执行命令:
show slave status \G;
- 正常情况下,SlaveIORunning和SlaveSQLRunning都是No,因为还没开启主从复制过程。使用以下命令,即可开启主从复制:
start slave
# 此外 若想关闭则 stop slave;即可
- 再次查询主从复制状态show slave status \G;
已经变成Yes!
2.6 主从复制排错
使用start salve开启主从复制后,如果SlaveIORunning一直是Connecting,则说明主从复制一直处于连接状态,这种情况一般是下面几种原因造成的,可以根据Last_IO_Error提示予以排除。
1)网络不通
- 检查ip、端口
2)密码不对
- 检查是否需创建用于同步的用户和用户密码是否正确
3)pos并不对
- 检查Master的Position
4)mysql 版本的问题
- mysql8.0以上密码加密,grant时需加上,
因为mysql8.0以上需要使用RSA加密来传输密码
2.7 测试主从复制
在Master创建一个数据库,然后检查Slave是否存在此数据库
- Master
- Slave