溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

reset master導(dǎo)致主從GTID不一致怎么辦

發(fā)布時間:2021-11-06 14:10:40 來源:億速云 閱讀:208 作者:小新 欄目:MySQL數(shù)據(jù)庫

這篇文章將為大家詳細(xì)講解有關(guān)reset master導(dǎo)致主從GTID不一致怎么辦,小編覺得挺實(shí)用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

1、 主庫報同步異常(主從是雙向復(fù)制的),報錯信息顯示insert語句的目標(biāo)表不存在
2、 檢查主從庫的GTID信息發(fā)現(xiàn),主庫的GTID比從庫的高(應(yīng)該是從庫做過reset master的操作,重置了GTID),導(dǎo)致有些事務(wù)被跳過,從而引發(fā)報錯。這里被跳過的是建表語句。
3、 處理方法是推高從庫的GTID到主庫的水平,從而消除沖突,保證從庫過來的事務(wù)都可以在主庫執(zhí)行。
4、 第二天檢查發(fā)現(xiàn)還是有些事務(wù)被自動跳過,被跳過的是創(chuàng)建臨時表的語句。查詢文檔得知:臨時表的創(chuàng)建操作不會同步到備庫執(zhí)行,而臨時表的相關(guān)操作事務(wù),也會代之以空事務(wù)。

下面是詳細(xì)處理過程:
有個主庫最近同步從庫信息經(jīng)常報錯,跳過對應(yīng)的事務(wù)之后第二天還是有同樣的問題,報錯如下:
Last_Error: Error 'Table 'mysql.ibbackup_binlog_marker' doesn't exist' on query. Default database: 'mysql'. Query: 'INSERT INTO ibbackup_binlog_marker VALUES(1)'

其中一次詳細(xì)信息如下:
mysql> show slave status \G
*************************** 1. row ***************************
<省略部分信息>
        Relay_Master_Log_File: mysql-bin.000134
             Slave_IO_Running: Yes
                   Last_Errno: 1146
                   Last_Error: Error 'Table 'mysql.ibbackup_binlog_marker' doesn't exist' on query. Default database: 'mysql'. Query: 'INSERT INTO ibbackup_binlog_marker VALUES(1)'
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1534712
              Relay_Log_Space: 8079
               Last_SQL_Errno: 1146
               Last_SQL_Error: Error 'Table 'mysql.ibbackup_binlog_marker' doesn't exist' on query. Default database: 'mysql'. Query: 'INSERT INTO ibbackup_binlog_marker VALUES(1)'
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 3809805896
                 Master_UUID: 44d3c576-ca26-11e3-a90a-a0369f38458a
             Master_Info_File: mysql.slave_master_info
           Retrieved_Gtid_Set: 44d3c576-ca26-11e3-a90a-a0369f38458a:28-1420
           Executed_Gtid_Set: 258cacac-ca16-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-1530:1532-1543:1545-1556:1558-1570:1572-1583:1585-1596:1598-1609:1611-1622:1624-1635:1637-1648:1650-1662:1664-1675:1677-1688:1690-1701:1703-1714:1716-1727:1729-1740:1742-1754:1756-1767:1769-1780:1782-1793:1795-1806:1808-1819:1821-1832:1834-1846:1848-1859:1861-1872:1874-1885:1887-1898:1900-1911:1913-1924:1926-1938:1940-1951:1953-1964:1966-1977:1979-1990:1992-2003:2005-2016:2018-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-2240:2242-2253:2255-2266:2268-2279:2281-2292:2294-2306:2308-2319:2321-2332:2334-2345:2347-2358:2360-2371:2373-2384:2386-2398:2400-2411:2413-2424:2426-2437:2439-2450:2452-2463:2465-2476:2478-2490:2492-2503:2505-2516:2518-2529:2531-2542:2544-2555:2557-2568:2570-2582:2584-2595:2597-2608:2610-2621:2623-2634

報錯的是一個insert語句,但目標(biāo)表找不到。這個語句在從庫的mysql-bin.000134 日志上,Exec_Master_Log_Pos是1534712。

