一、 RDS常见问题排除及DAS自动弹性伸缩
通过对日常大量客户反馈的问题的分析,我们提炼了使用云上RDS数据库过程中3比较突出的问题。本文将围绕此三场景介绍问题的自助排查以及定位问题的方法。
对于连接类的问题,首先要明确访问链路的细节,包括客户端、客户端到RDS之间的网络以及RDS三个方面。比如客户端侧包含从哪里发起连接、用的什么RDS连接地址、客户端在哪里、网络的连通性或是否做了额外的限制导致无法连通。RDS侧包含是否添加安全组或白名单、连接数、连接地址等。另外,还包括数据库的账号密码是否正确、数据库的连接数是否有相应的限制等。
总结来说,客户端、客户端到RDS之间的网络以及RDS三者任意一者的配置不合理,都会导致连接可能出现问题。除了上图列出的因素,还有一些更细的影响因子,比如客户可能走的VPN方式访问,设置的MTU不匹配也可能会导致连接之后命令无响应。
如果一直连接不上,需要重点检查网络的连通性,比如连接地址是否正确、网络连接是否做了相关配置打通。
如果突然连接不上,也需要检测网络连通性;网络不通时,需要检查比如安全组、白名单的变更;网络连通的情况下,需要检查客户端与服务端的情况,比如实例的负载、客户端配置的连接池是否耗尽、服务端的连接数是否打满等。
如果是偶尔连接不上,则网络连通性大概率没有问题,更有可能是网络上或客户端和服务端的配置上出现了问题,比如服务端配置的timeout参数不合理,导致空闲太久被断开,客户端再次得到连接时可能会出现报错。
对于3种连接异常,可以使用ping、telnet、traceroute、mtr、tcpdump命令来诊断网络连通性、稳定性与连接报错。
一直连接不上或突然连接不上,首选ping与telnet来确认网络连通性;如果是偶尔连接不上,则推荐使用traceroute、mtr、tcpdump判断网络情况。
对于偶尔连接报错,一定要提前部署好抓包。复现问题后应第一时间将报文反馈给我们进行确认。
ping可以确认是否能够正常解析域名网络以及网络时延是多少。ping域名地址时,可以获取到对应的解析IP地址,判断IP地址是否正确。比如做了本地解析后,RDS变更导致底层的VIP发生了变化,如果还在本地做硬解析,则ping的地址还是之前的IP,导致连接不上。
Redis等内存型数据库对网络时延特别敏感,实例从ECS到RDS的SLB再到后端的DB,如果出现跨可用区访问,则时延会增加3ms左右。
连接不上时,可以用telnet查看端口是否通。使用telnet时,域名的后面要跟上数据库的端口,比如RDS默认端口为3306,如果在RDS控制台做了端口修改,也需要将此处的端口指定为修改后的端口。
在RDS侧做白名单拦截一般有两种方式,一种是在SLB做的,一种是在DB上做。在SLB上可能会出现telnet能通但实际连接不上的情况。
mtr用于追踪数据包的传输,判断路径中间是否出现丢包。一般会加上-n来避免反解析,-c用于指定发送的数据包数,-report可以以报告的形式输出,后面需要接上域名。输出结果的第一列为节点,第二列为节点对应的解析IP地址,第三列为丢包率,第四列为每秒发送的数据包,第五列为最近探测的延时值,第七列为标准方差,值越大证明节点的稳定性越差。
traceroute可以追踪数据包传输时的全部路径与时延。在一条路径上,每个设备会traceroute测试三次,输出结果包含每次测试的时间与设备的名称,一般也会加上-n反解析,-t表示走TCP协议,也可以指定为-i走ICMP协议,-p用于指定具体端口号。
网络重传、网络连接抖动等问题抓取,在Linux环境下一般使用tcpdump,windows环境下可以使用wiresarck,实际使用场景多为Linux环境部署的程序。
第一类使用场景为客户端程序报错日志指向不明确,没有将原始的MySQL报错信息展示出来,可以通过抓包的方式定位问题。第二类使用场景为偶尔连接不上或比较疑难的场景中,通常也推荐使用tcpdump。
tcpdump的使用步骤分为两步:
• 第一步,抓取报文。
• 第二步,分析报文。
抓取问题需要自己部署抓包命令,后续如果不具备分析报文的能力,可以将关报文在提交工单时与一并反馈,由我们助对报文进行分析。
抓取报文时需要注意3点:
• tcpdump要部署在存在连接问题的主机上。
• 出现问题前开始抓包,出现问题后停止抓包,要保证报文中出现异常时的报文。另外,程序最好将报错时间精确到秒级的日志打印出来,能够方便定位问题。
• 对低频报错的场景应提前部署循环抓包,但要避免单报文过大导致将磁盘打满。-i是指定端口,-s为0表示自动选择合适的长度抓取数据包,-w指将抓取的报文输出存放到该文件里,-c可以指定文件大小(-c 100表示文件大小为100M),-W指定文件数量 ,(-W 5表示循环写5个文件)。
过滤报文时会先进行快速过滤,一般对于有明显MySQL错误码的报文,可以通过mysql.error_code>0快速过滤;连接被重置的问题可以使用tcp.flags.reset=1的方式快速过滤。
如上图红框,服务端3306端口给客户端发的fin结束连接的报文与上一个时间相差了30秒。客户端在服务端设置了wait_timeout=30,空闲连接达到30秒后,服务端会进行回收连接。
如上面截图执行ping命令,如果能连通则可以获取到时延、IP;如果无法连通,则需要检查网络问题,比如网络连通性、域名解析正确性等。像做了本地解析后当底层VIP发生变化,此时如果再连接RDS实例,则必然连接不上。
如果此时进行telnet,也会显示不通,因为进行了本地解析。将1.1.1.1修改后再做telnet即可。
执行mtr命令时,会在全部探测完之后才以报告的形式输出。重点关注是否从某一跳以后持续性地出现丢包,如果是,再从标准偏差的数值进行具体判断。如走到外部网络运营商环境,则需要向网络运营商反馈。
traceroute时中间出现若干行并无大碍,可能是由于网络运营商做了屏蔽,不会返回数据。最后目标端的数据正常则说明没有问题。