• ADADADADAD

    【MySQL】5.6/5.7并行复制bug导致的故障 ERROR 1755/1756[ mysql数据库 ]

    mysql数据库 时间:2024-12-03 12:15:07

    作者:文/会员上传

    简介:

    最近做了很多组基于并行复制(MTS)的主从,其中大多数为5.6->5.7的结构,少部分5.6->5.6的并行复制。
    每组m-s结构配置相近,有一定几率出现如下错误,但不是全部出现:

    〇 ERROR 1755:

    以下为本文的正文内容,内容仅供参考!本站为公益性网站,复制本文以及下载DOC文档全部免费。

    最近做了很多组基于并行复制(MTS)的主从,其中大多数为5.6->5.7的结构,少部分5.6->5.6的并行复制。
    每组m-s结构配置相近,有一定几率出现如下错误,但不是全部出现:

    〇 ERROR 1755:
    错误场景:
    Master(5.6) -> Slave(5.6/5.7)

    相关配置:
    Slave开启并行复制:
    slave_parallel_workers>=1。

    Slave报错信息:(此处是5.7的Slave,5.6也类似,但reason会有不同)
      …… Slave_IO_Running: Yes
      Slave_SQL_Running: No
      ……
      Last_Errno: 1755
      Last_Error: Cannot execute the current event group in the parallel mode. Encountered event Gtid, relay-log name {目录}/relaylog/mysql-relay.000002, position 280408 which prevents execution of this event group in parallel mode. Reason: The master event is logically timestamped incorrectly.. ……
      Last_IO_Errno: 0
      Last_IO_Error:
      Last_SQL_Errno: 1755
      Last_SQL_Error: Cannot execute the current event group in the parallel mode. Encountered event Gtid, relay-log name {目录}/relaylog/mysql-relay.000002, position 280408 which prevents execution of this event group in parallel mode. Reason: The master event is logically timestamped incorrectly..
      Replicate_Ignore_Server_Ids:
      ……

    错误提示很明显:
    Cannot execute the current event groupinthe parallel mode
    不能在parallel模式下执行目前的这个event组

    在5.6作为slave也有可能遇到这个问题。


    错误提示和原因显示很明白,关掉并行复制就可以了:
      STOP SLAVE;
      SET GLOBAL slave_parallel_workers=0;
      START SLAVE;

    同样是1755报错,目前收集到日志中可能给出的reason有下面三个:
      ① Reason:The master event is logically timestamped incorrectly(这个可能也和在5.7上设置slave_parallel_type="LOGICAL_CLOCK"有关)
      ② Reason: possible malformed group of events from an old master
      ③ Reason:the events is a part of a group that is unsupported in the parallel execution mode.

    总结一下原因可以是:
    在5.6老版本->5.6新版本/5.7的复制结构下,master的event没有记录并行复制的相关信息。

    在Slave为5.6和5.7下均有出现的可能,已经被认作是个BUG,可以参考:
    https://bugs.mysql.com/bug.php?id=71495
    https://bugs.mysql.com/bug.php?id=72537



    〇 ERROR 1756
    错误场景:
    Master(5.6) -> Slave(5.7)

    相关配置:
    Slave开启并行复制:
    slave_parallel_workers>=1。
    slave_parallel_type='LOGICAL_CLOCK'。

    与1755不同的是,出现1756错误的可能性似乎更多。

    Slave报错信息:
      …… Slave_IO_Running: Yes Slave_SQL_Running: No……Last_Errno: 1756
      Last_Error: … 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).
      …… Last_SQL_Errno: 1756
      Last_SQL_Error: … 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). ……
    此处报错原因:
    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的变量:
      class MYSQL_BIN_LOG: public TC_LOG
      {
      ...
      public:
      /* Committed transactions timestamp */
      Logical_clock max_committed_transaction;
      /* "Prepared" transactions timestamp */
      Logical_clock transaction_counter;
      ...
    max_committed_transaction:记录上次提交事务的logical_clock,即last_committed。
    transaction_counter:记录当前组提交中各事务的logical_clock,即sequence_number。

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

    这种情况下,修正该问题就好说了:
      STOP SLAVE;
      SET GLOBAL slave_parallel_type="DATABASE";
      START SLAVE;
    或者关闭并行复制也可以,即如1755一样,设置slave_parallel_workers=0;
    不幸的是,1756错误发生不止这一种原因。

    更多可以参考:
    https://bugs.mysql.com/bug.php?id=69369
    https://bugs.mysql.com/bug.php?id=77239
    ………………

    其中一个比较有趣的是,MHA作者Yoshinori Matsunobu也遇到了ERROR 1756:
    https://bugs.mysql.com/bug.php?id=68465
    其原因是并行复制并不支持“slave_transaction_retries”

    他在rpl_slave.cc发现了该描述:
    ----
    /* MTS technical limitation no support of trans retry */
    if (mi->rli->opt_slave_parallel_workers != 0 && slave_trans_retries != 0


    复现操作:
    1.将slave_transaction_retries设置为一个较高的值
    2.开启并行复制:slave_parallel_workers>=0
    3.在slave上,对t1表持有一个较长时间的InnoDB锁,比如BEGIN; UPDATE t1 SET a=100;
    4.在master上执行一个冲突的语句并提交传输到slave上,比如UPDATE t1 SET a=100 WHERE id=1;

    这个bug所造成的ERROR 1756已经在5.7.5被修复。


    关于ERROR 1755/1756总结一下:
    避免跨版本的并行复制。
    升级到5.6.x的更高版本,避免使用老版本5.6的并行复制。
    升级到5.7.x的更高版本,避免使用老版本5.7。


    〇 参考文档

    MySQL 5.7并行复制实现原理与调优 by 姜承尧
    从MySQL 5.6到5.7复制错误解决 by 佚名
    https://bugs.mysql.com/


    【MySQL】5.6/5.7并行复制bug导致的故障 ERROR 1755/1756.docx

    将本文的Word文档下载到电脑

    推荐度:

    下载
    热门标签: 17551756error