一、GTID概述

GTID是MYSQL5.6新增的特性,GTID(Global Transaction Identifier)全称为全局事务标示符,用以数据库实例事务唯一标识,其组成主要是source_id和transaction_id 即GTID = source_id:transaction_id。其中source_id是数据库启动自动生成的数据库实例唯一标识,保存在auto.cnf中,而transaction_id则是事务执行的序列号。

什么是GTID
GTID(Global Transaction)全局事务标识符:是一个唯一的标识符,它创建并与源服务器(主)上提交的每个事务相关联。此标识符不仅对其发起的服务器是唯一的,而且在给定复制设置中的所有服务器上都是唯一的。所有交易和所有GTID之间都有1对1的映射。
GTID实际上是由UUID+TID组成的。其中UUID是一个MySQL实例的唯一标识。TID代表了该实例上已经提交的事务数量,并且随着事务提交单调递增。
下面是一个GTID的具体形式:
3E11FA47-71CA-11E1-9E33-C80AA9429562:23

二、GTID优缺点

优点:
复制安全性更高,一个事务在每个实例上只执行一次;
故障切换简单,可通过设置MASTER_AUTO_POSITION=1,而非master_log_file和master_log_pos来建立主从关系;
可根据GTID确定事务最早提交的实例;
缺点:
组复制中,必须要求统一开启GTID或者关闭GTID;
不支持复制create table table_name select … from table_name_xx ;
不支持create temporary table和drop temporary table;
不支持sql_slave_skip_counter,可通过set global gtid_next=’’ 跳过;
从库和主库都必须设置log_slave_updates

GTID的新特性
(1)支持多线程复制:事实上是针对每个database开启相应的独立线程,即每个库有一个单独的(sql thread)
(2)支持启用GTID,在配置主从复制,传统的方式里,你需要找到binlog和POS点,然后change master to 指向。在mysql5.6里,无须再知道binlog和POS点,只需要知道master的IP/端口/账号密码即可,因为同步复制是自动的,MySQL通过内部机制GTID自动找点同步。
(3)基于Row复制只保存改变的列,大大节省磁盘空间,网络,内存等
(4)支持把Master和Slave的相关信息记录在Table中;原来是记录在文件里,现在则记录在表里,增强可用性
(5)支持延迟复制

三、GTID工作原理

1、master更新数据时,会在事务前产生GTID,一同记录到binlog日志中。
2、slave端的i/o 线程将变更的binlog,写入到本地的relay log中。
3、sql线程从relay log中获取GTID,然后对比slave端的binlog是否有记录。
4、如果有记录,说明该GTID的事务已经执行,slave会忽略。
5、如果没有记录,slave就会从relay log中执行该GTID的事务,并记录到binlog。
6、在解析过程中会判断是否有主键,如果没有就用二级索引,如果没有就用全部扫描。

四、GTID开启和关闭

gtid_mode=ON(必选)
log_bin=ON(必选)
log-slave-updates=ON(必选)
enforce-gtid-consistency=ON(必选) #强制gtid一致性,开启后对于特定create table不被支持
log-bin = /home/mysql/mysql-bin(必选)
binlog_format = MIXED(必选mixed或者row) #强烈建议,其他格式可能造成数据不一致
image.png
image.png
##
change master to master_host = ‘ipaddr’,master_port = 3306,master_user = ‘username’,master_password=’password’,master_auto_position = 1;

change master to master_host=’192.168.0.111’,master_password=’999999’,master_port=3306,master_user=’rep’,master_auto_position=1;

mysql> change master to \
-> master_host=’192.168.0.111’,\ #主库IP
-> master_user=’rep’,\ #主库复制用户
-> master_password=’999999’,\ #主库复制用密码
-> master_auto_position=1; #GTID位置点(自动追踪需要同步的position)

image.png

mysql> show variables like “%gtid%”; #查看gtid开关状态
mysql> show variables like ‘%gtid_next%’;
默认是不开启的
image.png
验证查看
image.png
image.png


常用参数的作用:
a) gtid_executed
在当前实例上执行过的 GTID 集合,实际上包含了所有记录到 binlog 中的事务。设置 set sql_log_bin=0 后执行的事务不会生成 binlog 事件,也不会被记录到 gtid_executed 中。执行 RESET MASTER 可以将该变量置空。
b) gtid_purged
binlog 不可能永远驻留在服务上,需要定期进行清理(通过版本5.7 expire_logs_days ,Mysql8.0 参数binlog_expire_logs_seconds 可以控制定期清理间隔),否则迟早它会把磁盘用尽。
gtid_purged 用于记录本机上已经执行过,但是已经被清除了的 binlog 事务集合。它是 gtid_executed 的子集。只有 gtid_executed 为空时才能手动设置该变量,此时会同时更新 gtid_executed 为和 gtid_purged 相同的值。
gtid_executed 为空意味着要么之前没有启动过基于 GTID 的复制,要么执行过 RESET MASTER。执行 RESET MASTER 时同样也会把 gtid_purged 置空,即始终保持 gtid_purged 是 gtid_executed 的子集。
c) gtid_next
会话级变量,指示如何产生下一个GTID。可能的取值如下:
第一个:AUTOMATIC
自动生成下一个 GTID,实现上是分配一个当前实例上尚未执行过的序号最小的 GTID。
第二个:ANONYMOUS
设置后执行事务不会产生GTID。
第三个:显式指定的GTID
可以指定任意形式合法的 GTID 值,但不能是当前 gtid_executed 中的已经包含的 GTID,否则下次执行事务时会报错。

五、GTID适用场景

1、搭建高可用架构,方便主从切换后,新的从库重新指定主库(例如一主二从的结构,A为mater,B为Slave,C为Slave,A宕机切换到B后,C重新指定主库为B)
2、不经常使用create table table_name select * from table_name/create temporary table/update t1,t2 where …这种语句的场合

六、GTID相关参数

参数 comment
gtid_executed 执行过的所有GTID,可通过reset master重置
gtid_purged 丢弃掉的GTID,设置后从而导致slave不会再去master请求这些GTIDs,并且Executed_Gtid_Set为空时,才可以设置此值
gtid_mode gtid模式
gtid_next session级别的变量,下一个gtid
gtid_owned 正在运行的gtid
enforce_gtid_consistency 保证GTID安全的参数