当前位置:首页 > 问答 > 正文

磁盘写入出问题了,数据库老是卡住,数据根本写不进去啊

(一)

“磁盘写入出问题了,数据库老是卡住,数据根本写不进去啊!”——这话不是我说的,是我一个在电商公司做运维的朋友,前几天在深夜的电话里,用近乎崩溃的语气跟我吼出来的,你能想象吗,大促前夕,整个技术团队严阵以待,结果核心数据库突然“摆烂”,写入性能断崖式下跌,用户的订单提交按钮点下去就像石沉大海,后台日志里塞满了报错,用他的话说,“那感觉就像高速公路收费站所有闸机突然同时坏了,后面的车排成长龙,喇叭按得震天响,但你就是一辆车也放不过去,只能眼睁睁看着拥堵蔓延。”

他描述的现象非常具体:应用服务器看起来一切正常,CPU、内存占用率都不高,但任何涉及写入数据库的操作,无论是下订单、更新库存还是记录日志,都会变得极其缓慢,最终超时失败,前端的用户界面就一直转圈圈,直到显示“网络错误”或“服务繁忙”,而在数据库服务器上,他们观察到磁盘I/O使用率长时间维持在100%,但写入速度却低得可怜,每秒只有几MB,甚至几百KB,这就像一个水管工明明开着最大水压,但水龙头里却只能滴出几滴水,肯定是管道中间某个地方堵死了。

(二)

问题到底出在哪儿?他们一开始也是满头雾水,按照常规思路排查了一遍,首先怀疑是数据库本身,比如有没有什么锁表的长事务,或者执行了特别糟糕的SQL语句把资源耗尽了,但查了一圈,慢查询日志里没什么异常,锁等待的情况也不严重,数据库进程看起来很想干活,但就是“有力使不出”。

他们把目光投向了硬件,这台数据库服务器用的是传统机械硬盘(HDD)做的RAID阵列,而不是更快的固态硬盘(SSD),有人怀疑是某块硬盘快要坏了,导致了I/O性能下降,他们检查了RAID卡的状态和硬盘的SMART健康信息,奇怪的是,所有硬盘都显示“健康”,没有预警,这就排除了单块硬盘物理损坏这个最常见的原因。

就在大家一筹莫展的时候,我那位朋友做了一个关键操作:他跳过了RAID卡和文件系统的缓存,直接用工具对物理磁盘进行低级别的写入测试,结果令人吃惊:裸盘的写入速度也远远低于正常值,这下,嫌疑基本锁定在了RAID卡或者硬盘本身的老化或故障上。

(三)

为了不影响线上业务,他们连夜申请了维护窗口,准备更换硬件,但就在停机前,一个更资深的工程师提出了一个“古怪”的可能性:会不会是RAID卡的电池没电了?这个想法一开始遭到了不少人的质疑,因为RAID卡电池(通常是锂电池,BBU)的作用是给卡上的缓存供电,保证在服务器意外断电时,缓存里还没来得及写入硬盘的数据不会丢失,它跟磁盘的写入速度有什么关系?

关系大了,这位工程师解释道:为了保证数据绝对安全,很多RAID卡有一个默认策略——当检测到电池电量不足或失效时,为了避免断电丢数据,它会自动将写入模式从“Write-Back”切换为“Write-Through”。

简单打个比方,“Write-Back”模式就像有个高效的秘书,应用要写数据,RAID卡先快速地把数据收进自己的高速缓存里,然后马上告诉应用“写好了,你继续吧”,之后RAID卡再找个空闲时间,慢慢把缓存里的数据整理好、写入速度较慢的物理硬盘,这样应用感觉速度飞快。

而“Write-Through”模式则像撤掉了这个秘书,应用要写数据,RAID卡不敢偷懒,必须老老实实地等到数据被安全地写入物理硬盘后,才敢回头告诉应用“写好了”,这样一来,每一次写入操作的延迟,都直接受制于机械硬盘寻道和旋转的物理速度,性能自然一落千丈。

(四)

一语点醒梦中人!他们立刻登录RAID卡的管理界面,果然,状态页面里清晰地显示着一行警告:“Battery Charge: 0%” 或 “Battery Failed”,罪魁祸首找到了!就是因为这块小小的电池寿终正寝,触发了RAID卡的自我保护机制,导致了写入性能的雪崩。

后续的解决就相对简单了,他们在维护窗口期间,更换了RAID卡的电池,完成后,RAID卡经过一段时间充电,状态恢复正常,自动切换回了高效的“Write-Back”模式,重启数据库后,监控图表上的磁盘写入延迟曲线瞬间从高耸入云的山峰变成了一马平川的直线,写入吞吐量也恢复了正常,那个夜晚,整个技术团队才算真正松了一口气。

这件事给我朋友留下了深刻的印象,他后来总结说,很多看似复杂诡异的技术问题,根源往往是一些最基础、最容易被忽略的环节,RAID卡电池没电,这种问题在教科书里可能就一句话带过,但真发生在生产环境里,带来的却是真金白银的损失和巨大的心理压力,它也提醒我们,不能只盯着CPU、内存这些“明星”指标,对于磁盘I/O子系统这种底层设施,必须建立更完善的监控,比如定期检查RAID卡电池健康状态、监控读写缓存模式的变化等,把隐患消灭在萌芽状态,毕竟,对于数据库而言,不能稳定可靠地写入数据,其他一切功能都是空中楼阁。

磁盘写入出问题了,数据库老是卡住,数据根本写不进去啊