
//
GTID复制模式Executed_Gtid_Set太多咋整?
//
今天下午,在测试环境搭建一个双主的时候碰到了这个问题,问题描述如下:
环境A:192.168.10.187 主库
环境B:192.168.10.186 从库
在从库B上使用show slave status看到如下结果:
mysql--dba_admin@127.0.0.1:(none) 15:58:26>>show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.10.187
Master_User: dba_repl
Master_Port: 4306
Connect_Retry: 60
Master_Log_File: mysqlbin.000012
Read_Master_Log_Pos: 534903212
Relay_Log_File: slave-relay-bin.000002
Relay_Log_Pos: 534888629
Relay_Master_Log_File: mysqlbin.000012
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
......
Retrieved_Gtid_Set: 1f7133df-aa0b-11e9-af7d-005056b7a90a:6346314-8157448
Executed_Gtid_Set: 059aab73-bd7e-11e9-9f2e-005056b7360f:785014722-785915551,
1f7133df-aa0b-11e9-af7d-005056b7a90a:1-8157448,
bca9ac2e-aa0a-11e9-ac0c-005056b71124:1-6306
Auto_Position: 0
复制状态是双Yes,但是可以看到Executed_Gtid_Set的值有三个,分别是059xxx、1f7xxx、bcaxxx,这和我们通过show master status查看的结果相同:
mysql--dba_admin@127.0.0.1:(none) 15:58:34>>show master status\G
*************************** 1. row ***************************
File: mysqlbin.000002
Position: 528858722
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 059aab73-bd7e-11e9-9f2e-005056b7360f:785014722-785915551,
1f7133df-aa0b-11e9-af7d-005056b7a90a:1-8157448,
bca9ac2e-aa0a-11e9-ac0c-005056b71124:1-6306
1 row in set (0.00 sec)
再来在主库上通过show master status来查看主库上的Executed_gtid_set,发现主库上也有3个Gtid。多个GTID值产生的原因,可能是该测试库曾经是其他库的从库,后面主从复制关系被改变过,但是没有对GTID的值进行清理。多个GTID值看着很不清晰,也可能会影响双主模式的搭建。
至此,问题总结如下:
1、从库Executed_gtid_set有多个值
2、主库Executed_gtid_set也有多个值
01
问题一
首先来看问题1,解决方案也比较简单:
a、查看主库A上的uuid,发现是1f7xxx
b、
在从库上操作:
第一步、stop slave;
并记录对应的Executed_Gtid_Set值:1f7133df-aa0b-11e9-af7d-005056b7a90a:1-8157448
第二步、show master status\G
查看对应Executed_Gtid_Set值是否和上面保持一致,一般情况下是一致的。
第三步:reset master;
重置从库上的binlog,该操作会清空从库上的mysql.gtid_executed表中的内容
第四步:set global gtid_purged='1f7133df-aa0b-11e9-af7d-005056b7a90a:1-8157448';
重置从库的gtid_purged的值
第五步:start slave; 重启复制关系
第六步:show slave status\G 查看最终结果
Master_SSL_Crlpath:
Retrieved_Gtid_Set: f7133df-aa0b-11e9-af7d-005056b7a90a:6346314-8157502
Executed_Gtid_Set: f7133df-aa0b-11e9-af7d-005056b7a90a:1-8157502
Auto_Position:
可以发现,从库B上通过以上6个步骤的操作,最终的Executed_gtid_set已经变为一个了。它的UUID是主库A的UUID。
注意,此时:
从库B的GTID已经变成1个,
1f7xxx
但是主库A的GTID值还是有3个。
059xxx
1f7xxx
bcaxxx
02
问题2
主库A上的多个gtid值怎么解决呢?换句话说,多个GTID的值是否会影响双主模式的搭建?我先简单的做了个测试,直接在原主库上执行:
change master to master_host='192.168.10.186',
master_user='dba_repl',
master_password='xxxxxxx',
master_port=,
master_auto_position=;
然后,start slave;发现报错了,报错信息如下:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 1236
Last_IO_Error: Got fatal error 1236 from master when reading data
from binary log: 'Slave has more GTIDs than the master has, using the master's
SERVER_UUID. This may indicate that the end of the binary log was truncated or
that the last binary log file was lost, e.g., after a power or disk failure when
sync_binlog != 1. The master may or may not have rolled back transactions that
were already replica'
Last_SQL_Errno: 0
Last_SQL_Error:
其中有一句比较点睛:slave has more GTIDs than the master has.
一开始对这句话理解有误,以为是原主节点A的GTID个数(3个)比原从节点B多,后面查询官方文档,发现这句话其实表明的意思是,原主节点A有些GTID比原来的从节点B新。所以导致复制创建失败。
这个时候再来查看原主节点A上的Executed_gtid_set的3个GTID值分别是啥:
059xxx、(主节点A有,从节点B没有)
1f7xxx、(主节点A自己的UUID,因为主从复制关系,两边一致)
bcaxxx、(从节点的UUID,主节点A有,从节点B没有)
这里,问题可能就比较明显了,就是说我们的主节点A上有bcaxxx这个GTID的值,这个值取的是从节点B的uuid,但是从节点B上又没有这个GTID,只有个1f7的GTID值。
所以,怎么让从节点B上有这个值?
我在从节点B上执行了一个SQL,create database testdb;
mysql--dba_admin@127.0.0.1:(none) 16:10:36>>show master status\G
*************************** 1. row ***************************
File: mysqlbin.000001
Position: 147322
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 1f7133df-aa0b-11e9-af7d-005056b7a90a:1-8157976
1 row in set (0.00 sec)
mysql--dba_admin@127.0.0.1:(none) 16:16:23>>create database testdb;
Query OK, row affected (0.00 sec)
mysql--dba_admin@127.0.0.1:(none) 16:16:31>>show master status\G
*************************** 1. row ***************************
File: mysqlbin.000001
Position:
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: f7133df-aa0b-11e9-af7d-005056b7a90a:1-8157988,
bca9ac2e-aa0a-11e9-ac0c-005056b71124:
row in set (0.00 sec)
可以发现,执行完create 语句之后,从节点B上已经有了这个GTID的值,但是它并没有同步到主节点A上,因为反向复制关系还没有建立起来。
此时,查看主节点A上的的bca的具体值,发现是:
bcaxxx:1-6304
而从节点B上的值是:
bcaxxx:1
这样,只需要将从节点B上的值改成bcaxxx:1-6304,此时搭建反向复制关系就一定能成功。
在从节点B上进行操作:
mysql 16:25:03>>stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql 16:25:12>>reset master;
Query OK, 0 rows affected (0.00 sec)
mysql 16:25:17>>set global gtid_purged='1f7133df-aa0b-11e9-af7d-005056b7a90a:1-8158243,bca9ac2e-aa0a-11e9-ac0c-005056b71124:1-6304';
Query OK, 0 rows affected (0.00 sec)
mysql 16:25:48>>start slave ;
Query OK, 0 rows affected (0.01 sec)
操作完毕之后,此时主从库的gtid值变为:
主库A
059xxx
1f7xxx
bcaxxx
从库B,此时有两个了。
1f7xxx(和A保持一致)
bcaxxx(和A保持一致)
再次搭建主节点A到从节点B的反向复制关系:
mysql 16:30:03>>change master to master_host='192.168.10.186',
-> master_user='dba_repl',
-> master_password='xxxxxxx',
-> master_port=,
-> master_auto_position=;
Query OK, 0 rows affected, 1 warning (0.02 sec)
mysql 16:30:05>>start slave ;
Query OK, 0 rows affected (0.04 sec)
mysql 16:30:10>>show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.10.186
Master_User: dba_repl
Master_Port:
Connect_Retry:
Master_Log_File: mysqlbin.000001
Read_Master_Log_Pos:
Relay_Log_File: slave-relay-bin.000002
Relay_Log_Pos:
Relay_Master_Log_File: mysqlbin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
发现搭建成功。
在原来的从节点B上执行命令create database,发现主从节点上的gtid值都有相应增加:
从
bca9ac2e-aa0a-11e9-ac0c-005056b71124:1-6304
变为:
bca9ac2e-aa0a-11e9-ac0c-005056b71124:1-6305
至此,双向复制关系搭建成功。
总结与思考:
遇到多个GTID值的情况:
1、先解决从库上的问题。
从库上stop slave ,记录当前的gtid_executed_set中uuid为主库的那个值,然后reset master,接着set gtid_purged值为上述保存值,最后重新change master即可。
2、不要在主库上使用reset master的方法,这个方法会抛弃掉主库的所有binlog,导致主从复制失败。
3、主库上搭建反向复制的时候,需要在从库上补充uuid为从库的gtid值,还是使用set gtid_purged
的方法,保证这个值和主库上的值一致,否则反向复制搭建的时候回报错。