翻译|节假日处理数据库集群异常小记


翻译|节假日处理数据库集群异常小记

文章图片


今天还在假期状态中 , 大概在10:30左右的时候 , 收到一条短信报警 , 提示一个数据库集群的中间件内存报警了 , 但是不到1分钟的时间 , 就提示报警恢复了 , 但是在11:00左右的时候 , 接到了研发同学的反馈 , 说这个数据库集群的只读服务貌似有些问题 , 想让我帮忙看一下到底有什么问题 , 整个集群的架构模式类似下面的形式 , 现在提示是黄色部分的只读数据库中间件有问题 。


因为节前也做了巡检 , 而且这个只读服务已经运行了很长时间了 , 差不多有3年以上 , 所以我对于这个问题的初步印象是数据库中间件异常 , 通常是一些大查询导致的内存异常 , 应该重启一下就可以了 , 本来打算是让同事去处理一下的 , 过节了还是自己上吧 。
因为涉及的是只读节点 , 对于线上业务是没有直接影响的 , 所以处理问题的方式会和读写节点的方式有一些差别 。
登录到了服务器端之后 , 发现问题现象比较蹊跷 , 首先是我通过本地登录的方式尝试连接到数据库中间件 , 但是出现了卡顿 , 迟迟没有进入命令行 , 我想这个可能是内存的问题 , 因为之前在其他环境出现过类似的中间件假死的状态 , 需要重启一下中间件 , 所以重启后继续验证 , 发现问题没有改善 , 查看中间件日志 , 提示客户端的一些连接是异常的 , 而且从之前的日志中发现在今天是触发了一次OOM导致内存异常 。
于是开始分析是不是系统层出现了问题 , 比如内存使用率等等 , 但是查看系统负载和磁盘 , CPU等使用情况没有发现明显的异常 , 所以关注点还是在中间重启 , 比如kill掉多余的进程进行重启 , 但是重启无果后 , 准备进行终极大杀器-重启服务器 。
在重启服务器之前和系统的同事也打了招呼 , 避免出现服务器无法启动的尴尬场景 , 重启的过程很顺利 , 但是中间件的服务状态还是依旧 , 依旧是卡 , 情况在一些停顿之后有一些改善 , 没有那么卡了 , 但是实际测试的时候 , 连接到中间件使用show processlist等命令均产生了卡顿无响应 。
所以这个时候的关注点开始下移 , 我开始关注中间件的配置文件是否有变化 , 或者是自动化运维任务做了调整等 , 这个时候我从历史的备份中开始比对配置文件的变化情况 , 在做了多重备份之后 , 使用昨天的配置文件覆盖了今天的 , 但是重启之后依旧无果 。

在多次查看日志无果的情况下 , 我在怀疑是不是防火墙产生了异常 , 比如有的服务以前是长连接 , 如果中间件异常后尝试重连 , 理由感觉很牵强而且不够严谨 , 但是还是试着做了这样的尝试 , 显然没有效果 。  

所以到了这个时候 , 已经做了很多尝试 , 但是效果都不明显 , 于是开始认真查看日志的异常情况 , 是否是数据节点出现了问题 , 逐一检查了配置和负载都没有发现异常 , 这个时候我开始从一些不明显的异常日志入手 , 比如提示中间件连接数据节点的时候连接被拒绝和关闭 , 于是我开始仔细的通过mysql命令测试真实的连接情况 。
配置文件中的信息如下:
<dataHost name=\"localhost4\" maxCon=\"1000\" minCon=\"10\" balance=\"0\"                writeType=\"0\" dbType=\"mysql\" dbDriver=\"native\" >                <heartbeat>select user()</heartbeat>                <writeHost host=\"hostM4\" url=\"xxxxx:3309\" user=\"xxxx\"                       password=\"xxxx\">                </writeHost>        </dataHost>
经过测试和比对 , 发现中间件竟然连接不到数据节点 , 提示是密码错误 , 感觉就像数据库中间件和数据节点没有做任何配置一样 。
mysql -uxxxx -pxxxx -hxxxx -P3309Warning: Using a password on the command line interface can be insecure.ERROR 1045 (28000): Access denied
这个测试情况让我大感吃惊 , 但是问题的方向已经基本明确了 , 所以和研发同学初步沟通了问题预计的处理策略和时间 , 就开始处理这个问题了 , 我逐个在数据节点的从库服务器端比对了数据库账号情况 , 发现这个账号的配置竟然在好几年前就失效了 , 通过数据库账号的配置发现原来的数据库账号只配置了读写中间件的IP , 但是没有只读中间件的IP 。