SQL SERVER2014 alwayson 的一次完美的雪崩

今天注定是一个值得深思的日子,下午两点左右陆续有同事说测试cms打开非常慢,测试环境无法下单,测试环境……,然后有同事在群里面截图,一看大家瞬间秒懂数据库超时,有同事立刻猜测是不是测试环境数据库挂了其实从上班开始我已经收到告警邮件,等待进程已经超越阈值,而且在不断堆积。我的监控显示如下:
在这里插入图片描述
打开监控一看,感觉不妙,从早晨到现在磁盘IO尽然一直都稳定在100M每秒,这是什么概念,而就在大家反馈各种问题之后磁盘IO开始下降,物理已用内存也已经99% ,监控如下:
SQL SERVER2014 alwayson 的一次完美的雪崩_第1张图片
。此时心中已经开始万马奔腾,我意识到一定是发生了资源被锁的情况,立刻查看数据库锁情况,一看有那么两张表的锁类型是ix锁,简单来讲就是在一个房间门口放一个标记告诉外面的人这个房间我已经住下了,外面的人不要进来了想进来可以先在外面排队等着吧,等我出来了才能进来下一个。我立刻拿被锁资源的objectid查看是哪个表被锁住了,结果有点似曾相识,又很无奈,我们的通用日志表和自动化任务表被锁住了,被加锁其实是一件非常正常的事情,但是长时间被同一个事务加锁就不正常了。依稀记得日志表的资源争抢曾几何时发生过,日志表为什么会被长时间加锁,说明此时有大量数据被写入数据库,也许是有项目在做导入功能的测试,也许是周边系统在同步数据这些操作在平时的开发测试过程中属于正常的工作范畴,无可非议。但是按理来说测试环境要达到100M/S的磁盘IO是非常困难的,既然是日志表被锁,我立刻通知开发同事将日志接口关闭,测试环境各系统随即逐渐恢复。然后我仔细分析了记录的日志,由于日志表锁的资源争抢,导致部分项目日志写入等待,如全量缓存、wms、scm、U8等系统与oms系统交互的自动化服务无时无刻都在循环跑着。由于无法及时将日志写入磁盘,达到服务超时时间,出现超时错误,然而超时也是一条日志,这样就循环生产很多超时日志,同样超时日志也写入不了日志表,从而因为超时导致任务失败,经过查看确实在5:00:00点到14:00:00点之间日志表没有任何日志,而我们系统很多流程都必须写入日志后才能成功提交,这就是为什么很多同事反馈整个系统都有问题不正常的原因。
当磁盘非常繁忙的时候任何写入都有可能等待,一旦系统的共享资源被锁会引发系统中与共享资源相关的数据同时无法被写入磁盘,从以上磁盘监控截图可以看出,当磁盘IO下降的时候即共享资源被锁时,等待的任务直线上升,并且不断堆积,导致内存中堆积的数据越来越多,可用的物理内存几近耗尽。当我登录服务器的时候发现服务黑屏很长一段时间才响应,我点击了几下鼠标发现它根本不想理我,系统苟延残喘,这是一个接近假死的状态,这一现象其实十分危险,因为服务器似死非死,但其实已经无法响应其它请求,而这种情况并不能触发故障转移。但监控系统往往会因为系统长时间无法响应而报服务器已经故障,这是多么让人蛋疼的事情。从这次事故来看,单从某一个项目来分析,每个项目都没有问题,项目大批量导数据、同步数据、写日志等都非常正常,但是我们如果只从一个项目看问题那么一叶足以障目。当我们的系统非常庞大了之后,就需要综合考虑问题,是否存在一个问题引发蝴蝶效应进而导致数据库雪崩的隐患。
这里有两种方案:
第一、 作为一个DBA传统的思路是分表、分库,不同的项目尽量使用不同的库,不同的表,不同的日志类型写入不同的表,尽量不资源共享也算是一种解耦,如果资源允许可以将不同的项目使用不同的服务器,即使一个项目被写挂了也不至于影响其它数据库服务器;
第二、作为一个有几年经验的it人员,不建议所有数据都写入数据库,比如日志数据,可以对日志进行细分部分日志可以写入文本,然后通过工具接入专业的日志平台,另外为了缓解写入压力可以考虑消息队列等缓冲机制来缓解数据库的IO压力,目前我们很多周边系统与核心数据的交互都是硬着陆的方式,这也是一大隐患,没有缓冲意味着没有合理的管控,容易引发不约而同的联合攻城现象,就如同今天发生的情况一样,我们不能很好的感知到服务器的压力,不能很好的管控系统对数据库的读写。
不过值得庆幸的是在我们CTO 的大力推动下我们的生产环境对系统日志的改造终于已经接近第二种方案,数据库的压力得到有效降低。

你可能感兴趣的:(技术类)