重置master导致主从GTID不一致怎么办?

分类:编程技术 时间:2024-02-20 15:48 浏览:0 评论:0
0
本文将详细讲解如果由于reset master导致主从GTID不一致怎么办。小编觉得还是比较实用的,所以分享给大家,作为参考。希望您读完本文后有所收获。

1.主库报同步异常(主从复制是双向的),错误信息显示insert语句的目标表不存在
2.查看主从库的GTID信息,发现主库的GTID比从库的GTID高(应该是从库执行了重置主操作,重置了GTID),导致部分事务被跳过,导致错误。这里跳过的是建表语句。
3.处理方法是将从库的GTID推送到主库级别,从而消除冲突,保证从库的所有事务都可以在主库中执行。
4.第二天查看,发现还是有部分事务被自动跳过,而且被跳过的语句都是创建临时表的语句。根据文档说明,临时表的创建操作不会同步到备库执行,临时表的相关操作事务也会被空事务替换。

以下是详细的处理过程:
有一个主库,最近同步从库信息时经常报错。跳过相应的交易后,第二天仍然出现同样的问题。错误如下:
Last_Error: 查询时出现错误“表‘mysql.ibbackup_binlog_marker’不存在’”。默认数据库:“mysql”。查询:'INSERT INTO ibbackup_binlog_marker VALUES(1)'

其中一条详细信息如下:
mysql> show Slave status \G
**************************** 1. 行 *** ********* ******************


Relay_master_log_file:MySQL-BIN.000134
Slave_io_Running:是
                      Last_Errno : 1146
                      Last_Error: 查询时出现错误“表‘mysql.ibbackup_binlog_marker’不存在”。默认数据库:“mysql”。查询:“插入 ibbackup_binlog_marker VALUES(1)”
                   Skip_Counter: 0
          Exec_Master_Log_Pos: 1534712
                Relay_Log_Space: 8079
              Last_SQL_Errno: 1146
                 Last_SQL_Error: 错误“表”mysql查询时.ibbackup_binlog_marker“不存在”。默认数据库:“mysql”。查询:“插入 ibbackup_binlog_marker VALUES(1)”
Replicate_Ignore_Server_Ids:
Master_Server_Id:3809805896
; d3c576-ca26-11e3-a90a-a0369f38458a:28-1420 11e3-a8a1-a0369f35d966:1-160657756,
44d3c576-ca26-11e3-a90a-a0369f38458a:1-5: 7-19:21-1294:1296 -1307:1309-1320:1322-1333:1335-1346:1348-1359:1361-1372:1374-1412:1414-1425:1427-1438:1440-1451:1453-1464:1466-1478:1480-1491:1493-1504:1506-1517 :1519 -1 530:1532-1543:1545-1556:1558-1570:1572-1583:1585-1596:1598-1609:1611-1622:1624-1635:1637-1648:1650-1662:1664-1675:1677 - 1688:1 690- 1701:1703-1714:1716-1727:1729-1740:1742-1754:1756-1767:1769-1780:1782-1793:1795-1806:1808-1819:1821-1832:1834 -1846 :1848-1 859: 1861-1872: 1874-1885: 1887-1898: 1900-1911: 1913-1924: 1926-1938: 1940-1951: 1953-1964: 1966-1977: 1979-1990 : 1992-2003: 2005-2016:2023-2030:2032-2043:2045-2056:2058-2069:2071-2082:2084-2095:2097-2108:2110-2122:2124-2135:2137-2148:2150-2161: 2163- 2174:21 76- 2187:2189-2200:2202-2214:2216-2227:2229-2240:2242-2253:2255-2266:2268-2279:2281-2292:2294-2306:2308-2319:2321 -2332 :2334-2 345:2347-2358:2360-2371:2373-2384:2386-2398:2400-2411:2413-2424:2426-2437:2439-2450:2452-2463:2465-2476:2478-249 0: 2492-2503:2 505- 2516:2518-2529:2531-2542:2544-2555:2557-2568:2570-2582:2584-2595:2597-2608:2610-2621:2623-2634

