MySQL:新的MGR MySQL协议报错BUG

2024年 6月 12日 113.3k 0

作者简介:高鹏,笔名八怪。《深入理解MySQL主从原理》图书作者,同时运营个人公众号“MySQL学习”,持续分享遇到的有趣case以及代码解析!

问题

这个问题,在线上环境偶尔遇到如下错误,甚至偶尔连主节点的bootstrap都不行,报错大概就是如下,

2024-05-22T11:53:07.919600+08:00 0 [ERROR] [MY-013780] [Repl] Plugin group_replication reported: 'Failed to establish MySQL client connection in Group Replication. Error establishing connection. Please refer to the manual to make sure that you configured Group Replication properly to work with MySQL Protocol connections.'
2024-05-22T11:53:07.919780+08:00 0 [ERROR] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] The group communication engine failed to test connectivity to the local group communication engine on 192.168.1.86:3320. This may be due to one or more invalid configuration settings. Double-check your group replication 
local address, firewall, SE Linux and TLS configurations and try restarting Group Replication on this server.'

这个报错其实不太明显,我们检查所有的防火墙,SE Linux 和 SSL配置等都没有问题。而我自己模拟的时候,只能关闭掉数据库的SSL支持,然后MGR 使用SSL连接,这个肯定报错,如下,

first,skip ssl ,add tls_version='' in my.cnf to disable ssl .

| have_openssl                                      | DISABLED        |
| have_ssl                                          | DISABLED        |

use mysql 

| group_replication_recovery_use_ssl                  | ON       |
| group_replication_ssl_mode                          | REQUIRED |
| group_replication_communication_stack               | MYSQL                                |
| group_replication_group_seeds                       | 192.168.1.84:3320,192.168.1.85:3320  |
| group_replication_local_address                     | 192.168.1.86:3320                    |

boot first node
set global group_replication_bootstrap_group=on;
start group_replication;

这样就会有类似的报错,但是报错视乎不太明显,当我们使用xcom协议的时候,报错变得很清晰,

2024-05-23T21:30:06.935157+08:00 0 [ERROR] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] TLS version is invalid: '
2024-05-23T21:30:06.935239+08:00 0 [Note] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] Error initializing SSL'
2024-05-23T21:30:06.935355+08:00 9 [ERROR] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] Error starting SSL in the group communication engine.'
2024-05-23T21:30:06.956616+08:00 9 [ERROR] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] Error initializing the group communication engine.'
2024-05-23T21:30:06.977953+08:00 9 [ERROR] [MY-011674] [Repl] Plugin group_replication reported: 'Unable to initialize the group communication engine'
2024-05-23T21:30:06.977998+08:00 9 [ERROR] [MY-011637] [Repl] Plugin group_replication reported: 'Error on group communication engine initialization'
2024-05-23T21:30:06.978025+08:00 9 [Note] [MY-011649] [Repl] Plugin group_replication reported: 'Requesting to leave the group despite of not being a member'

相关原理

实际上MGR在传递消息给底层XCOM的时候,首先会通过mysql的gcs层将消息打包好,然后传送给本地的XCOM,因为是本地传输,因此消息只需要放入队列就好了,然后通过pipe传递一个消息,然后XCOM收到这些消息后会走paxos协议传递到远端的各个节点,这个地方是需要走网络socket的,而scoket到底走不走ssl协议则是参数group_replication_ssl_mode和group_replication_recovery_use_ssl控制的,如果我们不想MGR连接使用SSL协议可以考虑设置这两个参数为,

  • set persist group_replication_recovery_use_ssl=off;
  • set persist group_replication_ssl_mode=disable;

这是老的方式,叫做XCOM协议。而到了8027,新增了一个参数group_replication_communication_stack(参数默认还是XCOM协议),其可以设置为XCOM何MYSQL,新的MYSQL协议实际上就是在我们上面说的底层XCOM互联的时候使用mysql自己的协议来连接,传输的数据都需要额外封装一层mysql协议,我们可以看看下面的图,发现XCOM的sender_task在连接初始化连接的时候带了mysql的协议,包含了用户名和密码,用的是我们的recovery通道的用户,

MySQL:新的MGR MySQL协议报错BUG-1

MySQL:新的MGR MySQL协议报错BUG-2

而到了shell的8031左右,搭建cluster group_replication_communication_stack参数更是会被默认的设置为MYSQL协议,也就是说如果使用cluster在不注意的情况下group_replication_communication_stack已经变成了MYSQL协议,而不是我们传统的XCOM协议,XCOM协议我们已经用了很久了,貌似更稳定一些。

当然MGR在初始化的时候就会进行连接的探测,如果报错提前报错出来,不至于到了XCOM进行连接发送消息的时候才报错,而且会探测所有的本地节点和远端节点,只要不能连接就会报错,大概在这个地方,

MySQL:新的MGR MySQL协议报错BUG-3

而我们看到XCOM协议报错是比较明显的,而MYSQL协议报错报得不明不白,同时我们考虑使用XCOM协议的时候没有类似问题,因此感觉大概率为封装xcom消息封装MySQL协议后出现的问题。

MySQL协议的握手信息溢出情况

这个问题就是在对上面问题进行debug的时候发现的,大概如下,

<code class="language-js_darkmode__21">Old value = 63487
New value = 18446744072098936831
csm_parse_handshake (ctx=0x7fff027f2ff0) at /pxc/mysql-8.0.36/sql-common/client.cc:6858

code,
 mysql->server_capabilities |= uint2korr((uchar *)end + 5) << 16;

这里有一个明显的溢出,这里就是进行MySQL协议握手的时候客户端接收到服务端的握手信息后解包得到服务端的信息的时候,其中包含了服务端是否支持SSL连接。

如何解决

这个问题我们可以考虑切换为老的XCOM协议看看是否问题还存在,如下

set persist group_replication_communication_stack='xcom';
set persist group_replication_group_seeds='192.168.1.85:33201,192.168.1.84:33201,192.168.1.86:33201';
set persist group_replication_local_address='192.168.1.86:33201';

同时搭建cluster的时候可以指定一下使用XCOM协议。

BUG

最后将一些信息提交给了官方如下, https://bugs.mysql.com/bug.php?id=115087&thanks=4

当然如果有能稳定重现的方式,也可以告知一下。

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论