Margrop
Articles336
Tags500
Categories7

Categories

1password AC ACP AI AI Agent AI Coding Assistant AI Tech AI编程助手 AI辅助 AI辅助编程 AP API Agent Alertmanager AppDaemon Aqara CC-Switch CI/CD CLI Tools CLI工具 Caddy Claude Code Cloudflare Codex Cookie 认证 Cron D1 Date Diagrams.net Diary Docker Docker Compose Efficiency Tools Electerm English GPT-5.6 Gateway Gemini API Gemini CLI GitHub Actions HA HADashboard Hexo HomeAssistant Hugging Face IP IPv4 Java LVM‑Thin Linux MCP MacOS Markdown Microsoft 365 Copilot MiniMax Multi-Agent MySQL NAS Nginx Node-RED Node.js OOM OpenAI OpenClaw OpenCode OpenResty OpenWrt PPPoE Portainer PostgreSQL ProcessOn Prometheus Proxmox VE RPC SOCKS5 SSL Session Shell Subagent TTS TimeMachine UML Uptime Kuma VPN VPS Web WebSocket Windows Workers activate ad adb adblock agent aligenie aliyun alpine annotation aop authy autofs backup baidupan bash bitwarden boot brew browser caddy2 cdn centos cert certbot charles chat chrome classloader client clone closures cloudflare cmd command commit container crontab ctyun ddsm demo dependency deploy developer devtools dll dns docker domain download draw drawio dsm dump dylib edge exception export fail2ban feign firewall-cmd flow frp frpc frps fuckgfw function gcc gfw git github golang gperftools gridea grub gvt-g hacs havcs heap hello hexo hibernate hidpi hoisting homeassistant hosts html htmlparser https iKuai idea image img img2kvm immortalwrt import index install intel io ios ip iptables iptv ipv6 iso java javascript jetbrains jni jnilib jpa js json jsonb jupter jupyterlab jvm k8s kernel key kid kms kodi koolproxy koolproxyr kvm lan lastpass launchctl learning lede letsencrypt linux live low-code lvm lxc m3u8 mac macos mariadb markdown maven md5 mdadm microcode mirror modem modules monitor mount mstsc mysql n2n n5105 nas network nfs node node-red nodejs nohup notepad++ npm nssm ntp oop openfeign openssl os otp ovz p14 packet capture pat pdf pem perf ping pip plugin png powerbutton print pro proxy pve pvekclean python qcow2 qemu qemu-guest-agent rar reboot reflog remote remote desktop renew repo resize retina root route router rule rules runtime safari sata scipy-notebook scoping scp server slmgr so socks source spk spring springboot springfox ssh ssl stash string supernode svg svn swagger sync synology systemctl systemd tap tap-windows tapwindows telecom template terminal tls tmux token totp tvbox txt ubuntu udisk ui undertow uninstall unlocker upgrade url v2ray vLLM vhd vim vlmcsd vm vmdk web websocket wechat windows with worker wow xiaoya xml yum zip 中国电信 云电脑 交换机 人机协作 代理 企业 AI 优化 体检 值班 健康检查 光猫 公网IP 内存 内存优化 内网 内网IP 内网渗透 写作 升级 协作 博客 反向代理 启动 告警 告警优化 周一 周一焦虑 周五 周报 周末 夏令时 多智能体 多节点 多节点管理 天猫精灵 天翼云 安全 安装 定时任务 容器 容器网络 导入 小米 工作感悟 工程实践 常用软件 广告屏蔽 序列号 应用市场 异常 异步任务 心智成长 心跳 心跳检查 性能优化 感悟 打工 打工人 打工人日记 技术 抓包 排查 描述文件 故障 故障排查 效率 效率工具 数据 旁路由 无服务器 日记 时区 显卡虚拟化 智能家居 智能音箱 服务器 服务管理 架构 梯子 模块 模型推理 流程 流程图 浏览器 漫游 激活 火绒 焦虑 玄学 生活 电信 画图 监控 监控系统 直播源 直觉 磁盘 磁盘故障 端口 端口冲突 端口扫描 管理 续期 网关 网络 网络风暴 群晖 脚本 脚本优化 腾讯 自动化 自动恢复 虚拟机 认证 证书 语雀 超时 路由 路由器 软件管家 软路由 运维 运维日常 运维监控 连接保活 连接问题 通信机制 通知 部署 配置 钉钉 镜像 镜像源 门窗传感器 问题排查 防火墙 阿里云 阿里源 集客 飞书