报错是insert语句,但没有找到目标表。这条语句在从库的mysql-bin.000134日志中,Exec_Master_Log_Pos为1534712。

于是去从库查看对应的binlog。在对应位置可以看到insert语句的GTID为xxx:1413,而insert语句之前是建表语句,对应的GTID为1412:
# at 1534324
#160301 0 :21:00 服务器 ID 3809805896 end_log_pos 1534372 CRC32 0x9cf47996 GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '44d3c576-ca26-11e3- a90a-a0369f38458a :1411'/*!*/ ;
# 在 1534372
#160301 0:21:00 服务器 id 3809805896 end_log_pos 1534519 CRC32 0x0e9481da 查询 thread_id=947514 exec_time=0 error_code=0
SET TIMESTAMP=1456762860/*!*/;
DROP TABLE IF EXISTS `ibbackup_binlog_marker` /* 由服务器生成 */
/*!* /;
# at 1534519
#160301 0:21:00 服务器 id 3809805896 end_log_pos 1534567 CRC32 0xd09025a2 GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '44d3c576-ca26 -11e3 -a90a-a0369f38458a:1412'/*!*/;
# at 1534567
#160301 0:21:00 服务器 id 3809805896 end_log_pos 1534712 CRC32 0x04118941 查询 thread_id=94 7514 exec_time=0 error_code=0
SET TIMESTAMP=1456762860/*!*/;
SET @@session.pseudo_thread_id=94751 4/ *!*/;
创建临时表 ibbackup_binlog_marker (a INT) ENGINE = INNODB
/ *!*/;
# at 1534712
#160301 0:21:00 服务器 ID 3809805896 end_log_pos 1534760 CRC32 0x70ca2249 GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '44d3c576-ca26-11e3-a90a-a0369f38458a:1413'/*!*/;
# 在 1534 760
/>#160301 0:21:00 服务器 id 3809805896 end_log_pos 1534841 CRC32 0x5dad49 1c 查询 thread_id=947514 exec_time=0 error_code=0
SET TIMESTAMP=1456762860/*!*/;
BEGIN
/*!*/;
# at 1534841
#160301 0:21:00 服务器 id 3809805896 end_log_pos 1534961 CRC32 0xb5f7ab48 查询 thread_id=947514 exec_time=0 error_code=0
SET TIMESTAMP=1456762860/ *!*/;
插入INTO ibupup_bin log_marker VALUES(1)
/*!* /;
# at 1534961
#160301 0:21:00 server id 3809805896 end_log_pos 1535035 CRC32 0x9baea0da 查询 thread_id=947514 exec_time=0 error_code =0
SET TIMESTAMP=1456762860/*!*/ ;
COMMIT
/*!*/;

查看主relaylog时即可发送图书馆。这些交易已经成功同步并且没有丢失。那么为什么会提示该表不存在呢?建表语句不执行有什么原因吗?

我们先看一下master数据库的GTID。从库同步的最大执行事务数为7383:
************************ ******** 1. row **************************
变量名称:enforce_gtid_consistency
值:ON
***** ********************** 2. 行 ************** ********** ***
变量名称:gtid_execulated
值:258cacac-ca16-11e3-a8a1-a0369f35d966:1-160665110,
44d3c576-ca26-11e3-a90a-a0369f38458a:1-5:7-19:21-1294:1296-1307:1309-1320:1322-1333:1335-1346:1348-1359:1361-1372:1374-1412:1414-1425:1427- 1438:1440-1451:1453-1464:1466-1478:1480-1491:1493-1504:1506-1517:1519-1530:1532-1543:1545-1556:1558-1570:1572-1583:1585-1第596章:1598-1609:1611-1622:1624-1635:1637-1648:1650-1662:1664-1675:1677-1688:1690-1701:1703-1714:1716-1727:1729-1740:1742-1754 :1 756- 1767:1769-1780:1782-1793:1795-1806:1808-1819:1821-1832:1834-1846:1848-1859:1861-1872:1874-1885:1887-1898:1900-1911:1 913- 1 924:1926-1938:1940-1951:1953-1964:1966-1977:1979-1990:1992-2003:2005-2016:2023-2030:2032-2043:2045-2056:2058-2069:2071 -2082 :2084-2095:2097-2108:2110-2122:2124-2135:2137-2148:2150-2161:2163-2174:2176-2187:2189-2200:2202-2214:2216-2227:2229-224 0:2242 -2253:2255-2266:2268-2279:2281-2292:2294-2306:2308-2319:2321-2332:2334-2345:2347-2358:2360-2371:2 373-2384:2386-2398:2400 - 2411:2413-2424:2426-2437:2439-2450:2452-2463:2465-2476:2478-2490:2492-2503:2505-2516:2518-7383:


