在配置第一台服务器

START GROUP_REPLICATION;

后出现以下问题:

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
ERROR 3092 (HY000): The server is not configured properly to be an active member of the group. Please see more details on error log.

发现,本机无法ping通,修改/etc/sysconfig/network-scripts/ifcfg-eth0(eth0为你上网用的网卡),设置好本机ip、子网掩码、网关,之后重启network就行

二、第二台服务器一直处于RECOVERING状态

这个问题比较复杂,很有可能是因为出现一些错误情况导致服务器之间连接不成功,一般MySQL会尝试连接10次,之后后起的服务器会处于ERROR状态。

一旦一个实例进入ERROR状态,该实例super_read_only选项被设置为ON。要离开ERROR 状态,必须手动配置实例super_read_only=OFF。

情况1:

防火墙和selinux没关,这是小问题,关掉就行。

情况2:

两台服务器主机名相同,mysql无法通过DNS找到对应服务器。

解决方法:
在my.cnf文件中设置

report-host=192.168.50.22 #后面跟的ip是本机的ip

或者取消掉mysql通过DNS查找服务器的策略,当然,也可以修改hosts文件,方法网上可以找到的。当然,最好是设置report-host。
还有server_id每台服务器一定要不同。

情况3:

查看mysql日志,发现两台服务器直接一直在尝试连接,一直连接不上。尝试10次之后,变成ERROR状态。

VM Ware的锅,概率不高。

然后我运气不好,碰到了,折磨了我一个星期,网上根本找不到解决方法,最后换成VirtualBox就好了,实际生产环境应该不会有这么坑爹的问题,大概是VM Ware虚拟机网络通信机制的问题,猜测可能还有防火墙,同事用VM Ware做成功了,大概是版本问题或者其他的,具体原因查不出来。

我后来在用一个纯净的基本没有自配的服务的centos镜像在VM Ware下装机,连网卡都启动不来后才猜出来的,然后毅然下了个VirtualBox,重新配,就没问题了。

初步觉得可能是管理员权限的原因,VM Ware和Win 10都该背锅。

情况4:

加载的sql查询文件语法不兼容组复制,例如建表没有主键,创建的带返回值的函数没有声明DETERMINISTIC之类的,查MySQL日志大概能查出来。

如果用虚拟机模拟组复制,那么,最好不要直接克隆一台已经配置好的虚拟机,至少,不能克隆已经初始化了mysql的虚拟机,不然会造成两台服务器的MEMBER_ID相同,导致两台服务器无法找到对方。

四、自增量

如果在数据库内使用到了自增的字段,最好在/etc/my.cnf中添加auto_increment_increment、auto_increment_offset两个参数,防止发生事务冲突(MGR其实本身就有防止自增量事务冲突的能力,运用了GROUP_REPLICATION_AUTO_INCREMENT_INCREMENT这个参数,但如果不去手动设置,自增量的间隔会非常奇怪)。

auto_increment_increment为自增量的间隔,auto_increment_offset为自增量的初始位置。

从官网查到的文档上,建议最好为:

auto_increment_increment=n(组内成员数)
auto_increment_offset=server_id(这里的server_id最好为1,2,3这样的自增量,且每台都不同)

这样肯定能解决事务冲突的问题,但是,这样,为了让自增量每次都是+1,必须得DB1插表,然后DB2,接着DB3...如果一直是DB1(或者任意一台组内的服务器)插表,会导致自增量每次是+n。如果有强迫症,会很难受...

网上也有这么做的:

auto_increment_increment=1
auto_increment_offset=2

这样,我们做MGR的时候也试过,还试过auto_increment_offset等于其他大于1的值,基本上自增量每次都是+1,也没有出现事务冲突,凑合着是可以用的,但逻辑上有点奇怪,不知道会不会有隐藏的问题。

至于

auto_increment_increment=1
auto_increment_offset=1

这样的做法,肯定是哪位老哥用官网上的做法写的DB1示例后,被人各种无脑Ctrl+C、Ctrl+V之后的做法。

这样会导致每次自增的间隔为7,不论在哪台服务器上。

至于为什么会这样,貌似是GROUP_REPLICATION_AUTO_INCREMENT_INCREMENT这个参数默认是7,而MGR默认的规避自增量导致的事务冲突的方式中auto_increment_increment=GROUP_REPLICATION_AUTO_INCREMENT_INCREMENT。

这样做,还不如用官方提出的设计。

现在,我们在公司里,用的是:

# auto_increment_increment=1
auto_increment_offset=9

这里auto_increment_increment参数被我们注释掉了,在测试的时候基本也没出问题,不知道到时候到生产环境会怎样。

自增字段的大小依赖于group replication组中成员的多少。

auto_increment_offset值,最好是大于等于组内成员数,如果段的大小等于组内成员的数量,则所有的自增值都会被使用。

auto_increment_offset值小于组内成员数,我们有试过,不过不知道是我们测试的虚拟机数量太少,还是情况考虑的不周,暂时没什么问题,不过以防万一,还是不要这么操作。

关于组复制设置自增量间隔,推荐可以看:

WL#8445: Group Replication: Auto-increment configuration/handling

笨小孩的dba之路-MySQL group replication介绍

还有自行Google,至于百度就算了,没什么用。

五、设置read_only

因为以默认的方式(不设置loose-group_replication_single_primary_mode=FALSE)启动组复制时后起服务器没用写的权限,所以要在MySQL shell上输入

set global read_only=0;

不过,最好在服务器ONLINE之后再执行,不然,同步会出现问题。

查看日志/var/log/mysqld.log,大量出现:

[ERROR] Plugin group_replication reported: 'Transaction cannot be executed while Group Replication is recovering. Try again when the server is ONLINE.'
[ERROR] Run function 'before_commit' in plugin 'group_replication' failed

当然这样依然有概率能ONLINE,不过比较浪费时间,而且也有很大概率失败。

所有生产环境最好不要在服务器RECOVERING时设置read_only=0。

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