首页 > 代码库 > Mysql5.7基于GTID的半同步复制

Mysql5.7基于GTID的半同步复制

一、GTID是什么

GTID是事务的ID,唯一识别号,全局唯一。
随事务记录到Binary Log中,用来标识事务。
每个事务有一个Gtid_log_event。
GTID的构成:UUID + Sequence Number

Sequence Number是MySQL服务器内部的一个事务顺序号。一个MySQL服务器上的事务不会有重复的顺序号(保证服务器内唯一)。
每个MySQL服务器有一个全局唯一的UUID。


GTID的目的
简化复制的使用过程和降低复制集群维护的难度,不再依赖Master的binlog文件名和文件中的位置。
常规:CHANGE MASTER TO MASTER_LOG_FILE=‘Master-bin.000008’, MASTER_LOG_POS=‘216’;
使用GTID:CHANGE MASTER TO AUTO_POSITION=1;

AUTO_POSITION的原理
MySQL Server 记录了所有已经执行了的事务的GTID,包括复制过来的(可用过系统变量Gtid_executed查看)。
Slave记录了所有从master接收过来的事务的GTID(可通过Retrieve_gtid_set查看)。
Slave连接到Master时,会把gtid_executed中的gtid发给master,Master会自动跳过这些事务,只将没有复制的事物发送到Slave去。


GTID不支持的语句/事务
1.CREATE TABLE … SELECT

2.事务中同时使用了支持事务和不支持事务的引擎。
BEGIN;
INSERT INTO innodb_tbl(…);
INSERT INTO myisam_tbl(…);
COMMIT;

3.在事务中使用CREATE/DROP TEMPORARY TABLE
BEGIN;
INSERT INTO innodb_tbl(…);
CREATE TEMPORARY TABLE temp1;
...
COMMIT;


注意:启用GTID前,请检测业务系统中是否有GTID不支持的语句/事务,提前处理。


启用GTID

SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE; (在每一个服务器上设置)
SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE; (在每一个服务器上设置)
SET @@GLOBAL.GTID_MODE = ON; (在每一个服务器上设置)


二、无数据丢失的半同步复制

从MySQL5.5开始,MySQL以插件的形式支持半同步复制。如何理解半同步呢?首先我们来看看异步,全同步的概念。


异步复制(Asynchronous replication)

MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即返回给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主库如果crash掉了,此时主库上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主库上的数据不完整。


全同步复制(Fully synchronous replication)
指当主库执行一个事务,等所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能commit,所以全同步复制的性能必然会收到严重的影响。

半同步复制(Semisynchronous replication)
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。


半同步复制的潜在问题

客户端事务在存储引擎层提交后,在得到从库确认的过程中,主库宕机了,此时,可能的情况有两种:

1.事务还没发送到从库上

此时,客户端会收到事务提交失败的信息,客户端会重新提交该事务到新的主上,当宕机的主库重新启动后,以从库的身份重新加入到该主从结构中,会发现,该事务在从库中被提交了两次,一次是之前作为主的时候,一次是被新主同步过来的。

2.事务已经发送到从库上

此时,从库已经收到并应用了该事务,但是客户端仍然会收到事务提交失败的信息,重新提交该事务到新的主上。

无数据丢失的半同步复制

针对上述潜在问题,MySQL 5.7引入了一种新的半同步方案:Loss-Less半同步复制。



当然,之前的半同步方案同样支持,MySQL 5.7引入了一个新的参数进行控制-rpl_semi_sync_master_wait_point

rpl_semi_sync_master_wait_point有两种取值:

AFTER_SYNC:这个即新的半同步方案,Waiting Slave dump在Storage Commit之前。
AFTER_COMMIT:老的半同步方案


三、无数据丢失的半同步复制的部署

--安装前提
1、MySQL5.5 版本或更高
2、主、从库的 have_dynamic_loading 系统变量值为 yes
3、主、从异步复制已部署


在主库安装 rpl_semi_sync_master 插件

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


查看插件是否加载成功
有两种方式
1.
mysql> show plugins;

| rpl_semi_sync_master       | ACTIVE   | REPLICATION        | semisync_master.so | GPL     |

2.

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.00 sec)


mysql> show variables like ‘%rpl%‘;
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | OFF        |
| 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 |
| rpl_stop_slave_timeout                    | 31536000   |
+-------------------------------------------+------------+
7 rows in set (0.00 sec)


主库增加以下配置:

[mysqld]
#For GTID Replication
server_id=18
gtid_mode=on
enforce_gtid_consistency=on
#For Semi Sync config
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=3000  # 3 second
#For binlog
log_bin=master-binlog
binlog_format=row
log_slave_updates=1


在从库安装 rpl_semi_sync_slave 插件

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

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


从库增加以下配置:

[mysqld]
#For GTID Replication
server_id=19
gtid_mode=on
enforce_gtid_consistency=on
#For binlog
log_bin=master-binlog
binlog_format=row
log_slave_updates=1
#For as slave. Please mark it if switch to master.
read_only=1
skip_slave_start=1
relay_log_recovery=1
##For Semi Sync config
rpl_semi_sync_slave_enabled=1


启动半同步复制

在安装完插件后,半同步复制默认是关闭的,上面已经将半同步的参数配置好了,可以重启mysql即可,也可以不重启mysql,手动设置参数来使之生效:
主:
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;

从:
mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;

重启Slave上的IO线程
mysql> STOP SLAVE IO_THREAD;
mysql> START SLAVE IO_THREAD;

如果没有重启,则默认还是异步复制,重启后,slave会在master上注册为半同步复制的slave角色。

在master上的error.log中会有以下信息:

2017-02-07T07:42:06.941095Z 21 [Note] Start binlog_dump to master_thread_id(21) slave_server(19), pos(, 4)
2017-02-07T07:42:06.941124Z 21 [Note] Start semi-sync binlog_dump to slave (server_id: 19), pos(, 4)


查看半同步是否在运行
主:
mysql> show status like ‘Rpl_semi_sync_master_status‘;
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON    |
+-----------------------------+-------+
1 row in set (0.00 sec)


从:
mysql> show status like ‘Rpl_semi_sync_slave_status‘;
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)


这两个变量常用来监控主从是否运行在半同步复制模式下。


当半同步复制发生超时时(由rpl_semi_sync_master_timeout参数控制,单位是毫秒,默认为10000,即10s),会暂时关闭半同步复制,转而使用异步复制。当master dump线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为半同步复制。


查看半同步复制的状态

mysql> show status like ‘%Rpl_semi%‘;

本文出自 “June我行” 博客,请务必保留此出处http://junewx.blog.51cto.com/12554494/1895712

Mysql5.7基于GTID的半同步复制