看着 sl再次查看数据库,发现最大数量只有1420!
************************************ 1. 行 ************* ***** *************
变量名称:enforce_gtid_consistency
值:ON
**************** ********** ****** 2.行 **************************
Variable_name:gtid_execulated
值:258cacac -ca16-11e3-a8a1-a0369f35d966:109528488-160665725,
44d3c576-ca26-11e3-a90a-a0369f38458a:1-1420

问题就是:为什么从库的GTID比主库大?图书馆有多小?应该是有同学对从库进行了reset master操作,重置了GTID导致的!

我们知道,备库应用主库的日志时,会检查GTID来判断对应的事务是否已经执行。如果备库中已经记录了对应的GTID,则说明对应的事务已经执行完毕,不n需要再次被执行。否则需要实施。
从上面主库的GTID记录可以看到,GTID:1412已经被执行了。但是我们可以大胆推测,执行的1412并不是上面从库的binlog对应的1412。也就是说,这是很久以前使用的GTID。当从库的1412号新事务(建表语句)同步到主库时,主库发现这个GTID已经有执行记录,于是跳过直接执行1413号insert语句,导致表不存在错误。

找到原因后,即可确定解决方案:
由于这是从库同步到主库的信息,而从库是只读的,只是临时信息将生成备份。因此可以跳过这些事务。但由于从库的GTID小于主库的GTIDmaster数据库,1413号事务被跳过,后续还会有更多类似的问题。因此,还需要将从库上的事务号推送到与主库相同的级别,以便从库生成的后续事务号不再与主库上的事务号冲突。推高交易数量可以通过执行空交易来实现:
set gtid_next='44d3c576-ca26-11e3-a90a-a0369f38458a:1421;
begin;commit;
set gtid_next=' 44d3c576-ca26 -11e3-a90a-a0369f38458a:1422;
开始;提交;
……………………………………
set gtid_next='44d3c576- ca26-11e3-a90a- a0369f38458a:7383;
begin;commit;

set gtid_next='AUTOMATIC';

同时,同样的流程是在主库上也做了这样的处理,目的是完成上面跳过的事务造成的“间隙”处理完后,可以将auto_position设置为1:
mysql> show Slave status\G
** ************ ****************** 1. 行 ********************** ****
<省略部分信息>
Slave_IO_Running:是
Slave_SQL_Running:是
Slave_SQL_Running_State:Slave 已读取所有中继日志;等待从属 I/O 线程更新它
Executed_Gtid_Set: 258cacac- ca16-11e3-a8a1-a0369f35d966:1-161808236,
44d3c576-ca26-11e3-a90a-a0369f38458a:1-7383
        Auto_Position: 1
1 row in set (0 .00 sec)


至此,问题已经解决。

第二天查看,发现同步正常,但是主库申请的GTID又被跳过了。主库未执行7388号事务:
mysql> show Slave status\G
************************ ****** 1.行 ****************** **************
<省略一些信息>
Slave_IO_Running:是
Slave_SQL_Running:是
Slave_SQL_Running_State:Slave 已读取所有中继日志;等待从属 I/O 线程更新它
 检索的_Gtid_集:44d3c576-ca26-11e3-a90a-a0369f38458a:7384-7396
执行的_Gtid_集:258cacac-ca16-11e3-a8a1-a0369f35d 966:1-161808236,
4 4d3c576-ca26-11e3-a90a-a0369f38458a: 1-7387: 7389-7396
Auto_POSITION: 1
1 Row in Set (0.00 SEC)

