一,GTID概念
GTID (Global Transaction ID) 是对于一个已提交事务的编号,并且是一个全局唯一的编号。 GTID是由UUID+TID 组成的。其中UUID是一个 MySQL实例的唯一标识。TID代表了该实例上已经提交的事务数量,并且随着事务提交单调递增。
二,GTID的工作原理
- 当一个事务在主库端执行并提交时,产生GTID,一同记录到binlog日志中。
- binlog传输到slave,并存储到slave的relaylog后,读取这个GTID的这个值设置gtid_next变量,即告诉Slave,下一个要执行的GTID值。
- sql线程从relay log中获取GTID,然后对比slave端的binlog是否有该GTID。
- 如果有记录,说明该GTID的事务已经执行,slave会忽略。
- 如果没有记录,slave就会执行该GTID事务,并记录该GTID到自身的binlog,在读取执行事务前会先检查其他session持有该GTID,确保不被重复执行。
三,GTID在主从复制中如何工作
- master执行的每一个变更操作都生成一个gtid值,并且会把该值记录在binlog中用来主从复制,后续择机更新gtid_executed表记录
- 主从复制模式下,start slave后,从库会将自身执行过的gtid集合信息发送给主库,主库将从库未执行过的binlog信息发送给从库
- 从库读取relaylog中把该值设置为当前的gtid_next值,对具体的事务进行应用,择机更新gtid_executed表记录。期间主库不断的将新产生的binlog event发送至从库
从库应用主库的事务时不会生成新的gtid值,而是将读取的gtid_next的值记录在自己的binlog文件中。
四,相对于坐标位置,使用 GTID 配置复制时的优势
使用 GTID(全局事务标识符)可以唯一标识复制拓扑中的每个事务。
每个 GTID 的格式为 <source-uuid>:<transaction-id>,例如:
0ed18583-47fd-11e2-92f3-0019b944b7f7:338
使用 GTID 时,循环拓扑中的故障转移很简单:在发生故障的主服务器的从属服务器上,通过发出
单个 CHANGE MASTER TO 语句绕过该主服务器,每个服务器忽略或应用从拓扑中的其他服务器复制的事务。
五,GTID优点
- GTID相对于行复制数据安全性更高,故障切换更简单。
- 简单的实现 failover,不用以前那样在需要找 log_file 和 log_pos。
- 更简单的搭建主从复制,确保每个事务只会被执行一次。
- 比传统的复制更加安全,一个 GTID 在一个服务器上只执行一次,避免重复执行导致数据混乱或者主从不一致。
- GTID是连续的没有空洞的,保证数据的一致性,零丢失
- GTID 用来代替classic的复制方法,不再使用 binlog+pos 开启复制。而是使用master_auto_postion=1 的方式自动匹配 GTID 断点进行复制。
- GTID 的引入,让每一个事务在集群事务的海洋中有了秩序,使得 DBA 在运维中做集群变迁时更加方便
- 根据 GTID 可以快速的确定事务最初是在哪个实例上提交的。
六,GTID缺点
1)主从库的表存储引擎必须是一致的
- 主从库的表存储引擎不一致,就会导致数据不一致。如果主从库的存储引擎不一致,例如一个是事务存储引擎,一个是非事务存储引擎,则会导致事务和 GTID 之间一对一的关系被破坏,结果就会导致基于 GTID 的复制不能正确运行;
- master:对一个innodb表做一个多sql更新的事物,效果是产生一个GTID。
- slave:假设对应的表是MYISAM引擎,执行这个GTID的第一个语句后就会报错,因为非事务引擎一个sql就是一个事务。
2)不允许一个SQL同时更新一个事务引擎和非事务引擎的表
- 事务中混合多个存储引擎,就会产生多个 GTID。当使用 GTID 时,如果在同一个事务中,更新包括了非事务引擎(如 MyISAM)和事务引擎(如 InnoDB)表的操作,就会导致多个 GTID 分配给了同一个事务。
3)在一个复制组中,必须要求统一开启GTID或是关闭GTID;
4)不支持create table….select 语句复制(主库直接报错);
- create table xxx as select的语句,其实会被拆分为两部分,create语句和insert语句,但是如果想一次搞定,MySQL会抛出如下的错误。
- ERROR 1786 (HY000): Statement violates GTID consistency: CREATE TABLE ... SELECT.
- create table xxx as select 的方式可以拆分成两部分,如下:create table xxxx like data_mgr;insert into xxxx select *from data_mgr;
5)对于create temporary table 和 drop temporary table语句不支持;
- 使用GTID复制模式时,不支持create temporary table 和 drop temporary table。但是在autocommit=1的情况下可以创建临时表,Master端创建临时表不产生GTID信息,所以不会同步到slave,但是在删除临时表的时候会产生GTID会导致,主从中断.
6)不支持sal_slave_skip_counter.
- mysql在主从复制时如果要跳过报错,可以采取以下方式跳过SQL(event)组成的事务,但GTID不支持以下方式。set global SQL_SLAVE_SKIP_COUNTER=1;start slave sql_thread;