于是到從庫檢查對應(yīng)binlog,在對應(yīng)位置可以看到,insert語句的GTID是xxx:1413,而在insert語句之前就是建表語句,對應(yīng)的GTID是1412:
# at 1534324
#160301  0:21:00 server id 3809805896  end_log_pos 1534372 CRC32 0x9cf47996     GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '44d3c576-ca26-11e3-a90a-a0369f38458a:1411'/*!*/;
# at 1534372
#160301  0:21:00 server id 3809805896  end_log_pos 1534519 CRC32 0x0e9481da     Query   thread_id=947514        exec_time=0     error_code=0
SET TIMESTAMP=1456762860/*!*/;
DROP TABLE IF EXISTS `ibbackup_binlog_marker` /* generated by server */
/*!*/;
# at 1534519
#160301  0:21:00 server 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 server id 3809805896  end_log_pos 1534712 CRC32 0x04118941     Query   thread_id=947514        exec_time=0     error_code=0
SET TIMESTAMP=1456762860/*!*/;
SET @@session.pseudo_thread_id=947514/*!*/;
CREATE TEMPORARY TABLE ibbackup_binlog_marker (a INT) ENGINE = INNODB
/*!*/;
# at 1534712
#160301  0:21:00 server id 3809805896  end_log_pos 1534760 CRC32 0x70ca2249     GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '44d3c576-ca26-11e3-a90a-a0369f38458a:1413'/*!*/;
# at 1534760
#160301  0:21:00 server id 3809805896  end_log_pos 1534841 CRC32 0x5dad491c     Query   thread_id=947514        exec_time=0     error_code=0
SET TIMESTAMP=1456762860/*!*/;
BEGIN
/*!*/;
# at 1534841
#160301  0:21:00 server id 3809805896  end_log_pos 1534961 CRC32 0xb5f7ab48     Query   thread_id=947514        exec_time=0     error_code=0
SET TIMESTAMP=1456762860/*!*/;
INSERT INTO ibbackup_binlog_marker VALUES(1)
/*!*/;
# at 1534961
#160301  0:21:00 server id 3809805896  end_log_pos 1535035 CRC32 0x9baea0da     Query   thread_id=947514        exec_time=0     error_code=0
SET TIMESTAMP=1456762860/*!*/;
COMMIT
/*!*/;

而檢查主庫的relaylog時可以發(fā)下,這些事務(wù)都是有成功同步過來的,并沒有丟失。那為什么會提示表不存在的錯誤呢?是有什么原因?qū)е陆ū碚Z句沒有執(zhí)行?

我們先看一下主庫的GTID,從從庫同步過來的已執(zhí)行的最大事務(wù)號是7383:
*************************** 1. row ***************************
Variable_name: enforce_gtid_consistency
        Value: ON
*************************** 2. row ***************************
Variable_name: gtid_executed
        Value: 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-1596:1598-1609:1611-1622:1624-1635:1637-1648:1650-1662:1664-1675:1677-1688:1690-1701:1703-1714:1716-1727:1729-1740:1742-1754:1756-1767:1769-1780:1782-1793:1795-1806:1808-1819:1821-1832:1834-1846:1848-1859:1861-1872:1874-1885:1887-1898:1900-1911:1913-1924:1926-1938:1940-1951:1953-1964:1966-1977:1979-1990:1992-2003:2005-2016:2018-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-2240:2242-2253:2255-2266:2268-2279:2281-2292:2294-2306:2308-2319:2321-2332:2334-2345:2347-2358:2360-2371:2373-2384:2386-2398:2400-2411:2413-2424:2426-2437:2439-2450:2452-2463:2465-2476:2478-2490:2492-2503:2505-2516:2518-7383:


再看一下從庫,發(fā)現(xiàn)最大只去到1420!
*************************** 1. row ***************************
Variable_name: enforce_gtid_consistency
        Value: ON
*************************** 2. row ***************************
Variable_name: gtid_executed
        Value: 258cacac-ca16-11e3-a8a1-a0369f35d966:109528488-160665725,
44d3c576-ca26-11e3-a90a-a0369f38458a:1-1420

問題來了:為什么從庫的GTID會比主庫的小呢?應(yīng)該是有同學(xué)在從庫做了reset master的操作,重置了GTID導(dǎo)致的!

我們知道,備庫在應(yīng)用主庫的日志時,會通過檢查GTID來確定對應(yīng)的事務(wù)是否已經(jīng)執(zhí)行過。如果對應(yīng)的GTID已經(jīng)在備庫中有記錄,說明對應(yīng)事務(wù)已經(jīng)執(zhí)行過,不必再重復(fù)執(zhí)行。反之則需要執(zhí)行。
從上面主庫的GTID記錄可以看到,GTID:1412已經(jīng)執(zhí)行過了。但我們可以大膽推測,此已經(jīng)執(zhí)行的1412非上面從庫的binlog對應(yīng)的1412,也就是說,這是很久以前用過的GTID。當(dāng)從庫的這個新的1412號事務(wù)(建表語句)同步到主庫時,主庫發(fā)現(xiàn)這個GTID已經(jīng)有執(zhí)行記錄,所以就跳過直接就去執(zhí)行1413號insert語句,從而引發(fā)了 Table doesn't exist的錯誤。

