很是抱歉!今天 12:03-12:52 ,因为数据库链接数异常突增超过1万,达到了阿里云RDS的最大链接数限制,影响了全站的正常访问。由此给您带来麻烦,请您谅解。html
在发现数据库链接数突增的问题后,咱们一开始怀疑多是咱们的某些应用中产生太多ADO.NET链接引发的,可是对嫌疑的应用们进行重启后,链接数依然高居不下。数据库
后来,咱们回想起去年9月份遇到的一次数据库问题,当时不少数据库查询超时,IOPS突增达到RDS的最大限制。开始咱们也是从应用层面下手,但怎么也解决不了,后来实在没办法,试了试主备库切换,切换后立马神奇地恢复正常,而后就一直相安无事,直到今天。服务器
今天咱们再试试这一招吧!12:38开始进行主备库切换,12:52左右链接数降到了1000如下,全站访问恢复正常,这一招又一次神奇地发挥了做用。ide
恢复正常后,咱们分析了一下对应的应用日志。post
在出现故障以前应用日志就已经记录了一些数据库查询超时:阿里云
System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. This failure occured while attempting to connect to the Principle server. ---> System.ComponentModel.Win32Exception (0x80004005): The wait operation timed out
在故障期间出现了大量下面的错误日志:url
1)没法与阿里云RDS创建TCP链接3d
System.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)
2)达到ADO.NET链接池的最大链接数限制日志
System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
3)达到阿里云RDS的最大链接数限制,被拒绝登陆code
System.Data.Entity.Core.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Logon failed for login 'xxx' due to trigger execution.
将这些错误日志联系起来,咱们推断数据库链接数过万并非应用中真的产生了大量的数据库链接(并且发生的时间点是在午餐时间的访问低峰),而是RDS出现了咱们所不知道的情况,形成大量数据库操做没法正常按时完成,所占用的数据库链接不能快速释放,或者甚至是创建或释放数据库链接操做自己出了问题,形成数据库链接愈来愈多。
看一下RDS的链接数在7天内的监控图(见下图),从4.2开始,链接数就开始异常,4.2-4.4天天的访问量要明显低于3.31-4.1,然而4.2的链接数居然高于3.31,以后愈来愈来高。可能咱们所用的RDS实例在4.2开始出现异常情况。
主备库切换是将当前的RDS实例切换到了另一台数据库服务器上,切换后当即恢复正常也说明了以前RDS实例所在的服务器出了情况。并且,在今天下午的访问高峰,在切换后的新服务器器上的最高链接数不超过3000。
虽然咱们的推断只是没有足够证据的猜测,虽然阿里云坚定认为是咱们的应用产生了过多的数据库链接,但咱们依然坚持对这个问题的推断——是RDS的问题(注:后来事实证实是咱们推断错了,不是RDS的问题,是微软.NET Core的一个bug引发的,详见后续博文)。咱们没法去验证本身的推断,咱们没法躲避下次的一样问题,但幸亏还有个救命稻草——主备库切换,比提交工单还有效的救命稻草,当咱们急如燃眉地提交工单,等收到回复时,咱们已经完成了主备库切换,恢复了正常。
【更新】
这个问题的后续进展详见 数据库链接数过万的真相,从阿里云RDS到微软.NET Core