最近做了很多组基于并行复制(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会有不同)
错误提示很明显:
Cannot execute the current event group in the parallel mode
不能在parallel模式下执行目前的这个event组
在5.6作为slave也有可能遇到这个问题。
错误提示和原因显示很明白,关掉并行复制就可以了:
同样是1755报错,目前收集到日志中可能给出的reason有下面三个:
总结一下原因可以是:
在 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的复制分发对象被为“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的变量:
max_committed_transaction:记录上次提交事务的logical_clock,即last_committed。
transaction_counter:记录当前组提交中各事务的logical_clock,即sequence_number。
而5.6所产生的binlog是没有这些记录 的,作为slave的5.7 自然无法 基于logical_clock进行并行复制。
这种情况下,修正该问题就好说了:
不幸的是,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/
每组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 group in the 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;
- ...
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;
SET GLOBAL slave_parallel_type="DATABASE";
START SLAVE;
不幸的是,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/
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29773961/viewspace-2142050/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/29773961/viewspace-2142050/