Primary-Secondary Replication 主备(从)模式
Group Replication
主备复制 != 备份
是用于
1:实时同步
2:机械故障
3:远程灾备
4:用于备份
5:高可用HA
6:负载均衡
7:读写分离
8:分布式数据库
M 一主模式 (承担读和写)
M-S 一主一从
M-S-S 一主多从
M-M 互主
M-M-S-S 多源复制
复制拓扑结构:


我们把blackhole 又称为黑洞引擎,写完就没了,它的作用就一个,那就是做中转,做分发
复制原理:

主库必须打开二进制日志,在主库上把数据更改(DDL,DML,DCL) 记录到二进制日志(Binary Log) 中
备库I/O线程将主库的日志复制到自己的中继日志(Relay Log)中。(所以中继日志只会在从库这种角色中存在)
备库SQL线程读取中继日志中的事件,将其重放到备库数据之上。
官方给的说明:

M-S 传统模式
master1(master)—————–> master2(slave)
192.168.1.2 ——————–> 192.168.1.3
master hostfile :
192.168.1.2 master1
192.168.1.3 master2
192.168.1.4 slave1
192.168.1.5 slave2
MS流程
首先准备两台环境干净的主机,两台数据库。一主一从
Master(主库)
1: my.cnf 文件添加 log-bin server-id=1 两台主机都打开binlog日志(互备)
restart(重启mysql)
2: grant replication 授权
3: 初始化数据库 ,mysqldump all databases (log_file,position) scp rsync ——> master2(Slave) 把主库数据备份,然后传给从库 记录下二进制的log_file和position, Slave从库 就从position这个位置开始追赶主库的记录 ,最后达到一致
Slave(从库)
1: server-id =2
2: 初始化数据库,导入(主库之前备份的)数据
3:mysql > change master to
master_host=’master’, #或masterIP
master_user=’授权用户’ ,
master_password=’授权密码’,
master_log_file=’xxx’ ,
master_log_pos=’xxx’;
4:mysql > start slave ;
5:mysql > show slave status \G
Master 部署[master1]:
[root@Breeze ~]# vim /etc/my.cnf
log-bin
server-id=1
[root@master1~]# systemctl restart mysqld
[root@master1~]# mysql -p'admin'
mysql > grant replication slave , replication client on *.* to 'repo'@'192.168.1.%' identified by 'password'; (这里直接授权给192.168.1.0网段用户名为 repo 密码为 'password' , *.* 表示所有数据库的所有表)
mysql > flush privileges;
[root@master1~]# mysqldump -p'admin' --all-databases --single-transaction --master-data=1 --flush-logs > `data+%F`-mysql-all.sql (文件名 2020-02-28-15-mysql-all.sql)
[root@master1~]# vim 2020-02-28-15-mysql-all.sql
(打开文件看一看确认是否有问题,确保第22行 CHANGE MASTER TO MASTER_LOG_FILE='master1_bin.000002',MASTER_LOG_POS=154; 这一行没有被注释)
[root@master1~]# scp -r 2020-02-28-15-mysql-all.sql master2:/root (传到master2的root目录下)
mysql > 在做一些插入修改的操作,来增加下binlog日志的记录
Slave 部署[master2]
先对我们master1授权的账户 repo’@’192.168.1.%’ identified by ‘password’; 进行测试。
[root@master2~]# mysql -hmaster1 -urepo -p'password' (对之前master1 的 repo'@'192.168.1.%' identified by 'password' 授权信息进行验证,在排除防火墙的影响下,确保能够登录,否则后面一切操作都无效,进行I/O操作是就会报错)
mysql > show grants;(登录后查看下权限)
[root@master2~]# vim /etc/my.cnf
server-id=2
[root@master2~]# systemctl restart mysqld
下一步就可以导入我们之前master1 用mysqldump 备份的2020-02-28-15-mysql-all.sql 数据了 , 导入的方法我们有两种,第一是在mysql终端外部,使用mysqldump < 进行导入,还有一种就是进入到mysql终端 使用source 进行导入。
这里最好不要采用外部mysqldump导入的方式去导入,否则文件无法识别到我们2020-02-28-15-mysql-all.sql 文件中的 binlog position , 即我们之前vim 确认的 第22行 CHANGE MASTER TO MASTER_LOG_FILE='master1_bin.000002',MASTER_LOG_POS=154 这 一行,后面就需要手动指定文件位置;
mysql > set sql_log_bin=0 ;
mysql > source /root/2020-02-28-15-mysql-all.sql ;
mysql > change master to
master_host='master1',
master_user='repo' ,
master_password='password';
如果是采用外部mysqldunp导入备份sql 的方式 ,这里就要指定 master_log_file='xxx' , master_log_pos='xxx' 两个binlog日志的位置和position
mysql > show slave status \G ;

现在两台主机的数据库就已经完成了同步,可以查询两端的数据库,可以发现数据一致,因为上面说明了binlog 的position ,salve 就可以读取binlog日志,开始对master1数据进行同步,对master1 ,进行任何DDL,DML,DCL 操作,salve 就会自动进行同步。因为之前
grant replication slave , replication client on *.* to ‘repo’@’192.168.1.%’ identified by ‘password’; 这里是对*.* 是对所有数据库所有表进行授权,所以会同步所有操作。
M-S GTID 互备模式
清理环境
master1(master) ———————–> master2(slave)
192.168.1.2 —————————–> 192.168.1.3
192.168.1.2 master1
192.168.1.3 master2
192.168.1.4 slave1
192.168.1.5 slave2
[root@master2~]# systemctl stop mysqld
[root@master2~]# rm -rf /var/lib/mysql/*
[root@master2~]# systemctl start mysqld
[root@master2~]# grep password /var/log/mysqld.log
[root@master2~]# mysqladmin -p'随机密码' password'admin'
M-S流程 GTID:
Master :
1: my.cnf 文件添加
log-bin
server-id=1
gtid_mode =ON
enforce_gtid_consistency=1
restart mysql
2:grant replication
grant replication slave , replication client on *.* to ‘repo’@’192.168.1.%’ identified by ‘password’;
3:初始化数据库(逻辑完全备份) mysqldump all databases scp rsync ——–>master2
mysqldump -p’admin’ –all-databases –single-transaction –master-data=2 –flush-logs > `data+%F
`-mysql-all.sql
scp 2020-02-28-15-mysql-all.sql master2:/root
Slave(master2) :
先测试Master1的授权
mysql -hmaster1 -urepo -p’password’ 测试通过之后再进行下面的下一步操作
1: my.cnf文件添加
server-id=2
gtid_mode=ON
enforce_gtid_consistency=1
master-info-repository=TABLE
reply-log-info-repository=TABLE(slave)
(加了这个之后master的信息,bin,端口,账号信息 等等那些信息就会保存在表当中,如果不加,master会保存在文件当中,在/var/lib/mysql/mster.info,通常建议保存在表 当中, 视同GTID ,会自动协商,保存在表当中。)
2:初始化数据库,导入master1的备份数据
3:
mysql > change master to
master_host='master1',
master_user="授权用户",
master_password='授权密码',
master_auto_position=1,
4 mysql > start slave ; #启动slave 角色
5 mysql > show slave status \G
M-M-S-S GTID
先执行 M-M 流程 (master1 <—————-> master2) 互备模式
master2: 主服务器
1:
log-bin
server-id=2
gtid_moid=ON
enforce_gtid_consistency=1
restart mysqld
2:
确保 master1 和master2 数据已经一致
3:
给master1授权, 上面采用了网段授权的方式 ‘repo’@’192.168.1.%’ 这里就不额外授权了(如果采用IP 授权的方式,授权要从master1授权,2给1授权,在1上做,只有1上授权了,2的数据才会同步过去)
master1 主服务器
mysql > change master to
-> master_host='master2',
-> master_user='repo',
-> master_password='admin',
-> master_auto_position=1;
mysql > start slave ;
mysql >show slave status \G ;
测试:分别在两台mysql 分别插入数据,检测两边的同步情况,现在M-M ok 接下来是S-S
添加 S-S MultiSource 多源复制
先重新初始化数据库(或者将备份在四台主机完全同步),保证master1,master2,slave1,salve2,数据一致
在之前M-M 的基础上,添加S-S
Slave 1
my.cnf:
server-id=3
gtid_moid=ON
enforce_gtid_consistency=1
master-info-repository=TABLE
relay-log-info-repository=TABLE
[root@lslave1~]# systemctl restart mysqld
mysql > reset master;
mysql > change master to
> master_host='master1',
> master_user='repo',
> master_password='admin'
> master_auto_position=1 for channel 'repo-master1';(rep-master1 自定义一个频道的名称)
第二台master:
mysql > change master to
> master_host='master2',
> master_user='repo',
> master_password='admin'
> master_auto_position=1 for channel 'repo-master2';(rep-master2 自定义一个频道的名称)
mysql >start slave status;
mysql >show slave \G ;
Slave2:
my.cnf:
server-id=4
gtid_moid=ON
enforce_gtid_consistency=1
master-info-repository=TABLE
relay-log-info-repository=TABLE
[root@lslave1~]# systemctl restart mysqld
清除下二进制日志
mysql > reset master ;
mysql > change master to
> master_host='master1',
> master_user='repo',
> master_password='admin'
> master_auto_position=1 for channel 'repo-master1';(rep-master1 自定义一个频道的名称)
第二台master2
mysql > change master to
> master_host='master2',
> master_user='repo',
> master_password='admin'
> master_auto_position=1 for channel 'repo-master2';(rep-master2 自定义一个频道的名称)
mysql >start slave status;
mysql >show slave \G ;
启动master之后 通过show slave \G 查看Slave_IO_Running 和 Slave_IO_Running 是否为yes ,如果其中一个为NO,则检查binlog以及master等等, 同时在slave备机 reset master后,master1,master2 也需要reset maste 保持同步;然后stop slave ,再启动 start slave
注意没有reset master不能在主机master 上随便使用。在master ,reset master的前提是数据没有变化,同时主机备机日志冲突