暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【MySQL】并行复制ERROR 1755/1756故障处理

神谕的暗影长廊 2020-10-20
3628
在官方版本的MySQL5.6中,并行复制已经可以使用,基于database,局限性比较大。5.7以后,实现了真正意义上的“并行”,基于组提交(logical clock)。本文主要分享一些ERROR 1755/1756故障的处理方法及原因,部分是官方已认定的BUG。

ERROR 1755

导致这个错误的原因很多,通过此处只列出几个特殊场景下的例子。

1) Reason:The master event is logically timestamped incorrectly

1Last_SQL_Error: Cannot execute the current event group in the parallel mode. Encountered event Gtid, 
2relay-log name $dir/relaylog/mysql-relay.000002
3position 280408 which prevents execution of this event group in parallel mode. 
4Reason: The master event is logically timestamped incorrectly.

目前只在MySQL-5.6 ---> MySQL-5.7 这个结构中发现,MySQL-5.7中开启了基于逻辑时钟的MTS,master的event没有记录并行复制的相关信息。这种跨大版本的结构可能同样导致ERROR 1756(见后面)

原因:

Slave的复制分发对象被为logical_clock
,但5.6是仅支持database
粒度的并行复制。

那么为什么5.7使用基于logical_clock
的就会出现这个问题呢?

因为在5.7的binlog event
中,新增了last_committed
sequence_number

前者表示事务提交时,上次提交的事务编号,若事务具有相同的last_committed
,则表明这些事务在同一个组内,可以并行进行apply
这两者的出现,也是5.7新增基于logical_clock
进行并行复制的基础。
无论在开启GTID还是关闭GTID的情况下,都会有对应信息的产生。

在5.7中,MYSQL_BIN_LOG定义了两个Logical_clock的变量:

1class MYSQL_BIN_LOG: public TC_LOG
2{
3  ...
4  public:
5  /* Committed transactions timestamp */
6  Logical_clock max_committed_transaction;
7  /* "Prepared" transactions timestamp */
8  Logical_clock transaction_counter;
9  ...

max_committed_transaction:记录上次提交事务的logical_clock,即last_committed。
transaction_counter:记录当前组提交中各事务的logical_clock,即sequence_number。

而5.6所产生的binlog是没有这些记录的,作为slave的5.7自然无法基于logical_clock进行并行复制。

解决办法:

① 关闭MTS

1STOP SLAVE;
2SET GLOBAL slave_parallel_workers=0;
3START SLAVE;

② 修改为5.6的方式

1STOP SLAVE;
2SET GLOBAL slave_parallel_type='DATABASE';
3START SLAVE;

2) Reason: the event is a part of a group that is unsupported in the parallel execution mode.

3) Reason: possible malformed group of events from an old master.

2)3) 可以统一到一起,主要发生在老版本的MySQL-5.6的MTS结构中。
按报错,通过字面可理解为部分event group无法被SLAVE所正常应用。

解决办法依然只能是关闭并行复制,将slave_parallel_workers设置为0。
(微信好像不能直接外链跳转)

bug #71495:    

https://bugs.mysql.com/bug.php?id=71495


bug #72537:    

https://bugs.mysql.com/bug.php?id=72537

ERROR 1755 可大致可以理解为,master上产生的events是无法被slave通过并行复制的方式正常应用的。
如果真的遇到了,可以看看当时执行的events是否有奇怪的语句。MySQL-5.6的并行复制比较鸡肋,关闭MTS功能总是最稳健的解决方案,此外,在5.6中,使用传统单线程复制可能还会更快。要用MTS,上5.7+吧。


ERROR 1756

这个错误场景可能更多,在我遇到的1756里,错误信息报出来也会千奇百怪。
文档上也比较简单:

1Error: 1756 SQLSTATE: HY000 (ER_MTS_INCONSISTENT_DATA)
2Message: %s

1) 最为常见的一种ERROR 1756

 1……
2Slave_IO_Running: Yes
3Slave_SQL_Running: No
4……
5Last_SQL_Errno: 1756
6Last_SQL_Error: … The slave coordinator and worker threads are stopped, 
7possibly leaving data in inconsistent state. A restart should restore consistency automatically, 
8although using non-transactional storage for data or info tables or 
9DDL queries could lead to problems. In such cases you have to examine your data (see documentation for details).
10……           

这是一个知名BUG:(在MySQL5.6和MySQL5.7高版本被修复)

bug #77239: 

https://bugs.mysql.com/bug.php?id=77239   

原因是由于InnoDB死锁而无法执行事务,或者因为事务的执行时间超过了InnoDB的innodb_lock_wait_timeout

有趣的是,这个error会在错误日志中被打印出三次,也被人认为是个bug:

bug #77237: 

https://bugs.mysql.com/bug.php?id=77237

bug #77237 在MySQL-5.6.30和MySQL-5.7.12修复:

1When a multi-threaded slave stopped with an error, the same error message
2was printed three times. Now, the SQL thread's kill acceptance status is
3saved, and only printed once.

当然,除了是个bug #77239,也可能是字面意思,即DDL或者非事务引擎导致,如果发生此错误,也可以看一下当时主库在干什么。

bug #77239的稳定复现方法:

 1master> CREATE TABLE test.t(id int PRIMARY KEY); 
2Query OK, 0 rows affected (0.00 sec)
3
4master> INSERT INTO test.t SELECT 1;
5Query OK, 1 row affected (0.00 sec)
6Records: 1  Duplicates: 0  Warnings: 0
7
8slave> BEGIN; SELECT * FROM t WHERE id=1 FOR UPDATE;
9Query OK, 0 rows affected (0.00 sec)
10
11+----+
12| id |
13+----+
14|  1 |
15+----+
161 row in set (0.00 sec)
17
18slave> SHOW SLAVE STATUS\G
19…………
20Last_SQL_Errno: 1756
21Last_SQL_Error: ... The slave coordinator and worker threads are stopped, 
22possibly leaving data in inconsistent state. ………… 
23…………
241 row in set (0.00 sec)

上述测试以下环境测试下来均可:

1VERSION: MySQL-5.6.20
2binlog_format=[ROW|MIXED]
3CHANGE MASTER TO master_auto_position=[0|1]

解决方案:

① 重新开启sql_thread:

1START SLAVE sql_thread;

② 关闭MTS(真万能):

1STOP SLAVE;
2SET GLOBAL slave_parallel_workers=0;
3START SLAVE;

google了一下,这个报错(The slave coordinator and worker threads are stopped, possibly leaving data in inconsistent state. A restart should restore consistency automatically, although using non-transactional storage for data or info tables or DDL queries could lead to problems. In such cases you have to examine your data (see documentation for details).)

老叶也遇到过,但是他定位的原因和我理解的不太一致:
有兴趣可看一下:
FAQ系列 | 从MySQL 5.6到5.7复制错误解决
http://imysql.cn/?p=4118

2) @@slave_transaction_retries在MTS中无效

这个要结合1)来看。
首先,slave_transaction_retries
这个参数的作用是,遇到1)中的1756情况,则coordinator thread
会在出错之前自动重试slave_transaction_retries
次。
而在一些版本里,这个值在MTS中没用的,从而导致1756(正确设置这个参数本该可以避免)。

部分版本里,开启MTS会有提示:

1[Note] 1753 
2slave_transaction_retries is not supported in multi-threaded slave mode. 
3In the event of a transient failure, the slave will not retry the transaction and will stop

在5.7的文档上也写的很明白:

1As of MySQL 5.7.5, retrying of transactions is supported when multi-threading is enabled on a slave. 
2In previous versions, slave_transaction_retries was treated as equal to 0 when using multi-threaded slaves.

简单来说,就是5.7.5之前,在MTS结构中,slave_transaction_retries
被视为0。

此处又一个有趣的事,MHA的作者:Yoshinori Matsunobu巨佬在bugs.mysql.com里吐槽:

1“目前MTS不支持slave_transaction_retries,但是我从在线文档里没有找到任何有关这个的讯息,
2而在rpl_slave.c中清楚的描述到:
3----
4/* MTS technical limitation no support of trans retry */
5if (mi->rli->opt_slave_parallel_workers != 0 && slave_trans_retries != 0
6----”

围观请看:

bug #68465:  

https://bugs.mysql.com/bug.php?id=68465

MySQL官方这个就让人很懵了,既然当时还不支持,手册上又没有,又有多少人遇到这个问题会去懂去源码描述。(源码里的确写了不支持)

当然在Yoshinori Matsunobu巨佬反馈后的几个月后,官方更新了手册:

1Thank you for your bug report. This issue has been addressed in the documentation. 
2The updated documentation will appear on our website shortly, 
3and will be included in the next release of the relevant products.

3)和XA事务有关的ERROR 1756

不太确定是否为bug,是否可复现。
提交“bug”的同学是一个中国人,有兴趣可以去看一下:
这个被MySQL官方技术支持大佬Umesh Shastry先生认定为Duplicate,即和1)中的问题重复。

bug #80180: 

https://bugs.mysql.com/bug.php?id=80180

写作3)仅为多一个在遇到ERROR 1756时的参考case。


ERROR 1755/1756 的总结:

避免跨版本的并行复制。(如果非要,关闭MTS)
升级到5.6.x的更高版本,避免使用老版本5.6的并行复制。
升级到5.7.x的更高版本,避免使用老版本5.7。



-- 可能感兴趣的文章

【MySQL】mysqldump备份失败与解决方案合集(下)

【MySQL】mysqldump备份失败与解决方案合集(上)

【MySQL】通过SQL_Thread快速恢复binlog




-- the end --





阅读原文查看历史推送。

文章转载自神谕的暗影长廊,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论