企业级高性能MYSQL的用法---------(二)----------半同步复制 和 全同步复制(组复制)

企业级高性能MYSQL的用法---------(二)----------半同步复制 和 全同步复制(组复制)

1.基于GDIT的半同步复制

  1. 为什么要实现mysqI的复制
    1.实现服务器负载均衡
    2.通过复制实现数据的异地备份
    3.提高数据库系统的可用性

  2. 异步复制、全同步复制和半同步复制的对比
    1.异步复制( Asynchronous replication )
    MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果down掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。
    2.全同步复制( Fully synchronous replication )
    指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。
    3.半同步复制( Semisynchronous replication )
    介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。

在2010年MySQL 5.5版本之前,一直采用的是这种异步复制的方式。主库的事务执行不会管备库的同步进度,如果备库落后,主库不幸crash,那么就会导致数据丢失。于是在MySQL在5.5中就顺其自然地引入了半同步复制,主库在应答客户端提交的事务前需要保证至少一个从库接收并写到relay log中

  1. 基于GDIT的半同步复制
    第一步:主库安装服务插件,并且开启半同步复制
[root@server1 ~]# mysql -uroot -pXiaoxu@junjun021129
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.28-log MySQL Community Server (GPL)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>  install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (0.01 sec)

mysql> select plugin_name,plugin_status
    -> from information_schema.plugins
    -> where plugin_name like '%semi%';
+----------------------+---------------+
| plugin_name          | plugin_status |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE        |
+----------------------+---------------+
1 row in set (0.01 sec)

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

mysql> show variables like '%semi%'; 
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | ON         |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)

mysql> show status like '%rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)

mysql> 

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第二步:在从端也安装插件,开启半同步复制

mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (0.01 sec)

mysql> set global rpl_semi_sync_slave_enabled=1;
Query OK, 0 rows affected (0.01 sec)

mysql> show variables like '%semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.03 sec)

mysql> 

在这里插入图片描述

注意:要重启从端的IO线程,如果没有重启,则默认还是异步复制,重启后,slave会在master上注册为半同步复制的slave角色

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

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

mysql> show status like '%rpl%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)

mysql> show variables like '%rpl%';
+---------------------------------+----------+
| Variable_name                   | Value    |
+---------------------------------+----------+
| rpl_semi_sync_slave_enabled     | ON       |
| rpl_semi_sync_slave_trace_level | 32       |
| rpl_stop_slave_timeout          | 31536000 |
+---------------------------------+----------+
3 rows in set (0.00 sec)

mysql> 

在这里插入图片描述
在这里插入图片描述

测试:

情况一1:半同步失败的情况

没有通过半同步复制

1.从端关掉IO线程:

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

2. 在主端表中插入数据,会等待10秒,10s后会变为异步复制:

mysql> insert into userlist values ('user5','555');
Query OK, 1 row affected (10.01 sec)

此时在主端发现半同步失败次数+1:

Rpl_semi_sync_master_no_tx表示没有成功接收slave提交的次数,也就是使用半同步失败的次数,10s后没有得到反馈信息,会转为异步复制
Rpl_semi_sync_master_yes_tx使用半同步成功的次数,数据的一致性能提高

在这里插入图片描述

此时,从端会发现没有同步过来,再次打开IO线程后,数据才能同步过来,此时复制过来的是异步复制的结果

mysql> select * from userlist;
+----------+----------+
| username | password |
+----------+----------+
| user1    | 888      |
| user2    | 888      |
+----------+----------+
2 rows in set (0.00 sec)

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

mysql> select * from userlist;
+----------+----------+
| username | password |
+----------+----------+
| user1    | 888      |
| user2    | 888      |
| user3    | 888      |
+----------+----------+
3 rows in set (0.00 sec)

mysql> 

在这里插入图片描述
情况二:半同步正常情况

第一步:从端打开IO:

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

第二步 主端插入新数据:

mysql> insert into userlist values ('user6','666');
Query OK, 1 row affected (0.01 sec)

mysql> select * from userlist;

mysql> show status like '%rpl%';  #Rpl_semi_sync_master_yes_tx 变为1,成功一次

在这里插入图片描述
从端验证同步结果
在这里插入图片描述

2.MySQL的组复制

1.组复制模型

  1. 组复制模型
    MySQL组复制是MySQL 5.7.17开始引入的新功能,为主从复制实现高可用功能。它支持单主模型和多主模型两种工作方式(默认是单主模型)。
  2. 单主模型
    从复制组中众多个MySQL节点中自动选举一个master节点,只有master节点可以写,其他节点自动设置为read only。当master节点故障时,会自动选举一个新的master节点,选举成功后,它将设置为可写,其他slave将指向这个新的master。
  3. 多主模型
    复制组中的任何一个节点都可以写,因此没有master和slave的概念,只要突然故障的节点数量不太多,这个多主模型就能继续可用。

2.组复制原理

复制组由多个 server成员构成,并且组中的每个 server 成员可以独立地执行事务。但所有读写(RW)事务只有在冲突检测成功后才会提交。只读(RO)事务不需要在冲突检测,可以立即提交。

换句话说,对于任何 RW 事务,提交操作并不是由始发 server 单向决定的,而是由组来决定是否提交。准确地说,在始发 server 上,当事务准备好提交时,该 server 会广播写入值(已改变的行)和对应的写入集(已更新的行的唯一标识符)。然后会为该事务建立一个全局的顺序。最终,这意味着所有 server 成员以相同的顺序接收同一组事务。因此,所有 server 成员以相同的顺序应用相同的更改,以确保组内一致。

