首页 > 代码库 > 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的半同步复制