這篇文章主要介紹了MySQL部分5.6版本罕見復制報錯ERROR 1837如何處理,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
場景:
1、簡單的一主一從,版本MySQL-5.6.20
2、master_auto_position=0
3、開啟gtid
報錯如下:
Last_SQL_Errno: 1837
Last_SQL_Error: Error 'When @@SESSION.GTID_NEXT is set to a GTID, you must explicitly set it to a different value after a COMMIT or ROLLBACK. Please check GTID_NEXT variable manual page for detailed explanation. Current @@SESSION.GTID_NEXT is 'c44bd915-440d-11e6-8ea0-6c92bf24b8c0:71844624'.' on query. Default database: '$db'. Query: 'DELETE FROM `db2`.`tb2`'
看完報錯一臉懵逼,莫非主庫在做什么騷操作?
檢查一下主庫binlog對應的GTID點,可以發現點什么:
(已做數據脫敏,如上兩張表分別用db1.tb1和db2.tb2來區分)
發現到GTID為【c44bd915-440d-11e6-8ea0-6c92bf24b8c0:71844624】和【71844625】之間做了如下操作:
USE db3;
DELETE FROM `db1`.`tb1`;
DELETE FROM `db2`.`tb2`;
DELETE FROM `db_1`.`t1`與DELETE FROM `db_2`.`t2`之間并沒有更多的:SET @@SESSION.GTID_NEXT。
這似乎就違反了GTID的限制,一個事務應該對應一個GTID號才對。
結合報錯信息,懷疑此時在執行到第二個DELETE時,因為第二個DELETE沒有對應的GTID_NEXT,就報錯了:
Last_SQL_Errno: 1837 …… Default database: '$db'. Query: 'DELETE FROM `db2`.`tb2`'
再檢查一下存儲引擎,發現db1.tb1和db2.tb2這兩張表均為memory,即為非事務引擎。
可能與這個有關。
此處,為了修復這個復制故障,在從庫上做如下操作:
〇 SET SESSION sql_log_bin=0;
〇 手動執行未執行的事務,此處為:DELETE FROM `db2`.`tb2`;
〇 SET SESSION sql_log_bin=1;
〇 STOP SLAVE sql_thread; SET @@SESSION.GTID_NEXT= 'AUTOMATIC'; START SLAVE sql_thread;
至于為什么在ENFORCE_GTID_CONSISTENCY為ON的情況下,產生這樣違反GTID的events,我搜了一下bug庫:
更多討論如下:
https://bugs.mysql.com/bug.php?id=71695
該問題發生在5.6.20及以前的5.6版本。
并在5.6.21以后的版本修復了這個問題。
在文檔中找到:
Replication: When mysqlbinlog processed multiple binary log files into a single output file, this file was not in a useful
state for point-in-time recovery, when it failed with the error, When @@SESSION.GTID_NEXT is set to a GTID, you must
explicitly set it to a different value after a COMMIT or ROLLBACK. Please check GTID_NEXT variable manual page for
detailed explanation. Current @@SESSION.GTID_NEXT is 'xyz'. When mysqlbinlog processes a binary log containing GTIDs,
it outputs SET gtid_next statements, but gtid_next is set to undefined whenever a commit occurs; this left gtid_next
undefined when the server had finished processing the output from mysqlbinlog. When the next binary log file started
with one or more anonymous statements or transactions, the combination of gtid_next being left undefined at the end
of the first binary log and the second binary log containing anonymous transactions to the error described previously
(Error 1837, ER_GTID_NEXT_TYPE_UNDEFINED_GROUP).
To fix this issue, now, whenever mysqlbinlog encounters this situation, it inserts SET gtid_next = AUTOMATIC
if required to avoid leaving the previous binary log with gtid_next undefined.
In addition, as a result of this fix, mysqlbinlog no longer outputs session variable information for every binary log;
now, this value is printed only once unless it changes. (Bug #18258933, Bug #71695)
大致原因是:
當mysqlbinlog處理包含GTID的binlog時,它會輸出gtid_next,但是當提交時,gtid_next會被設置為“undefined”。
當服務器處理完來自mysqlbinlog的輸出后,就留下了binlog undefined。
簡單的來說:
因為gtid_next可能會被設置為undefined,導致復制出現1837。
為了修復這個問題,在MySQL5.6.21版本中,做出了如下修復:
每當mysqlbinlog遇到這種情況,會自動加入如下語句:
“SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;”
以避免使用gtid_next保留之前binlog undefined。
(這個可以在開啟GTID時,輕易測試得出)
后來又搜了一下,在使用INSERT DELAYED語法時,也可能出現這個問題
雖然文檔描述好像和這個case不太像,但總之也是有收獲的:
〇 升級到更高版本的MySQL。
〇 盡量使用事務引擎,避免在一個事務中同時操作事務表和非事務表的可能性。
(雖然enforce_gtid_consistency開啟,但也有可能出現突破GTID限制的語句,盡量從業務上限制)
〇 盡量避免使用INSERT DELAYED語法。
感謝你能夠認真閱讀完這篇文章,希望小編分享的“MySQL部分5.6版本罕見復制報錯ERROR 1837如何處理”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。