配置Mysql Group Replication遇到的问题笔记
一
在配置第一台服务器
START GROUP_REPLICATION;
后出现以下问题:
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。