MySQL 5.7 Bug slave_compressed_protocol 与半同步复制同时开启,导致主库写入卡住

MySQL 5.7 同时开启半同步复制和复制压缩协议slave_compressed_protocol=ON,会触发MySQL Bug,导致主库事务提交卡住。

一、环境配置:
  • MySQL 5.7.19 1主2从
  • slave_compressed_protocol=ON
  • 主库:rpl_semi_sync_master_enabled=ON,rpl_semi_sync_slave_enabled=OFF
  • 从库:rpl_semi_sync_master_enabled=OFF,rpl_semi_sync_slave_enabled=ON

为了验证效果,将半同步超时参数设置大一点。
rpl_semi_sync_master_timeout=1000000

二、Bug验证

往主库写入数据,会卡住,大概30秒后,才写入成功。

mysql> insert into tb select 6;
Query OK, 1 row affected (31.78 sec)
Records: 1  Duplicates: 0  Warnings: 0

在从库上检查写入的数据确实已经复制到了从库,进一步发现,数据复制到从库,并不需要等30秒,在主库提交后,几乎立刻就能复制到从库,但是主库始终会卡30秒左右,才显示提交成功。

查看主、从库的错误日志,发现如下:

2020-02-14T15:52:11.278985+08:00 0 [ERROR] Read semi-sync reply magic number error
2020-02-14T15:52:11.280066+08:00 0 [ERROR] /usr/local/mysql/bin/mysqld: Got timeout reading communication packets

网上搜索,发现这个Bug早已存在,见地址:https://bugs.mysql.com/bug.php?id=86230

简单地说,就是主库的半同步接收ack的线程无法识别复制压缩协议,一直等待半同步ack,直到超时或者heartbeat心跳。好在官方在8.0.4和5.7.21中修复了这个Bug。

之前提到主库会等30秒才显示成功,为什么是30秒,这个30秒与哪个参数有关?经过排查,最终发现30秒与参数
master_heartbeat_period有关,调整该参数到60秒,发现主库写入数据等待60秒才成功。

change master to master_heartbeat_period=60;

mysql> insert into tb select 11;
Query OK, 1 row affected (1 min 1.82 sec)
Records: 1  Duplicates: 0  Warnings: 0
三、结论:

slave_compressed_protocol 与 半同步一起使用会触发Bug,如果想规避该Bug,如下建议,任选其一:

  • 不开启复制压缩协议
  • 不开启半同步复制
  • 升级MySQL版本到 5.7.21 及以上,或者 8.0.4 及以上。

文章评论

0条评论