一、环境说明
应用系统:M域管理信息**系统
数据库系统:MySql 5.7.27 3台数据库主机
二、Mysql高可用方案
考虑数据库高可用性,在主库出现 (主机/操作系统/存储) 问题,**系统Mysql数据库采用一主两从的模式,主节点运行主实例,另外两个节点各运行一个从实例,实时与主库进行同步。当主节点服务器因掉电、网络延迟等因素未能连接主库时,会将其中一个从库自动切换成主库继续提供服务。前端应用通过RDS的VIP连接数据库访问,切换期间会有数据库 1-30 秒的连接闪断,应用程序应支持自动重连功能。具体的架构示意图如下:
三、真实问题场景
问题场景:**系统在12月21日16点左右,数据库发生主从切换,通过应用服务管理平台、登录异常数据库服务器以及通过本地客户端访问等多方查看主从库状态,验证数据库对外提供服务的能力。
应用进程有连接数据库失败现象,情况如下:
问题溯源:
1)主从切换原因
16点30分左右出现IO访问过大异常情况,造成从库出现同步延迟,RDS中间件检测到超过3S未能连接到主库,发生切换。IO访问过大如图:
16:40分左右发生主从切换,切换成功(新高可用主从关系异常)可对外提供服务。切换日志,如下:
通过应用服务管理平台界面可以看到数据库实例状态情况,如下:
2)应用连接异常原因
原因一:Mysql数据库高可用主从切换过程中业务进程会访问异常,切换完成后服务自动恢复。
原因二:应用程序操作数据库的连接池是持久的,当数据库发生切换时没有重试机制,无法检测连接池中的连接是否有效,无法自动恢复,必须重启才能重连数据库。数据库RDS中间件在16:52主从切换完成后,RDS到数据库的连接仍存在,连接数据库的请求还是初始化的连接。
3)新高可用主从关系异常原因
在主从发生切换的过程中,新从库有新的事务,造成主从的事务号不一致。解决方案如下:
3.1新从库上执行以下命令, 记录gtid_executed的值
show global variables like '%gtid%'\G*************************** 3. row ***************************Variable_name: gtid_executed Value: 2c076fcc-aa42-11e9-a65e-287b09c12167:1-89161795,88ea51ce-aa43-11e9-8c3d-287b09c1e17b:1-72789301
3.2新主库上执行以下命令, 记录gtid_executed的值
show global variables like '%gtid%'\G*************************** 3. row ***************************Variable_name: gtid_executed Value: 2c076fcc-aa42-11e9-a65e-287b09c12167:1-89161777,88ea51ce-aa43-11e9-8c3d-287b09c1e17b:1-72789301
3.3新从库上执行以下命令,停止同步线程及重置同步相关信息
mysql> stop slave; -- 关闭从复制mysql> reset slave; -- 重置从mysql> reset master; -- 重置主,清空从的gtid_executed
3.4新从库上设置gtid_purged调整新从库已执行的gtid。
mysql> set global gtid_purged='2c076fcc-aa42-11e9-a65e-287b09c12167:1-89161777,88ea51ce-aa43-11e9-8c3d-287b09c1e17b:1-72789301';
注意:设置gtid_purged值时,gtid_executed值必须为空否则报错,该值清空的方法就是reset master命令。
3.5重新开启同步
mysql> change master to master_host='10.253.24.208',master_port=4909,master_user='universe_op',master_password='************(密码)',master_auto_position=1;mysql> start slave;
3.6开启新从库的高可用配置
四、问题总结与思考
1)建议在数据库连接池druid中,通过设置testWhileIdle=true来开启访问异常重连机制,同时durid在1.1.5版本以下, 存在testWhileIdle在某些情况下失效的bug问题,建议升级到1.1.5版本以上。
2)通过设置druid连接池remove-abandoned-timeout参数,强制回收时间,从而提升控制自动恢复时长。