组复制使您能够根据在一组 server 中复制系统的状态来创建具有冗余的容错系统。因此,只要它不是全部或多数 server 发生故障,即使有一些 server 故障,系统仍然可用,最多只是性能和可伸缩性降低,但它仍然可用。server 故障是孤立并且独立的。它们由组成员服务来监控,组成员服务依赖于分布式故障检测系统,其能够在任何 server 自愿地或由于意外停止而离开组时发出信号。

总之,MySQL 组复制提供了高可用性,高弹性,可靠的 MySQL 服务。

3.实现组复制

实验环境:
server1 server2 server3三台装有mysql的虚拟机

第一步:还原之前做过的实验(因为server1 server2 之前做过实验,server3 是新机)

在server1 和 server2 中:

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

注意:如果之前没有做过其他的mysql实验,就可不用做这一步骤

在这里插入图片描述
在这里插入图片描述
第二步:配置server1

1. 生成UUID:
uuidgen	#这一步生成的uuid要在后面用到

2. 编辑mysql配置文件:

vim /etc/my.cnf
写入:
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	#指示Server必须为每个事务收集写集合,并使用XXHASH64哈希算法将其编码为散列
group_replication_group_name="d2c2069a-974c-11ea-8ffb-000c29050807"	#告知插件,正在加入或创建的组要命名,一般写UUID
group_replication_start_on_boot=off	#指示插件在 server 启动时不自动启动组复制
group_replication_local_address= "192.168.43.71:33061"	#告诉插件使用 IP 地址 本地主机,端口33061用于接受来自组中其他成员的传入连接。
group_replication_group_seeds= "192.168.43.71:33061,192.168.43.72:33061,192.168.43.73:33061"
group_replication_bootstrap_group=off	#配置是否自动引导组
loose-group_replication_ip_whitelist="127.0.0.1,192.168.43.0/24"	#用户白名单
loose-group_replication_enforce_update_everywhere_checks=ON	#多主模式下为多主更新启用或禁用严格一致性检查
loose-group_replication_single_primary_mode=OFF	#设置组自动选择一个 server 来处理读/写工作

在这里插入图片描述

3. 打开服务、过滤密码、安全初始化:

systemctl start mysqld
cat /var/log/mysqld.log | grep password
mysql_secure_installation 
4. 启动组复制:

mysql> SET SQL_LOG_BIN=0;	#禁用二进制日志
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'Xiaoxu@junjun021129';	#创建用户
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)

mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='Redhat.123' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.04 sec)

mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';	#安装组复制插件(因为配置文件已经写过此参数,所以报错)
ERROR 1125 (HY000): Function 'group_replication' already exists
mysql> SHOW PLUGINS;


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.30 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;	#查看状态,显示ONLINE则开启成功

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
第三步:配置server2

1 还原之前做过的实验:
注意:如果之前没有做过其他的mysql实验,就可不用做这一步骤
systemctl stop mysqld
cd /var/lib/mysql
rm -fr *

step2 编辑mysql配置文件:
vim /etc/my.cnf
修改两处:
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	
group_replication_group_name="d2c2069a-974c-11ea-8ffb-000c29050807"	
group_replication_start_on_boot=off	
group_replication_local_address= "192.168.43.72:33061"	#修改本机ip
group_replication_group_seeds= "192.168.43.71:33061,192.168.43.72:33061,192.168.43.73:33061"
group_replication_bootstrap_group=off
loose-group_replication_ip_whitelist="127.0.0.1,192.168.43.0/24"	
loose-group_replication_enforce_update_everywhere_checks=ON	
loose-group_replication_single_primary_mode=OFF	


3 打开服务、过滤密码、安全初始化:

systemctl start mysqld
cat /var/log/mysqld.log | grep password
mysql_secure_installation

4 配置组复制:
mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'Xiaoxu@junjun021129';
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)

mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='Xiaoxu@junjun021129' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.02 sec)

mysql> set global group_replication_allow_local_disjoint_gtids_join=on;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected, 1 warning (3.11 sec)

mysql> 

配置完成之后,在server1上查看状态:

在这里插入图片描述

第四步:配置server3

1 还原之前做过的实验:
注意:如果之前没有做过其他的mysql实验,就可不用做这一步骤
systemctl stop mysqld
cd /var/lib/mysql
rm -fr *

step2 编辑mysql配置文件:
vim /etc/my.cnf
修改两处:
server_id=3	#修改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	
group_replication_group_name="d2c2069a-974c-11ea-8ffb-000c29050807"	
group_replication_start_on_boot=off	
group_replication_local_address= "192.168.43.73:33061"	#修改本机ip
group_replication_group_seeds= "192.168.43.71:33061,192.168.43.72:33061,192.168.43.73:33061"
group_replication_bootstrap_group=off
loose-group_replication_ip_whitelist="127.0.0.1,192.168.43.0/24"	
loose-group_replication_enforce_update_everywhere_checks=ON	
loose-group_replication_single_primary_mode=OFF


3.打开服务、过滤密码、安全初始化:
systemctl start mysqld
cat /var/log/mysqld.log | grep password
mysql_secure_installation

4.配置组复制:
mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'Xiaoxu@junjun021129';
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)

mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='Xiaoxu@junjun021129' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.06 sec)

mysql> set global group_replication_allow_local_disjoint_gtids_join=on;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected, 1 warning (3.09 sec)

mysql> 

配置完成之后,在server1上查看状态:

在这里插入图片描述

测试:

在其中一台服务器中创建新表,在其他两台都能看见插入的信息

这里我们在server3中插入数据,在server1 和server2 中都可以看到数据

server3 中

在这里插入图片描述
server1 和 server2
在这里插入图片描述

同理:在其中一台服务器中创建新表,在其他两台都能看见插入的信息

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值