找到了原因就可以確定解決方案:
由于這是從從庫同步到主庫的信息,而從庫是只讀的,只會產(chǎn)生備份的臨時信息。因此這些事務(wù)都可以跳過。但由于從庫的GTID比主庫上的小,跳過了1413號事務(wù),后面還會有更多的類似的問題。因此還需要在從庫上將事務(wù)號推高到跟主庫一致的水平,這樣后面從庫產(chǎn)生的事務(wù)號都不會再跟主庫上的有沖突。推高事務(wù)號可以通過執(zhí)行空事務(wù)達(dá)到:
set gtid_next='44d3c576-ca26-11e3-a90a-a0369f38458a:1421;
begin;commit;
set gtid_next='44d3c576-ca26-11e3-a90a-a0369f38458a:1422;
begin;commit;
…………………………………
set gtid_next='44d3c576-ca26-11e3-a90a-a0369f38458a:7383;
begin;commit;

set gtid_next='AUTOMATIC';

同時也在主庫上做同樣的處理,目的是補(bǔ)全上面跳過的事務(wù)產(chǎn)生的“空隙”,處理完后就可以auto_position設(shè)置為1了:
mysql> show slave status\G
*************************** 1. row ***************************
<省略部分信息>
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Retrieved_Gtid_Set: 44d3c576-ca26-11e3-a90a-a0369f38458a:7384-7396
            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)


至此,問題處理完畢。

第二天復(fù)核,發(fā)現(xiàn)同步正常,但是主庫應(yīng)用的GTID又有跳過的現(xiàn)象,7388號事務(wù)在主庫沒有執(zhí)行:
mysql> show slave status\G
*************************** 1. row ***************************
<省略部分信息>
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Retrieved_Gtid_Set: 44d3c576-ca26-11e3-a90a-a0369f38458a:7384-7396
            Executed_Gtid_Set: 258cacac-ca16-11e3-a8a1-a0369f35d966:1-161808236,
44d3c576-ca26-11e3-a90a-a0369f38458a:1-7387:7389-7396
                Auto_Position: 1
1 row in set (0.00 sec)

檢查主庫relaylog,發(fā)現(xiàn)7388、7389這兩個事務(wù)主庫是有獲取到的,但7388看起來跳過沒執(zhí)行,為什么7389這次執(zhí)行卻沒報錯呢?
/*!*/;
# at 2300
#160303  3:06:55 server id 3809805896  end_log_pos 7759399 CRC32 0x844b31b3     GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '44d3c576-ca26-11e3-a90a-a0369f38458a:7388'/*!*/;
# at 2348
#160303  3:06:55 server id 3809805896  end_log_pos 7759544 CRC32 0x19df06b2     Query   thread_id=966014        exec_time=0     error_code=0
SET TIMESTAMP=1456945615/*!*/;
CREATE TEMPORARY TABLE ibbackup_binlog_marker (a INT) ENGINE = INNODB
/*!*/;
# at 2493
#160303  3:06:55 server 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 server id 3809805896  end_log_pos 7759673 CRC32 0x76269211     Query   thread_id=966014        exec_time=0     error_code=0
SET TIMESTAMP=1456945615/*!*/;
BEGIN
/*!*/;
# at 2622
#160303  3:06:55 server id 3809805896  end_log_pos 7759793 CRC32 0x7627ea96     Query   thread_id=966014        exec_time=0     error_code=0
SET TIMESTAMP=1456945615/*!*/;
INSERT INTO ibbackup_binlog_marker VALUES(1)
/*!*/;
# at 2742
#160303  3:06:55 server id 3809805896  end_log_pos 7759867 CRC32 0xb23b3a62     Query   thread_id=966014        exec_time=0     error_code=0
SET TIMESTAMP=1456945615/*!*/;
COMMIT

