本文共 4414 字,大约阅读时间需要 14 分钟。
现网环境是M-M GTID+haproxy+组成的高可用需要做一个基于时间点的回档
之前的方法:
1 新建出另外一组M-M GTID高可用集群。我们将新的集群成为B,旧的集群称为A
2 分别导入A的历史备份到B集群的两个实例上,分开导入,导入期间双主同步不关,但会关闭sql_log_bin
3 分别导入A的增量binlog到B集群的两个实例上,分开导入,导入期间双主同步不关,但会关闭sql_log_bin
结果发现集群B并没有回档到预期的效果,有时B上的主节点丢失增量数据,有时B上的备用节点丢失增量数据
通过分析,发现是gtid复制引起的原因,即在B集群的主节点上执行A的增量binlog时,即使这时我们将sql_log_bin关闭了,但是依旧会产生一些binlog,发现这些binlog都是一些带A集群节点uuid的空事务,而这些空事务也会产生一个个的gtid传到B集群的备用节点;当B集群的备用节点执行增量binlog时,发现之前自己"似乎已经"执行过了,于是就跳过了这些增量操作,导致B几群的备用节点丢失这些增量数据
mysql> reset master;
Query OK, 0 rows affected (0.00 sec) mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 151 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) mysql> select * from xx; Empty set (0.00 sec) mysql> set sql_log_bin=0; Query OK, 0 rows affected (0.00 sec) mysql> insert into xx values(123); Query OK, 1 row affected (0.00 sec) mysql> select * from xx; +------+ | id | +------+ | 123 | +------+ 1 row in set (0.00 sec) mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 151 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)//可以发现当sql_log_bin关闭后,再执行简单的insert是不会产生binlog的
mysql> SET @@SESSION.GTID_NEXT='8356b68c-5cfb-11e7-b683-6c92bf2352b8:1'; Query OK, 0 rows affected (0.00 sec) mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> insert into xx values(234); Query OK, 1 row affected (0.00 sec) mysql> commit; Query OK, 0 rows affected (10.00 sec) mysql> SET @@SESSION.GTID_NEXT='AUTOMATIC'; Query OK, 0 rows affected (0.00 sec) mysql> show master status; +------------------+----------+--------------+------------------+----------------------------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+----------------------------------------+ | mysql-bin.000001 | 346 | | | 8356b68c-5cfb-11e7-b683-6c92bf2352b8:1 | +------------------+----------+--------------+------------------+----------------------------------------+ 1 row in set (0.00 sec)//可以发现当指定了另外一个uuid的gtid事务后,再insert记录时,产生了binlog
SET @@SESSION.GTID_NEXT= '8356b68c-5cfb-11e7-b683-6c92bf2352b8:1'/*!*/;
# at 199 #170704 17:22:29 server id 168410320 end_log_pos 272 CRC32 0x232648e0 Query thread_id=1524016 exec_time=0 error_code=0 SET TIMESTAMP=1499160149/*!*/; SET @@session.pseudo_thread_id=1524016/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=1073741824/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8 *//*!*/; SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/; SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; BEGIN /*!*/; # at 272 #170704 17:22:29 server id 168410320 end_log_pos 346 CRC32 0x5661cdc7 Query thread_id=1524016 exec_time=0 error_code=0 SET TIMESTAMP=1499160149/*!*/; COMMIT /*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;//解析了产生的binlog后发现,这些binlog实际都是空事务,也就是说把insert into xx values(234);这条sql过滤了,但是gtid信息却是不会过滤,记录了下来,而这些信息传到备库,肯定会影响上述恢复的逻辑,备库误以为这些gtid已经执行过了,遂不会再执行备库的增量binlog
sql_log_bin只是让SQL内容不在binlog里显示,但是gtid的信息并无法屏蔽,查看官网对该参数解释有点含糊不清
Setting this variable to 0 prevents GTIDs from being assigned to transactions in the binary log. If you
are using GTIDs for replication, this means that, even when binary logging is later enabled once again, the GTIDs written into the log from this point do not account for any transactions that occurred in the meantime—in effect, those transactions are lost.知道了原因,解决方法就非常多样了,最简单的方法,也就是上述代码量更改最小的,就是mysqlbinlog在解析增量部分的binlog时,加上
转载地址:http://gdbgb.baihongyu.com/