设为首页 收藏本站
查看: 1590|回复: 0

[经验分享] Mysql5.7基于GTID的半同步复制

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2017-2-8 13:10:47 | 显示全部楼层 |阅读模式
一、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半同步复制。

QQ截图20170208131016.png

当然,之前的半同步方案同样支持,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%';


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-339374-1-1.html 上篇帖子: Warning: Skipping the data of table mysql.event. Specify the --events option ... 下篇帖子: MySQL水平分割案例
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表