查看主库Relaylog。发现7388为主库,7389为主库,7389为主库。已经获取到了,但是7388好像被跳过了,没有执行。为什么7389这次执行没有报错?
/*!*/;
# at 2300
#160303 3:06:55 服务器 ID 3809805896 end_log_pos 7759399 CRC32 0x844b31b3 GTID [commit=yes]
SET @@SESSION。 GTID_NEXT= '44d3c576-ca26-11e3-a90a-a0369f38458a:7388'/*!*/;
# 在 2348
#160303 3:06:55 服务器 ID 3809805896 end_log_pos 7759544 CRC32 0x1 9df 06b2 查询thread_id= 966014 exec_time=0 error_code=0
设置时间戳=1456945615/*!*/;
创建临时表 ibbackup_binlog_marker (a INT) ENGINE = INNODB
/*!*/;
# 在 2493
#160303 3:06:55 服务器 ID 3809805896 end_log_pos 7759592 CRC32 0x0641a4d4 GTID [commit=yes]
SET @@SESSION .GTID_NEXT= '44d3c576-ca26-11e3- a90a-a0369f38458a:7389'/*!*/;
# at 2541
#160303 3:06:55 服务器 id 3809805896 end_log_pos 7759673 CRC32 0 x76269211 查询 thread_id= 966014 exec_time=0 error_code= 0
SET TIMESTAMP=1456945615/*!*/;
BEGIN
/*!*/;
# at 2622
#160303 3 :06:55 服务器 ID 3809805896 end_log_pos 7759793 CRC32 0x7627ea96 查询 thread_id=966014 exec_time=0 error_code=0
SET TIMESTAMP=1456945615/*!*/;
插入 ibbackup_binlog_marker VALUES(1)
/*!*/;
# 在 2742
#160303 3:06:55 服务器 id 3809805896 end_log_pos 7759867 CRC32 0xb23b3a62 查询 thread_id=966014 exec_time=0 error_code=0
SET TIMESTAMP=1456945615/*!*/;
COMMIT

检查主库的binlog。
可以发现:7388确实被跳过了,而本应是插入的7389却变成了空事务!
#192527598
#160303 3:06:55 服务器 ID 3809805896 end_log_pos 192527646 CRC32 0x68163992 GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '44d3c576-ca26 -11e3-a90a -a03 69f38458a:7387'/ *!*/;
# at 192527646
#160303 3:06:55 server id 3809805896 end_log_pos 192527793 CRC32 0xf6c14291 Query thread_id=96601 4 exec_time=0 error_code=0
使用 `mysql`/ *!*/;
SET TIMESTAMP=1456945615/*!*/;
如果存在`ibbackup_binlog_marker`则删除表 /* 由服务器生成*/
/*!* /;
# 在 192527793
#160303 3:06:55 服务器 ID 3809805896 end_log_pos 192527841 CRC32 0x092b349d GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '44d3c576-ca 26-11e3 -a 90a-a0369f38458a :7389'/*!*/;
# at 192527841
#160303 3:06:55 serverid 3809805896 end_log_pos 192527914 CRC32 0x2df7ca6b 查询 thread_id=966014 exec_time=0 error_code=0
SET TIMESTAMP= 1456945615/*!*/;
BEGIN
/*!* /;
# at 192527914
#160303 3:06:55 服务器 ID 3809805896 end_log_pos 192527988 CRC32 0x1f722f7c 查询 thread_id= 966014 exec_time=0 error_code=0
设置时间 AMP=1456945615/*!*/;
提交
/*!*/;
# 在 192527988
#160303 3:06:55 服务器 ID 3809805896 end_log_pos 192528036 CRC32 0xf9656531 GTID [commit=yes]
SET @@SESSION.GTID_NEXT = '44d3c576-ca26-11e3-a90a-a0369f38458a:7390'/* !*/;

这个问题很让人困惑。阅读文档后,mysql使用行格式作为临时选项卡。处理情况如下:
1.不进行临时表复制(这里应该指的是创建)
2.从上面的binlog可以看出,对于temporary tab的dml操作,在复制时,将其替换为一个空事务。

