一、什么是GTID
MySQL 5.6开始支持GTID特性,即全局事务标识。GTID是全局唯一且具有幂等性的,每当有事务导致数据变化,GTID末位的数字就会自增,也就是说每个事务都有一个全局唯一的编号。从5.7版本开始即便不配置GTID也会存在匿名事务,只不过这个匿名事务不包含GTID信息,不能用于复制。
在MySQL中每个DDL都会有一个GTID,而DML则是从begin开始到commit才算一个GTID。GTID由UUID+GTID共同组成,UUID即MySQL variables中的Server_uuid,用于区分事务来自于哪个节点。
mysql > show variables like '%uuid%';
MySQL在启动的时候会读取auto.cnf获取到UUID,如果auto.cnf文件丢失则会自动生成新的UUID,但是UUID会发生变化。对于来自同一个实例的事务,GTID可以合并表达,比如:
#来自同一个实例的1-3个事务
2a09ee6e-645d-11e7-a96c-000c2953a1cb:1-3
#来自同一个实例的1-3个事务,第11个事务,第48-51个事务
2a09ee6e-645d-11e7-a96c-000c2953a1cb:1-3,11,48-51
正因为全局唯一性,GTID也简化了主从复制的维护,配置主从不再需要手动指定Position信息,只需要告知从库当前从哪个GTID开始执行后面的事务即可。这个特点对于主从切换也更方便,配置GTID后不同的binlog文件中的GTID是连续的,而在传统模式下每个节点的binlog信息则会不同,这样发生主从切换的话,由于从库记录的position信息是原主库的,而切换新主库后binlog信息是完全不一致,没办法直接指定正确的position。
二、GTID主从部署(GTID依赖于事务,所以MySQL必须配置为InnoDB引擎才可以)
1、在所有节点新增GTID相关配置,MySQL 5.7开始支持在线配置GTID,无需重启服务。
gtid_mode = on #开启GTID
enforce_gtid_consistency = on #强制GTID一致性,执行一些会导致GTID复制失败的语句会报错
# log_slave_updates = 1 #5.7开始可以通过gtid_executed表进行GTID持久化,所以可以不配置该参数,5.6则依赖binlog进行持久化,所以必须开启
在MySQL 5.7中对gtid_mode的值增加了OFF_PERMISSIVE和ON_PERMISSIVE,为了确保MySQL能正确处理从匿名事务更改为GTID事务的过程,gtid_mode的值只能按照顺序逐一提升或下降,比如可以从OFF_PERMISSIVE升级为ON_PERMISSIVE和OFF,但是不能直接调整为ON。
2、主库进行授权操作
grant replication slave,replication client on *.* to 'repl'@'192.168.1.110' identified by '123456'
3、从库在指定主库信息时不再需要position,而是根据GTID去自动判断哪些操作需要同步。主库的position信息会自动写到从库数据目录下的master.info文件中
#如果是做的物理备份,拷贝到只是物理文件,不包含binlog,所以还需要执行SET GLOBAL GTID_PURGED语句指定与备份数据一致的GTID位置,否则可能会出错
change master to master_host='192.168.1.100',master_port=3306,master_user='repl',master_password='123456',master_auto_position=1;
start slave;
4、数据目录下的auto.cnf存放了当前数据库的UUID,每个节点的ID是不能一样的,如果一样会出现主从状态是2个yes,但是数据不同步的情况)
show global variables like 'server_uuid' ;
5、主库执行show binlog event命令可以查看当前事务情况,SET开头的行是GTID,下面一行就是具体的SQL

6、在从库执行show slave status命令查看事务ID是否与主库一致,如果Executed_Gtid_Set出现了2个,那么第一个是当前GTID,第二个是同步到的GTID。

7、采用了GTID复制后从库也会产生binlog日志,通过show master logs可以看到与主库是一致的。在从库执行show binlog event in 'master-bin.000001'命令可以查看当前所执行的事务ID位置,正常情况与主库也是一致的
三、使用GTID进行数据恢复
1、如果在gtid模式下需要进行数据恢复,第一步也是从binlog找出正确的位置信息,然后导出
mysqlbinlog --include-gtids='yourgtid:1-100' mysql-bin.00001 mysql-bin.00002 mysql-bin.00003 mysql-bin.00004 > /tmp/gtid.sql #假设101的GTID为drop table,就截取到100即可
#还有--exclude-gtids选项用于排除某个GTID
2、由于GTID有幂等性,相同的GTID不会再次执行,所以恢复的时候要手动关闭GTID检查,或者在mysqlbinlog中加入--skip-gtids的选项,它会将重定向文件中的GTID信息删除掉
#方法1
mysqlbinlog --skip-gtids include-gtids='xxxxxxxxxxx:1-100' mysql-bin.00001 mysql-bin.00002 > /tmp/gtid.sql
#方法2
mysql > set sql_log_bin = 0 ;
mysql > source gtid.sql;
四、GTID主从复制发生异常如何处理
1、当主服务器发生意外情况导致从库无法自动同步时的解决(如从库停机期间主库的二进制日志被删除,会导致从库无法找到需要的ID):
#在从库上手动指定二进制日志文件和位置
mysql > stop slave;
mysql > change master to master_host='192.168.1.100',master_user='repl',master_password='123456',master_log_file='master-bin.000005',master_log_pos=526,master_auto_position=0;
mysql > start slave;
2、如果从库忘了指定relay-log而又发生了主机名更改的情况,只需要在从库重新执行一次同步
stop slave;
reset slave;
change master to master_host='192.168.1.100',master_port=3306,master_user='repl',master_password='123456',master_auto_position=1;
3、如果主库忘了指定bin-log而又发生了主机名更改的情况,从库会报错“Slave has more GTIDs than the master has,using the master's SERVER_UUID”,意思就是说自己的GTID比主库的更大了。解决方法(所有命令在从库执行):
stop slave;
reset slave;
reset master; #从库的binlog已经无效了,所以要执行这个命令清空binlog
change master to master_host='192.168.1.100',master_port=3306,master_user='repl',master_password='123456',master_auto_position=1;
本文详细介绍了MySQL的全局事务标识符(GTID)特性,包括其作用、工作原理以及如何在主从复制中使用。GTID简化了主从配置,允许在不同节点间轻松切换。同时,文章提供了GTID模式下的数据恢复步骤,并讨论了主从复制遇到异常时的处理方法。
874

被折叠的 条评论
为什么被折叠?