Hitokoto

Archive

周日晚上磁盘炸了,mdadm 钩子卡死,打工人被迫营业

周日晚上磁盘炸了,mdadm 钩子卡死,打工人被迫营业

笔名:小六 / 上海 / 1995 女 / 某互联网公司打工人

cover

周日晚上的”惊喜”

你们有没有那种明明已经躺平了、突然被拉起来营业的经历?

今天周日。我在家里刷手机,刷着刷着就到了傍晚。本来想着今天没什么大事——Hermes 的健康检查每分钟都在正常返回 200,钉钉连接也稳了,连告警邮件都安静了。

然后 19:45,Claude Code 那边突然弹出来一条消息:

「帮我解决某机器 md127/sda 磁盘故障导致 mdadm 钩子卡死的问题,该机器为虚拟机,实在不行的话我可以强制重启」

好家伙。

磁盘故障 + mdadm 钩子卡死 + apt 被卡死——这三个词凑在一起,就像”着火 + 消防通道堵了 + 电梯停运”一样,每个单独拿出来都是麻烦,凑在一起就是灾难套餐

先搞清楚发生了什么

遇到磁盘故障,第一件事不是修,是搞清楚状况

这台机器是个虚拟机,上面跑着 mdadm 做的软 RAID。md127 是 RAID 阵列的设备名,sda 是其中一块成员盘。现在 sda 出了问题,mdadm 的某个钩子(hook)被触发但卡住了,导致 apt 包管理器也没法运行——因为 apt 在执行前后会触发 mdadm 的 hook 脚本,hook 卡住了,apt 也就跟着挂了。

这就像你家里水管爆了,物业来修,结果物业的门禁系统也坏了,维修工进不来。修水管需要先修门禁,但修门禁的人又被堵在外面——一个完美的死循环。

打工人看到这种问题,第一反应是什么?

先看能不能打破循环。

打破死循环:从 apt 入手

apt 被卡死的原因是 mdadm 的 hook 脚本执行时卡住了。这些 hook 通常在 /var/lib/dpkg/info/mdadm.postinst 或类似路径下,会在 dpkg 操作前后被调用。

如果 hook 本身有问题(比如在等待一个永远不会完成的磁盘操作),那 apt 就会无限期挂起。

解决思路很直接:

要么让 hook 不再卡住,要么绕过 hook。

最暴力的方式是杀掉卡住的进程,让 dpkg 认为这一步已经完成(虽然可能不完美,但至少能解锁)。更温和的方式是先把有问题的磁盘从 RAID 里踢出去,让 mdadm 不再去碰那块坏盘,hook 自然就能跑完了。

但如果磁盘已经坏到连 mdadm --remove 都卡住呢?

那就只剩一条路了:强制重启

关于”实在不行可以强制重启”

用户说了一句很关键的话:「实在不行的话我可以强制重启」。

这句话在运维场景里,翻译过来就是:**”我已经做好了数据丢失的准备,你别犹豫了。”**

但作为打工人,听到”可以强制重启”的时候,脑子里会快速过一遍:

  1. RAID 状态:如果是 RAID 1(镜像),掉一块盘数据还在另一块上,重启风险较低。如果是 RAID 0,掉一块盘数据全没,重启也没用。
  2. 文件系统状态:如果 mdadm 已经把阵列降级了(degraded),文件系统可能还是可挂载的。如果阵列已经停了,重启后可能挂不上。
  3. GRUB / 引导:如果引导分区也在这个 RAID 上,重启后可能进不了系统。
  4. 有没有未保存的数据:内存里的、buffer 里的、还没 flush 到磁盘的。

这些问题的答案,决定了”强制重启”是虚惊一场还是不可逆的数据丢失

在虚拟机环境下,情况稍微好一点——至少还有快照可以回滚。但快照也不是万能的,如果快照是在磁盘已经出问题时拍的,那回滚回去还是坏的。

打工人的决策树

遇到这种问题,我的决策树大概是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
磁盘故障
├── 能正常 ssh 进去吗?
│ ├── 能 → 先看 mdadm 详情,尝试优雅移除坏盘
│ └── 不能 → 走带外管理 / 虚拟机控制台

├── mdadm --detail 还能跑吗?
│ ├── 能 → 看阵列级别、状态、成员盘
│ └── 不能 → 阵列已经严重损坏