对应文档:
RBL、RBR、临时表。如第 16.4.1.22 节“复制和临时表”中所述,使用基于行的格式时不会复制临时表。当混合格式生效时,涉及临时表的“安全”语句将使用基于语句的格式进行记录。了解更多
信息,请参见第 16.1 .2.1 节,“基于语句和基于行的复制的优点和缺点”。

MySQL 文档:17.1.3.4 使用 GTID 进行复制的限制
临时表。使用 GTID 时(即,当使用 --enforce-gtid-consistency 选项启动服务器时),事务内部不支持 CREATE TEMPORARY TABLE 和 DROP TEMPORARY TABLE 语句。可以在启用 GTID 的情况下使用这些语句,但只能在任何事务之外,并且只能在 autocommit=1 的情况下使用。

注意:重置从属操作不会对 gtid 产生任何影响,因此此方法不能用于保持主从 GTID 一致:
mysql> show Slave status \G
************************ ***** 1. 行 ********** ****************
                                                                                                          从属_IO_State:等待主机发送事件
省略一些信息>
sql_remaining_dlay: null
Slave_sql_Running_State:从站已读取所有中继; t
master_retry_count: 86400
                    Master_Bind:                                                                   Last_IO_Error_Timestamp: Re trieved_Gtid_Set: 73d1e54a-c3a5-11e3-bea2-005056b4006e:3-5
执行_Gtid_Set: 73d1e54a-c3a5-11e3-bea2-005056b4006e:1-5 ,a95348e2-e7aa-11e2-a42f-001b785aa468:1-5
          Auto_Position:1
集合中的1行(0.00秒)


mysql>
mysql>
mysql>
mysql>
mysql> 显示全局变量,如 '%gtid%';
+-------------------------------- - ---+-------------------------------------------------------- ---- --------------------------------------+
|变量名                   |值                                                                              |
+---------------------------------+--------- ---- ---------------------------------------------------------- ---- ---------------------+
|强制 gtid 一致性 |开 |开 |p;48e2-e7aa-11e2-a42f-001b785aa468:1-5 |
| gtid_mode                                                                                                                                                                                  >| gtid_owned                                                    |
| gtid_purged                                                                                   |简化的_binlog_gtid_recovery |关闭                                                       --------+-------------------------------------------- ------- ------------------------------------------- -------+
集合中 6 行(0.00 秒)

mysql> select * from test.aa;
+------+- ---+
|编号 |姓名 |
+------+------+
| 1 |一个|
| 2 |一个|
| 1 |空|
| 2 |空|
| 3 | NULL |
+ ------+------+
集合中的 5 行(0.00 秒)

mysql> stop Slave;
查询正常,0 行受影响(0.06 秒)

mysql> 重置从属;
查询正常,0 行受影响(0.11 秒)

mysql> 显示全局变量,如“%gtid%”;
+----------------------------------+---------- -------------------------------------------------- -----------------------+
|变量名                                                                                                                                                                                                                    ----------------------------------------+-------------------- ---- ---------------------------------------------------------- ---- ------------+
|强制 gtid 一致性 |开 |开 |
| gtid_execed                                                                                        001b785aa468:1-5 |
| gtid_mode                                                                                           |
| gtid_owned                                                   |
| gtid_purged                                                                                  simplified_binlog_gtid_recovery |离开;-------------------------------------------------- -----------------------+
集合中 6 行(0.00 秒)

这篇关于《重置master导致主从GTID不一致怎么办》的文章就分享到这里。希望以上内容能够对大家有所帮助,让大家能够学到更多的知识。如果您觉得文章不错,请转发,让更多人看到。

1. 本站所有资源来源于用户上传或网络,仅作为参考研究使用,如有侵权请邮件联系站长!
2. 本站积分货币获取途径以及用途的解读,想在本站混的好,请务必认真阅读!
3. 本站强烈打击盗版/破解等有损他人权益和违法作为,请各位会员支持正版!
4. 编程技术 > 重置master导致主从GTID不一致怎么办?

用户评论