檢查主庫的binlog。
可以發(fā)現(xiàn):7388的確是被跳過了,而7389這個本該是insert的卻變成了空事務(wù)!
# at 192527598
#160303  3:06:55 server id 3809805896  end_log_pos 192527646 CRC32 0x68163992   GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '44d3c576-ca26-11e3-a90a-a0369f38458a:7387'/*!*/;
# at 192527646
#160303  3:06:55 server id 3809805896  end_log_pos 192527793 CRC32 0xf6c14291   Query   thread_id=966014        exec_time=0     error_code=0
use `mysql`/*!*/;
SET TIMESTAMP=1456945615/*!*/;
DROP TABLE IF EXISTS `ibbackup_binlog_marker` /* generated by server */
/*!*/;
# at 192527793
#160303  3:06:55 server id 3809805896  end_log_pos 192527841 CRC32 0x092b349d   GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '44d3c576-ca26-11e3-a90a-a0369f38458a:7389'/*!*/;
# at 192527841
#160303  3:06:55 server id 3809805896  end_log_pos 192527914 CRC32 0x2df7ca6b   Query   thread_id=966014        exec_time=0     error_code=0
SET TIMESTAMP=1456945615/*!*/;
BEGIN
/*!*/;
# at 192527914
#160303  3:06:55 server id 3809805896  end_log_pos 192527988 CRC32 0x1f722f7c   Query   thread_id=966014        exec_time=0     error_code=0
SET TIMESTAMP=1456945615/*!*/;
COMMIT
/*!*/;
# at 192527988
#160303  3:06:55 server id 3809805896  end_log_pos 192528036 CRC32 0xf9656531   GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '44d3c576-ca26-11e3-a90a-a0369f38458a:7390'/*!*/;

這個問題比較坑,看了下文檔,mysql 在row format的情況下,對于temporary tab的處理情況如下:
1、不進(jìn)行tempory table 復(fù)制(這個應(yīng)該是指創(chuàng)建)
2、從上面的binlog中也可以看到,對于temporary tab 的dml操作,在復(fù)制的時候,用空事務(wù)代替。

相應(yīng)的文檔:
RBL, RBR, and temporary tables. As noted in Section 16.4.1.22, “Replication and Temporary
Tables”, temporary tables are not replicated when using row-based format. When mixed format is in
effect, “safe” statements involving temporary tables are logged using statement-based format. For more
information, see Section 16.1.2.1, “Advantages and Disadvantages of Statement-Based and Row-Based
Replication”.

MySQL文檔:17.1.3.4 Restrictions on Replication with GTIDs
Temporary tables.  CREATE TEMPORARY TABLE and DROP TEMPORARY TABLE statements are not supported inside transactions when using GTIDs (that is, when the server was started with the --enforce-gtid-consistency option). It is possible to use these statements with GTIDs enabled, but only outside of any transaction, and only with autocommit=1.

注意:reset slave操作沒有對gtid有任何影響,因此不能通過這種辦法來讓主從GTID保持一致:
mysql> show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
               < 省略部分信息 >
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 73d1e54a-c3a5-11e3-bea2-005056b4006e:3-5
            Executed_Gtid_Set: 73d1e54a-c3a5-11e3-bea2-005056b4006e:1-5,a95348e2-e7aa-11e2-a42f-001b785aa468:1-5
                Auto_Position: 1
1 row in set (0.00 sec)


mysql> 
mysql> 
mysql> 
mysql> 
mysql> show global variables like '%gtid%';
+---------------------------------+------------------------------------------------------------------------------------+
| Variable_name                   | Value                                                                              |
+---------------------------------+------------------------------------------------------------------------------------+
| enforce_gtid_consistency        | ON                                                                                 |
| gtid_executed                   | 73d1e54a-c3a5-11e3-bea2-005056b4006e:1-5, a95348e2-e7aa-11e2-a42f-001b785aa468:1-5 |
| gtid_mode                       | ON                                                                                 |
| gtid_owned                      |                                                                                    |
| gtid_purged                     |                                                                                    |
| simplified_binlog_gtid_recovery | OFF                                                                                |
+---------------------------------+------------------------------------------------------------------------------------+
6 rows in set (0.00 sec)

mysql> select * from test.aa;
+------+------+
| id   | name |
+------+------+
|    1 | a    |
|    2 | a    |
|    1 | NULL |
|    2 | NULL |
|    3 | NULL |
+------+------+
5 rows in set (0.00 sec)

mysql> stop slave;
Query OK, 0 rows affected (0.06 sec)

mysql> reset slave;
Query OK, 0 rows affected (0.11 sec)

mysql> show global variables like '%gtid%';
+---------------------------------+------------------------------------------------------------------------------------+
| Variable_name                   | Value                                                                              |
+---------------------------------+------------------------------------------------------------------------------------+
| enforce_gtid_consistency        | ON                                                                                 |
| gtid_executed                   | 73d1e54a-c3a5-11e3-bea2-005056b4006e:1-5, a95348e2-e7aa-11e2-a42f-001b785aa468:1-5 |
| gtid_mode                       | ON                                                                                 |
| gtid_owned                      |                                                                                    |
| gtid_purged                     |                                                                                    |
| simplified_binlog_gtid_recovery | OFF                                                                                |
+---------------------------------+------------------------------------------------------------------------------------+
6 rows in set (0.00 sec)

關(guān)于“reset master導(dǎo)致主從GTID不一致怎么辦”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI