线上问题总结及心得-数据库磁盘爆满问题排查及解决方案

前段时间搞活动,一天早上服务器突然宕机了,于是开始紧急排查问题。开始以为是服务挂了,于是把服务挨个重启,但重启后问题依旧,考虑可能是数据库出问题了,一查发现数据库的磁盘满了,找到运维临时挂了一块200G的磁盘,服务器才恢复正常了,但是磁盘的使用率继续在以5分钟/G的速度增长着,这个情况依然是岌岌可危,看来必须要找到数据暴增的根本原因才行。开始分析项目中哪些业务是最频繁的,以及哪些表增长最快,最开始想到的是用户日志,因为所有的增删改操作都会记录用户日志,而最要命的是用户日志中记录了大量的请求参数和响应参数,还有一部分原因是因为mq消息在发送和消费前会持久化到数据库中并且会更新消息的状态。于是把用户日志记录关掉,重新上线项目,上线后观察了一段时间,磁盘增长趋于平稳。

优化方案:

1.将日志记录迁移到MongoDB

2.日志中避免记录过大的文本信息

3.mq消息数据库只记录发送失败或者消费失败的消息,然后通过定时任务重试,然后如果写数据库失败再通过邮件等方式来通知人工补偿,这样可以大大减少写库的次数。但是这样的话假如业务所在事务提交后还没来得及发送系统已经宕机了数据库中是没有记录的,但是这样情况概率是极低的,可以通过业务中记录要发送的mq消息磁盘日志来恢复。

心得:

1.项目设计要多考虑未来的数据增长,一些不是特别重要的数据不要和业务数据放在同一个数据库里面,当然这个也看业务的规模了。

2.设计方案太追求完美也是不行的。比如项目中对于mq消息的发送和消费之前进行了全量持久化,这样消息发送或者消费失败后可以定时任务补偿从而保证mq消息的可靠消费,用的是业务数据库,这样可以保证mq消息的落库和业务数据提交在同一事务中,不会产生脏数据。但是这带来频繁插入和更新数据库的问题,BINLOG的增长过快这个问题也是其中原因之一。所以有时候考虑太全面反而因小失大。

3.对系统发生意外情况过于担心,设计上过多考虑意外情况如何处理是行不通的。最重要的是找到一个平衡点,让系统能够持续稳定地运行才是王道。没有一样东西是100%可靠的,比如mq服务器,正常情况下设置了磁盘持久化mq服务器是不会丢消息的,但是一旦把mq服务器的内存耗尽,消息仍然会大量丢失。我们要做的就是尽可能地让所有的服务永远不要达到它的极限,当时做起来还是挺难的,毕竟业务的增长有时候是很难预估的,而服务器的资源却是有限的,在投入成本和产出的效益上也要找到一个相对合理的点才行。

你可能感兴趣的:(数据库,mssql,磁盘爆满)