ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

一次线上存储节点进程假死的分析

2020-09-28 07:02:58  阅读:216  来源: 互联网

标签:存储 假死 sync while 线上 IO 日志 节点


背景

某大厂分布式存储程序猿大半夜收到电话报警,某个存储节点进程和主控节点心跳丢了。
穿着小内裤起来 检查了一番:

  • ping 主控节点:网络正常
  • telnet 主控节点端口: 能telnet 上
  • ps -aux 检查存储节点进程: 进程还在
  • 检查 日志: 日志居然不前进了!!!!
    又看了一遍 存储节点主进程的状态:居然不是正常状态!!!
    根据线上故障先止损后追因的原则,马上发命令check 无误后把这个节点从存储集群中下掉了。

分析过程

蛛丝马迹

看到业务恢复、故障报警消除后,开始分析root cause。
进程处于func状态, gdb attach 上去失败, gcore 也失败,根本就无法看到堆栈。
继续检查业务日志:发现故障在磁盘包障后的日志后出现。
检查内核日志:发现有块nvme 盘掉线了,和pcie root 断开了!!!

和厂商及系统部同学确认了下,出现NVME盘掉线的情况,短时不影响buffer IO ,只影响direct IO。

日志迷云

这就奇怪了,因为我们的数据流都是走page cache,而且落盘的时候用pthread, 即便磁盘坏掉了,也只应该影响这个pthread, 不应该导致整个存储进程上所有其他的线程,持续周期任务日志都打印不出来的情况。

到底是个什么鬼?

好事多磨

现有的日志和现场已经无法提供更多线索了,为了分析这个问题,只有想办法复现这个现象了。

怎么复现了?既然是坏盘影响IO,那么我就模拟坏盘吧。
搜索了一卷: 参考 磁盘故障模拟, 发现验证机器上没有相关的工具,也无法安装包,之好作罢。怎么办?

喝了一杯茶回来,想到既然是坏盘影响IO, 那么就把有IO的地方mock住!

说干就干,把raft 中和业务中数据流上pwrite/pread的地方都替换成无限sleep, 加个开关,启动后验证了一遍,一切正常,没有复现哪个问题。

后来仔细分析了下,不能一直sleep后,应该用while(1)啊,因为碰到磁盘故障,DIO执行到这里也不会返回,并且不会切换线程。 于是把上面的 sleep换成while。

重新编译执行,打开开关测试 ,还是一切正常啊!

直捣长龙 (pwrite --> sync)

又分析了一遍,既然NVME盘掉线,直接影响的是DIO,那么mock的时候:所有相关的这类操作都应该换成while(1)无法返回,DIO的操作有哪些?

write(O_DIRECT);
sync

grep 了一遍,没有O_DIRECT, 只有sync有几个,也换成了while(1), 重新启动,先正常跑了一通,然后把替换sync为 while(1)的开关打开,没过几分钟,就出现了和线上一模一样的假死现象。

根因

仔细分析了下我们的业务,原来在每次元数据更新完都会sync下元数据文件。这个操作在bthread里,为了避免同时操作这个文件,前面有锁。而这个操作又是在一个bthread里, 它做这个又会去拿磁盘基本的锁,这个锁又和很多业务线程互斥!!!

这样一旦这个sync huang住无法返回,就会导致存储进程假死!

总结

通过上面的分享可以看到,分析和模拟磁盘故障,需要知道它的本质影响然后想办法模拟手影响的地方,这样才能彻底定位根因!

标签:存储,假死,sync,while,线上,IO,日志,节点
来源: https://blog.51cto.com/xiamachao/2538192

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有