MySQL主从复制(4)GTID主从复制与运维

tanglu 5082 2021-03-15

一、GTID特性介绍

MySQL 5.6开始支持GTID全局事务标识,在5.7之后即便没有配置GTID也会存在匿名事务,只不过这个匿名事务不包含GTID信息,不能用于主从复制GTID拥有全局唯一、幂等性,一个完整的GTID包含了UUID和GTID两部分,如下:

#对于来自同一个实例的事务,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

· UUID即Server_uuid,用于区分事务来自于集群中哪个节点,MySQL在启动的时候通过读取auto.cnf获取UUID,如果auto.cnf文件丢失则会自动生成新的UUID,但是UUID会发生变化

· GTID是每个事务的全局唯一编号,每当有事务导致数据变化,GTID末位的数字就会自增

· 每一个DDL都有一个GTID,对于DML语句,从begin开始到commit结束才算一个GTID


正因为全局唯一性,GTID也简化了主从复制的维护,配置主从不再需要手动指定Position信息,只需要告知从库当前从哪个GTID开始执行后面的事务即可。这个特点对于主从切换也更方便,配置GTID后不同节点binlog中的GTID是连续的,而传统模式下每个节点的binlog信息则会不同,一旦发生主从切换,由于从库记录的position信息是原主库的,而切换新主库后binlog信息是完全不一致,没办法直接指定正确的position。不过GTID也有一些缺点,就是故障处理较为复杂,对执行的SQL也有一定限制,比如不再支持create table ... select ...语句等。


二、GTID相关表与变量

· mysql.gtid_executed表:用于持久化存储GTID信息,数据库实例启动时会读取该表信息并赋值给gtid_executed变量。在MySQL 5.6时期是使用binlog中的GTID_LOG_EVENT来持久化GTID信息的,所以必须配置log_slave_updates=1

· gtid_executed变量:表示当前数据库执行过的GTID集合,gtid_executed变量一定是实时更新的。执行show master status或show slave status命令时Executed_Gtid_Set的值就来自于该变量

· gtid_purged变量:记录了因为binlog过期或人为原因被删除后所丢失的GTID信息。在部署从库的时候通常需要使用set global gtid_purged设置本变量,表示从库不需要再执行这些GTID包含的操作


三、GTID主从部署(GTID依赖于事务,所以MySQL必须配置为InnoDB引擎才可以

1、在所有节点新增GTID相关配置,MySQL 5.7开始支持在线配置GTID,无需重启服务。但是为了确保MySQL能正确处理从匿名事务更改为GTID事务的过程,gtid_mode的值只能按照顺序逐一提升或下降,如可以从OFF_PERMISSIVE逐步升级为ON_PERMISSIVE和OFF,但是不能直接调整为ON,关于GTID在线开启详见http://www.linuxe.cn/post-647.html

gtid_mode = on  #开启GTID
enforce_gtid_consistency = on  #强制GTID一致性,执行一些会导致GTID复制失败的语句会报错
# log_slave_updates = 1  #5.7开始可以通过gtid_executed表进行GTID持久化,所以可以不配置该参数,5.6则依赖binlog进行持久化,所以必须开启


2、主库进行授权操作

grant replication slave,replication client on *.* to 'repl'@'192.168.1.110' identified by '123456'


3、从库恢复主库的全备数据,恢复后需要指定gtid_purged变量信息,这个信息根据备份方式不同查找的路径会有一些不同。如果是mysqldump逻辑备份,在备份文件前50行会有gtid_purged变量,而xtrabackup物理备份的话则会写入到xtrabackup的备份文件中

show master status \G  #备份完成后通过该命令可以看到从节点和主节点GTID信息是一致的 
reset master;  #防止从库读取到错误的gtid_executed变量,执行该命令可以重置变量
set global gtid_purged='xxxxxxxxxx:1-21';


4、指定同步位点信息。由于采用了GTID,所以从库在指定position信息时只用声明从哪个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;


5、数据目录下的auto.cnf存放了当前数据库的UUID,每个节点的ID是不能一样的,如果一样会出现主从状态是2个yes,但是数据不同步的情况

show global variables like 'server_uuid' ;


6、主库执行show binlog event命令可以查看当前事务情况,SET开头的行是GTID,下面一行就是具体的SQL

GTID.png


7、在从库执行show slave status命令查看事务ID是否与主库一致,Retrieved_Gtid_Set表示从库已经接受到的GTID信息;Executed_Gtid_Set表示从库已经应用了的GTID信息

企业微信截图_20181010095354.png


8、采用了GTID复制后从库也会产生binlog日志,通过show master logs可以看到与主库是一致的。在从库执行show binlog event in 'master-bin.000001'命令可以查看当前所执行的事务ID位置,正常情况与主库也是一致的


四、GTID模式下数据恢复

1、如果在gtid模式下需要进行数据恢复,第一步也是从binlog找出正确的gtid信息然后导出

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、使用mysqlbinlog进行恢复的时候要注意,由于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、和传统主从不同,开启GTID后如果需要跳过一个事务不能再使用sql_slave_skip_counter参数,而是要获得从库执行的最后一个GTID操作。也就是show slave status 中的Retrieved_Gtid_Set信息。企业微信截图_20211008171159.png


2、构建一个或多个空事务

stop slave;
set gtid_next='xxxxxxxxxx3:3'
begin;
commit;
set gtid_next='xxxxxxxxxx3:4'
begin;
commit;
set gtid_next='automatic';
start slave;


· 当主服务器发生意外情况导致从库无法自动同步时的解决(如从库停机期间主库的二进制日志被删除,会导致从库无法找到需要的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;


· 如果从库忘了指定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;


· 如果主库忘了指定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主从复制(3)主从复制过滤配置与跨库更新
下一篇:MySQL主从复制(5)多源主从复制
相关文章

 发表评论

暂时没有评论,来抢沙发吧~

微信二维码