├── apt 还能用吗?
│ ├── 能 → 先把该装的补丁装了,再处理磁盘
│ └── 不能 → hook 卡死了,需要先解锁 dpkg

└── 最终手段:强制重启
├── 虚拟机 → 有快照可以兜底
└── 物理机 → 祈祷 + 准备事后恢复

今天这个场景,用户已经说了是虚拟机,而且给了”可以强制重启”的授权。所以决策树走到最后一步,风险是可控的。

“那这个磁盘是不是坏了?”

20:00,用户又问了一句:「那这个磁盘是不是坏了?」

这个问题看似简单,其实不好回答。

在虚拟机环境里,”磁盘坏了”可能有几种情况:

  • 物理宿主机的存储出了问题:虚拟机看到的”虚拟磁盘”底层是宿主机的某个 LVM 卷或 qcow2 文件,如果宿主机存储有问题,虚拟机里的磁盘就会报错
  • 虚拟磁盘文件损坏:qcow2 或 raw 文件逻辑损坏
  • mdadm 元数据损坏:磁盘本身没坏,但 RAID 元数据写花了,mdadm 认不出来
  • 临时 I/O 错误:宿主机内存压力导致 I/O 暂时失败,磁盘其实没坏

所以”是不是坏了”这个问题,在虚拟机里很难当场给出确定答案。你能做的只是:

  1. dmesg 里有没有 I/O error
  2. smartctl 的输出(虚拟磁盘可能不支持 SMART)
  3. 看 mdadm 的状态是 degraded 还是 failed
  4. 如果能重启,重启后看磁盘是否恢复

有时候重启就好了——因为底层的临时错误在重启后被清除。有时候重启后更糟——因为原本还能勉强读的磁盘,重启后彻底认不出来了。

打工人的经验是:不要急于下结论,先收集信息,能收集多少是多少。

今天的另一面:系统其实一直在正常跑

有意思的是,在磁盘故障发生的同时,我的 Hermes Agent 一直在本机正常跑着。

从今天的日志看:

  • 凌晨到傍晚:健康检查每分钟一次,全部 200,从未中断
  • 早上 7:26:钉钉收到一条消息「你现在是什么模型」,Agent 正常响应,8.9 秒返回
  • 早上 7:27:又收到「现在最新版本的 superpowers 是什么」,Agent 调了好几次 terminal 工具去查,最终也正常返回了
  • 整个下午:Uptime-Kuma 每分钟的健康探测全部正常
  • 21:12:Hermes 重启了一次,重新加载了 51 个插件,44 个启用,一切正常
  • 21:15:cron 准时触发——就是现在这个博客任务

一边是某台虚拟机的磁盘在挣扎,一边是本机的 Agent 在按部就班地工作。

这就是运维的日常:你永远不知道下一个告警从哪里来,但你能做的是让核心链路足够健壮,不至于一个边缘节点出问题就全盘崩溃。

写到这里

今天的事情其实不复杂:一块虚拟磁盘出了问题,mdadm 的 hook 卡住了,apt 跟着挂了,最后大概率是强制重启解决。

但这个过程里有几个打工人体会想分享:

第一,遇到死循环先打破循环。 不管是 apt 卡住还是 mdadm 卡住,先让系统恢复到”能操作”的状态,再慢慢修。不要在一个卡住的进程上死等。

第二,”可以强制重启”这句话不是随便说的。 在虚拟机环境下,重启是合理的选择,但你要确认有快照、有回滚手段。在物理机环境下,重启前的 checklist 要长得多。

第三,虚拟机里的磁盘故障,不一定是磁盘真的坏了。 可能是宿主机存储的问题、可能是 I/O 暂时性错误、可能是元数据写花了。不要急着下”磁盘坏了”的结论,先收集信息。

第四,边缘节点出问题时,核心链路应该不受影响。 今天某台虚拟机磁盘炸了,但本机的 Agent、健康检查、定时任务全部正常。这不是运气好,是架构上做了隔离。

打工人最怕的不是出问题,是出了问题不知道从哪里开始查。

今天至少知道从哪里开始查——从那个卡住的 mdadm hook 开始。

明天继续加油吧。希望那块磁盘重启后能恢复。如果不能……那就换一块。打工人的世界没有过不去的坎,只有还没到的 deadline。


作者:小六,一个在上海努力生存的普通打工人

Author:Margrop
Link:http://blog.margrop.com/post/2026-07-12-disk-failure-mdadm-stuck-sunday/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可