mysql主从切换gtid不一致_reset master导致主从GTID不一致的处理方法
1、主庫報同步異常(主從是雙向復制的),報錯信息顯示insert語句的目標表不存在
2、檢查主從庫的GTID信息發現,主庫的GTID比從庫的高(應該是從庫做過reset master的操作,重置了GTID),導致有些事務被跳過,從而引發報錯。這里被跳過的是建表語句。
3、處理方法是推高從庫的GTID到主庫的水平,從而消除沖突,保證從庫過來的事務都可以在主庫執行。
4、第二天檢查發現還是有些事務被自動跳過,被跳過的是創建臨時表的語句。查詢文檔得知:臨時表的創建操作不會同步到備庫執行,而臨時表的相關操作事務,也會代之以空事務。
下面是詳細處理過程:
有個主庫最近同步從庫信息經常報錯,跳過對應的事務之后第二天還是有同樣的問題,報錯如下:
Last_Error: Error 'Table 'mysql.ibbackup_binlog_marker' doesn't exist' on query. Default database: 'mysql'. Query: 'INSERT INTO ibbackup_binlog_marker VALUES(1)'
其中一次詳細信息如下:
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語句,但目標表找不到。這個語句在從庫的mysql-bin.000134 日志上,Exec_Master_Log_Pos是1534712。
于是到從庫檢查對應binlog,在對應位置可以看到,insert語句的GTID是xxx:1413,而在insert語句之前就是建表語句,對應的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時可以發下,這些事務都是有成功同步過來的,并沒有丟失。那為什么會提示表不存在的錯誤呢?是有什么原因導致建表語句沒有執行?
我們先看一下主庫的GTID,從從庫同步過來的已執行的最大事務號是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:
再看一下從庫,發現最大只去到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會比主庫的小呢?應該是有同學在從庫做了reset master的操作,重置了GTID導致的!
我們知道,備庫在應用主庫的日志時,會通過檢查GTID來確定對應的事務是否已經執行過。如果對應的GTID已經在備庫中有記錄,說明對應事務已經執行過,不必再重復執行。反之則需要執行。
從上面主庫的GTID記錄可以看到,GTID:1412已經執行過了。但我們可以大膽推測,此已經執行的1412非上面從庫的binlog對應的1412,也就是說,這是很久以前用過的GTID。當從庫的這個新的1412號事務(建表語句)同步到主庫時,主庫發現這個GTID已經有執行記錄,所以就跳過直接就去執行1413號insert語句,從而引發了 Table doesn't exist的錯誤。
找到了原因就可以確定解決方案:
由于這是從從庫同步到主庫的信息,而從庫是只讀的,只會產生備份的臨時信息。因此這些事務都可以跳過。但由于從庫的GTID比主庫上的小,跳過了1413號事務,后面還會有更多的類似的問題。因此還需要在從庫上將事務號推高到跟主庫一致的水平,這樣后面從庫產生的事務號都不會再跟主庫上的有沖突。推高事務號可以通過執行空事務達到:
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';
同時也在主庫上做同樣的處理,目的是補全上面跳過的事務產生的“空隙”,處理完后就可以auto_position設置為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)
至此,問題處理完畢。
第二天復核,發現同步正常,但是主庫應用的GTID又有跳過的現象,7388號事務在主庫沒有執行:
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,發現7388、7389這兩個事務主庫是有獲取到的,但7388看起來跳過沒執行,為什么7389這次執行卻沒報錯呢?
/*!*/;
# 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。
可以發現:7388的確是被跳過了,而7389這個本該是insert的卻變成了空事務!
# 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、不進行tempory table 復制(這個應該是指創建)
2、從上面的binlog中也可以看到,對于temporary tab 的dml操作,在復制的時候,用空事務代替。
相應的文檔:
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)
來自 “ ITPUB博客 ” ,鏈接:http://blog.itpub.net/22818880/viewspace-2073787/,如需轉載,請注明出處,否則將追究法律責任。
總結
以上是生活随笔為你收集整理的mysql主从切换gtid不一致_reset master导致主从GTID不一致的处理方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LinuxZIP压缩和解压缩
- 下一篇: mysql root password_