mysql的多种主从复制详解

官网下载 mysql
https://www.mysql.com/
现在企业中用的最多的也是5.6 5.7,我们下载5.7版本的就可。

实验环境:
server1 172.25.254.1 前三种复制方式中充当master结点
server2 172.25.254.2 前三中复制方式中充当slave结点
server3 172.25.254.3 再做全同步复制时开启

在做实验的时候每台主机之间必须有解析,因为后面的实验会用到解析。

安装mysql

下载的 rpm-bundle 包里面有:

在这里插入图片描述
将他们用rpm的方式进行安装。

它的配置文件为 /etc/my.cnf

在这里插入图片描述
并且会自动生成 /var/log/mysqld.log 的日志文件,并且会生成一个初始密码:

[root@server1 ~]# cat /var/log/mysqld.log | grep password
2020-05-09T13:56:35.301030Z 1 [Note] A temporary password is generated for root@localhost: Khq*fpetp1S<

初次登陆它会警告我们更改密码:
在这里插入图片描述
进行安全初始化:

mysql_secure_installation 

这里的密码设置要求较高,需要设置的复杂一点 ,我的密码为Cc990718-+
在这里插入图片描述
进行相关的设置就可以了。

登陆数据库:
在这里插入图片描述
就可以登陆了。

mysql中的锁

对数据的操作其实只有两种,也就是读和写,而数据库在实现锁时,也会对这两种操作使用不同的锁,

  • 共享锁(读锁),允许多个事务读一行数据。Share Lock
  • 排他锁(写锁),允许一个事务删除或更新一行数据,其他事物不可以在上锁(读或写)。Exclusive Lock

mysql中的事务

事务: event ,具有四个个特性,原子性,隔离性,一致性,持久性

是无就是一组原子性的SQL查询,或者说一个独立的工作单元。
如果数据库引擎能够成功地对数据库进行该组查询的全部语句,那么就执行改组查询,如果其中有任何一条语句因为崩溃或者其它原因而无法执行,那么所有的语句都不会执行,也就是说,事务内的语句,要莫全部执行成功,要么全部执行失败。

mysql的主从复制(基于二进制日志)

主节点 server1 :172.25.254.1
从结点 server2 :172.25.254.2

原理:复制操作,不是复制数据,更稳定。

主节点先进行写操作,然后会把操作记录进二进制的日志文件中,此时主节点的dump的线程会通知从结点的IO线程复制数据,IO线程就和master结点进行通信,然后把获取到的二进制日志数据写入到终继日志(relay log)中,此时SQL线程会读取中继日志中的内容,在本机重新执行一次(replay)

在这里插入图片描述

master 主节点中配置文件:

vim /etc/my.cnf
在这里插入图片描述
然后打开数据库,执行命令,为复制创建一个用户:

# 创建repl用户,%代表整个网段,Cc9为密码
mysql> CREATE USER 'repl'@'172.25.254.%' IDENTIFIED BY 'Cc990718-+';
Query OK, 0 rows affected (0.00 sec)

#授权所有库的所有表的复制权限给刚创建的用户
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.25.254.%';
Query OK, 0 rows affected (0.00 sec)

SHOW MASTER STATUS;          获取,当前二进制日志的文件名称和位置

在这里插入图片描述
然后层测试使用repl用户登录;
在这里插入图片描述

slave 从结点进行配置

配置文件:vim /etc/my.cnf
在这里插入图片描述
登陆mysql执行命令:

mysql> CHANGE MASTER TO
    ->      MASTER_HOST='172.25.254.1',       主机名
    ->      MASTER_USER='repl',				用户
    ->      MASTER_PASSWORD='Cc990718-+',	密码
    ->      MASTER_LOG_FILE='mysql-bin.000001',		主节点获取到的文件名	
    ->      MASTER_LOG_POS=154;					主节点获取到的文件位置 
#CHANGE MASTER TO MASTER_HOST='172.25.254.1',MASTER_USER='repl',MASTER_PASSWORD='Cc990718-+',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;	

在这里插入图片描述

start slave;          开启复制
show slave status\G    查看slave结点状态,可以看见SQL线程和IO线程都是yes ,则正常开启复制

在这里插入图片描述
IO 线程负责和master结点进行通信,SQL进程负责把通信得来的数据写入到本机的数据库。

查看复制:
在这里插入图片描述
在这里插入图片描述
在主节点创建的数据库就可以在从结点看到了。
我们再在主节点创建一张表:
在这里插入图片描述
在从结点查看:
在这里插入图片描述
这就说明主从复制是ok的,这就是基于二进制日志的主从复制.

在这里插入图片描述
这里面是mysql的一些日志信息,我们可以用 mysqlbinlog 读取这些日志

基于全局事务标识的复制GTID

避免了即与二进制文件日志的复制的缺点:中途出现错误时事务就不能完整进行了,就成为了废数据。

GTID的优点就就是把一个事物看成一个单元,要么整体成功,要么整体失败。

在两台主机上的配置文件都加上GTID:
在这里插入图片描述
然后再slave结点去配置基于gtid的自动位置识别:
先停掉上面的基于二进制文件的slave:
在这里插入图片描述
再修改复制的方式,开启复制;
在这里插入图片描述
在这里插入图片描述
IO和SQL线程开启。
在这里插入图片描述
跟踪gtid 和执行gtid。
我们再次插入数据进行尝试:
在这里插入图片描述
插入user2,
在这里插入图片描述
这时slave结点也能看到了,
并且此时查看状态 , 在这里插入图片描述gtid捕捉到了一个事务:
在这里插入图片描述

半同步复制 Semi-synchronous replication

传统的复制原理:
master的新事务 t1 -> binlog buffer(缓冲区) -> dumper -> slave
binlog buffer(check) -> slave(IO) -> relay log -> SQL -> mysql

  • 传统的几种复制方式存在一个普遍的问题,就是如果master主节点执行一个比较大的任务时,slave主机的复制会消耗系统资源,会有一些延迟,这个时候如果slave还没有复制完成时master结点就挂掉了,这时还没有完成复制的slave就被迫成为新的master主机,这样的方式就会丢失数据。
  • 这样是有很大的缺陷的,所以mysql在5.5本本后就退出了这个半同步复制,相比于异步复制(GTID,二进制日志)提高了数据的完整性。
  • 也就是说master的dumper线程在通知slave之后会接收slave的ack的确认消息,ack 就是是否成功收到 t1 的标志,slave结点再把所有的 binlog 的数据记录到relay log 中后才会返回ack给dumper线程。
  • 如果没有收到ack信号就进入到等待,直到接至少接收到一个ack信号为止(slave结点可能由有多个),如果等待超时,就降级为普通的异步复制,接收到了ack就说明slave结点接收到了完整的 t1 ,就继续进行新的事务。

在主节点安装插件:

mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.16 sec)

在每个子结点安装插件:

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.03 sec)

在这里插入图片描述
在这里插入图片描述
插件安装完成。

激活插件:

mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
Query OK, 0 rows affected (0.00 sec)

mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
Query OK, 0 rows affected (0.00 sec)

slave 结点重启IO线程:

mysql> stop slave IO_THREAD;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> start slave IO_THREAD;
Query OK, 0 rows affected (0.00 sec)

在master结点查看状态:
在这里插入图片描述
功能打开,且又一个客户端在半同步复制。

在这里插入图片描述
功能打开,超时时间为10s。

slave结点查看:
在这里插入图片描述
现在在主节点插入数据测试:
在这里插入图片描述
在这里插入图片描述
复制正常,但我们怎样测试接收的ack信号哪?,我们关闭slave结点的IO线程。

mysql> stop slave io_thread;
Query OK, 0 rows affected (0.04 sec)

然后再次在追结点插入数据。
在这里插入图片描述
可见此时等待了10s才结束的,这时就已经切换到了异步复制了。

再次插入:
在这里插入图片描述
就又非常快了,因为已经到了异步复制了。

但这时我们在slave主机看不到刚才插入的两条数据:
在这里插入图片描述
我们再开启slave结点上的IO线程:
在这里插入图片描述
可见数据就又回来了。

全同步复制,组复制

group replication。银行机构一般会使用全同步。

组复制不同与半同步复制的地方在于,master结点会接收到所有的slave结点的ack信号时才会开始下一步。而半同步只要求接收到 >= 一个的信号就可以了。由于每台结点的内容都一样,所以每台结点主机都可以作为master结点。

我们开启第三台虚拟机: server3 172.25.254.3 作为第二个slave结点。

在三个结点中进行配置:
关闭数据库,并清空之前的数据。

systemctl stop mysqld
rm -fr /var/lib/mysql/*

配置文件:

删除前面的配置,并添加下面的配置:
vim /etc/my.cnf
server1 :

server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW

plugin_load_add='group_replication.so'
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="1d630e12-92a0-11ea-943f-525400685c65"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "172.25.254.1:33061"
loose-group_replication_group_seeds= "172.25.254.1:33061,172.25.254.2:33061,172.25.254.3:33061"     # 主机组
loose-group_replication_bootstrap_group=off
loose-group_replication_ip_whitelist='127.0.0.1,172.25.254.0/24'
loose-group_replication_enforce_update_everywhere_check=ON
loose-group_replication_single_primary_mode=OFF         关闭单主机模式,

server2:

server_id=2            这里的id不能和上面相同
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW

plugin_load_add='group_replication.so'
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="1d630e12-92a0-11ea-943f-525400685c65"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "172.25.254.2:33061"       本地ip
loose-group_replication_group_seeds= "172.25.254.1:33061,172.25.254.2:33061,172.25.254.3:33061"
loose-group_replication_bootstrap_group=off
loose-group_replication_ip_whitelist='127.0.0.1,172.25.254.0/24'
loose-group_replication_enforce_update_everywhere_check=ON
loose-group_replication_single_primary_mode=OFF

做完后我们启动mysqld ,并重新进行初始化,因为我们刚才删除了全部的文件,所以会重新生成初始密码,我们进行更改(三台主机都做):

mysql> alter user root@localhost identified by 'Cc990718-+';
Query OK, 0 rows affected (0.10 sec)

在mysql中进行配置:

server1:

#关闭二进制日志,防止中间三步产生的日志数据传输混乱
mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)

#创建用户
mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'Cc990718-+';
Query OK, 0 rows affected (0.00 sec)

#授权所有库所有表
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
Query OK, 0 rows affected (0.00 sec)

#刷新授权表
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

#再次开启二进制日志
mysql> SET SQL_LOG_BIN=1;
Query OK, 0 rows affected (0.00 sec)

#更改master用户,并指定组复制的插件。
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='Cc990718-+' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.25 sec)

#安装组复制的插件
INSTALL PLUGIN group_replication SONAME 'group_replication.so';

#发起组复制,生成组名,只能再一个结点开启, 这里我们选择server1
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
Query OK, 0 rows affected (0.00 sec)

#启动组复制
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (2.56 sec)

#关闭这个是因为这个参数会再每次开启组复制时生成一个组名,这样就混乱了,所以我们开启一次就关闭。
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
Query OK, 0 rows affected (0.00 sec)

#获取组信息,当前只有一台
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 26ff60fd-92a1-11ea-9713-525400e49b44 | server1     |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
1 row in set (0.00 sec)

然后我们把server2 和server3 加进组去,和上面相同的操作:

server2和server3:

mysql> SET SQL_LOG_BIN=0;

mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'Cc990718-+';

mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';

mysql> FLUSH PRIVILEGES;

mysql> SET SQL_LOG_BIN=1;

mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='Cc990718-+' FOR CHANNEL 'group_replication_recovery';

INSTALL PLUGIN group_replication SONAME 'group_replication.so';

mysql> START GROUP_REPLICATION;

## 如果报错,先关闭组复制,再执行这条命令,这是由于数据冲突产生的
set global group_replication_allow_local_disjoint_gtids_join=on;

这时我们再server1查看组:

server2和server3就加进去了。
在这里插入图片描述
这时我们就可以输入数据进行测试了:
再server1中插入数据:

INSERT INTO t1 VALUES (1, 'Luis');

再server3中插入数据:

insert into t1 values (2,'cay');

在server2中查看:
在这里插入图片描述
发现所有的组内的主机的数据都是一样的。

这样的方式是因为我们在哪一台主机上插入数据,那一台主机就是master主机。这就是组复制的原理。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值