ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Ubuntu启动卡在fsckd提示?解读文件系统检查机制与正确应对

Ubuntu启动卡在fsckd提示?解读文件系统检查机制与正确应对 1. 一次意外断电把 Ubuntu 堵在启动路上的提示我印象很深之前单位机房有一台跑着 Ubuntu 20.04 的服务器某天市电闪断UPS 也没撑住机器直接断电。等电力恢复、系统自动加电重启后我通过远程管理卡一看控制台屏幕就停在这样一行字上/dev/sda1: recovering journal fsckd-cancel-msg: Press CtrlC to cancel all filesystem checks“Press CtrlC to cancel all filesystem checks”——翻译过来就是“按 CtrlC 取消所有文件系统检查”。这行字给人的第一感觉非常具有诱惑力好像只要按一下系统就能立刻跳过这个烦人的检查恢复快速启动。但我当时没有按因为我知道这行字背后的分量Ubuntu 并不是闲着没事才做文件系统检查而是因为它认为磁盘上有没写完的“旧账”。这不是一个只能靠“死记硬背”解决的问题。搞清楚这行提示的机制、跳过检查的真实代价、以及后续如何排查反复出现的根因才能真正把启动问题治好。这篇文章不是教科书而是我几次真实“排坑”后的记录从“这提示到底谁发的”到“怎么避免它反复出现”一次讲透。2. 谁在启动时对你大喊 CtrlCfsckd 与文件系统检查链路拆解2.1 先理解那行字说的“filesystem checks”是什么在 Linux 世界里fsckfile system check是文件系统一致性检查工具的统称。它不是一个程序而是一组程序的“前端调度器”比如针对 ext2/ext3/ext4 会调用e2fsck针对 XFS 会调用xfs_repair针对 Btrfs 有btrfs check。当 Ubuntu 启动时发现某个分区有“非正常关闭”的记录就会触发一次fsck。那“非正常关闭”是怎么记录的呢以最常用的 ext4 文件系统为例它在磁盘上维护了一个“clean”标记。正常关机时系统会把文件系统干净地卸载umount并把这个标记置为 clean但断电、强制关机、内核 panic 这类非正常路径上文件系统还挂着呢电源就没了这个标记就会停留在“dirty”状态。下次开机系统看到 dirty 标记就认为这个文件系统可能有“写到一半”的数据不敢直接信任它于是 fsck 登场先检查日志journal把没做完的事务重放或者丢弃再扫描关键元数据有没有互相冲突的情况。2.2 fsckd 在里面扮演什么角色早期系统做 fsck通常就是一个进程在控制台上傻乎乎地输出“/dev/sda1: ***** FILE SYSTEM WAS MODIFIED *****”你也不知道它要跑多久也不知道能不能打断。到了 systemd 时代Ubuntu 把 fsck 的“前端交互”交给了systemd-fsckd——这就是你看到fsckd-cancel-msg这个标识符的源头。systemd-fsckd是一个守护进程它负责在 fsck 工作期间和用户交互如果发现根文件系统或者某个自动挂载的分区需要检查它就会在 console 上显示类似开头那样的提示告诉你按下 CtrlC 可以取消所有文件系统的检查。这算是 systemd 给用户留的一个“逃生门”紧急情况下你不想等着它慢慢检查可以跳过。但注意提示前半句还有一个更重要的信息recovering journal。这表示 fsck 已经在“重放日志”了——正在做最关键的修复动作。这个时候按 CtrlC相当于让手术做到一半就缝合风险肯定有。2.3 为什么有的设备有提示有的设备直接进系统这里给刚接触 Ubuntu 的朋友提一个容易被忽视的点不是所有分区都走同一套交互检查流程。根文件系统/如果发现 dirty通常由systemd-fsck-root.service处理屏幕上出现fsckd-cancel-msg提示的概率最大因为交互必须发生在这里否则系统没法往下挂载根分区。非根分区如/home、/data由systemd-fsck.service按挂载点逐个体检。它们的交互往往不会阻塞那么明显有时候会等到进入桌面或 SSH 后系统才告诉你有个分区需要检查。网络文件系统、tmpfs、proc 这类虚拟文件系统压根不做 fsck。Btrfs、XFS 等有不同机制的文件系统行为差异很大比如 Btrfs 的检查通常在挂载时自动做一部分不一定走传统 fsck。所以你在启动阶段看到的这行fsckd-cancel-msg绝大多数情况是在说根文件系统需要检查。这也是为什么我劝大家不要一看到提示就闭眼按 CtrlC——根文件系统带病工作可比晚几分钟开机难受多了。3. 判断能否跳过前先看懂这次检查的具体损伤3.1 按 CtrlC 会怎样真实的系统行为先给结论按 CtrlC 之后systemd 会取消当前正在等待的 fsck 流程并继续尝试挂载和启动。如果文件系统只是“日志需要重放”这种低危状态跳过也可能真的就启动了甚至用起来没任何异样。但高风险场景也真实存在。我自己处理过一次同事的机器他习惯性地“看到提示就 CtrlC”结果系统虽然进了桌面但/home下几个目录的权限错乱部分文件读不出来。后来手动跑了一次fsck -f发现错误修了一堆才复盘出问题不是那次检查不该跑而是他把提示当成了“可以随便跳过的东西”。还有一种情况更直接如果根文件系统已经有结构性损坏比如目录项坏块、inode 互相引用错误跳过存储检查后挂载阶段可能直接失败系统把你扔进 emergency mode。这时候你要面对的是一个只剩只读文件和 root shell 的“半瘫痪系统”反而更折腾。所以我的建议是除非你明确知道上次是自己故意强制关机、且系统一直很健康否则第一次遇到这个提示老老实实等它检查完。3.2 区分“检查进行中”和“停下来问你”很多卡在这条提示上的朋友其实并不是不想等而是等到崩溃——屏幕停在一行字上十几分钟没动静看起来像死机。这里要分清 fsck 的两种状态状态一正在扫描/修复。此时屏幕可能在滚动各种百分比或者不停输出“Pass 1: Checking inodes, blocks, and sizes”这类信息。虽然慢但它还活着。对于超大容量磁盘或大量小文件的文件系统跑几十分钟完全正常。状态二等待用户输入。有些 fsck 过程会发现需要修复的项目然后询问Fix? y或者Clear? y。如果 fsck 没有以-y参数自动回答是它就会停在这里等你输入。这个时候你干等着系统当然永远不会继续。如果你在控制台看到停住不动先确认键盘上的 Caps Lock 是否有反应再试着输入y回车看有没有回应。如果输入有反应说明就是状态二如果键盘没反应再考虑是不是真的卡死。3.3 等它检查完以后怎么看“战果”检查完成以后系统会正常进入登录界面或桌面。我建议你第一时间打开终端用 journalctl 翻一下上次 fsck 的记录journalctl --list-boots journalctl -b -1 -u systemd-fsckd.service journalctl -b -1 -u systemd-fsck-root.service-b -1表示上一次启动。这里能看到 fsck 检查了哪个设备、发现了什么问题、是否修复成功。如果里面有contains a file system with errors, check forced这种字眼就说明问题已经发生过而且还没完后面要仔细排查。如果你当时用的是 live USB 或者在救援模式下手动跑的 fsck也可以直接看 fsck 的输出来判断。正常的收尾一般是类似/sda1: ***** FILE SYSTEM WAS MODIFIED ***** /sda1: 12345 files, 678910 blocks used“FILE SYSTEM WAS MODIFIED”本身不一定是坏事它只是说 fsck 动了磁盘上的结构把问题修了。真修好了后面几天启动就不会反复提示。4. 反复出现这个提示说明根因不只在“没正常关机”4.1 断电之后的所有异常未必都是断电直接造成的很多人的第一反应是我上次断电了所以这次开机检查合理。但之后几天它反复出现 “fsckd-cancel-msg”很多人就开始不耐烦了。这里有个特别重要的判断逻辑**正常断电导致的 dirty 标记通常只会触发一次检查。fsck 跑完并修复元数据后文件系统会重新标记为 clean下次启动不该再出现同样的提示。**如果你连续多次开机都看到它说明存在三种可能系统每次都来不及正常关机——比如硬件层面的断电或者 sudo poweroff 之后卡死文件系统已经出现了真正的一致性错误fsck 没有彻底修好磁盘硬件开始退化了比如坏道、SATA 线接触不良、SSD 掉盘。不要小看第 3 种。我遇到过一台机器连续一周开机都跑 fsck最开始以为是机房供电不稳后来用smartctl一查Reallocated_Sector_Ct已经标红磁盘在悄悄把坏扇区挪到备用区。这种情况下你按多少次 CtrlC 都没用——系统不是故意拦你是磁盘状态真的不行了。4.2 怎么一步步查清“到底哪里坏了”下面这套排查手法是我遇到 fsck 反复出现时固定会做的操作不复杂但能把范围缩得很小。先看系统日志里有没有区块层的报错。用dmesg或journalctl -k搜索 IO error、ata、scsi 等关键词sudo dmesg | grep -Ei error|fail|bad|offline sudo journalctl -k | grep -Ei ata[0-9]|scsi如果出现大量I/O error、request sense、buffer I/O error基本可以断定是硬件相关重点检查盘和连接线。再看 SMART 信息。以最常见的 SATA/SAS 盘为例sudo apt install smartmontools sudo smartctl -a /dev/sda重点关注几项Reallocated_Sector_Ct已经被重映射的坏扇区数非零就要警惕Current_Pending_Sector待重映射的扇区如果不断增长说明盘在继续恶化UDMA_CRC_Error_Count如果同时伴随 SATA 线松动或接口接触不良这个数值会很高。如果 SMART 显示健康那再回到文件系统层面可以在线做一次只读体检不写任何数据sudo fsck.ext4 -fn /dev/sda1注意参数-f是强制检查-n是只读模式no changes。这个命令在单用户模式下更安全。如果它发现了错误但你在运行系统下最好记录下错误位置然后找维护窗口用 live 系统跑完整修复。4.3 用启动参数临时控制检查行为有时候你可能需要立刻进系统处理紧急工作没时间等 fsck 慢慢跑。这种情况下与其在 fsckd 提示时按 CtrlC 碰运气不如直接通过 GRUB 启动参数更可控地跳过或强制检查。在 GRUB 菜单处按e进入编辑在linux那一行末尾追加fsck.modeskip跳过本次文件系统检查fsck.modeforce强制检查所有文件系统fsck.repairyes自动修复等价于 fsck -yfsck.repairno只检查不修复。临时修改只对本次启动生效重启后 GRUB 配置自动还原。这个方式比在 fsckd 提示时盲按 CtrlC 更优雅因为你可以明确告诉系统“这次跳过是主动决策”而不是被一行提示带着走。我自己在维护生产机器时如果确认数据有完整备份、只是想先进系统处理业务会优先用这种参数跳过而不是按 CtrlC 让它“半路出家”。按了 CtrlC当前那个 fsck 进程的修复动作会被打断留下的状态可能更混乱。5. 用配置减少无谓检查从 tune2fs 到 fstab pass 字段的取舍5.1 谁说 ext4 的检查只能靠断电后的随机“抽奖”fsck 的触发不完全是断电决定的。ext4 文件系统还支持两种“定期体检”机制按挂载次数比如设置每挂载 30 次后强制检查按时间间隔比如设置每 180 天检查一次。Ubuntu 安装时默认值因发行版而异但很多服务器系统默认并不设置时间间隔只靠 dirty 标记触发。你可以用tune2fs -l查看当前文件系统的具体配置sudo tune2fs -l /dev/sda1关注这几行Mount count: 18 Maximum mount count: -1 Check interval: 0 (none) Last checked: Thu Jan 1 00:00:00 1970Maximum mount count为-1表示不按挂载次数检查Check interval为0表示不按时间检查。也就是说这台机器正常情况下只有“非正常关机”会触发 fsck。如果你希望系统定期自动体检可以设置sudo tune2fs -c 30 /dev/sda1 # 每挂载30次检查 sudo tune2fs -i 180d /dev/sda1 # 每180天检查反过来如果你明确知道某台机器的盘非常重要、每次开机检查都会造成服务停机太长也可以把-c改成-1关闭按次数检查。但我不建议彻底关掉时间检查哪怕系统的运维窗口再紧一年到头都不做一次元数据巡检盘也容易出问题。5.2 fstab 里的 pass 字段控制启动时到底查谁看到 fsckd 提示时你可能会想能不能让某些数据盘不参与启动检查可以但要在搞清楚风险的前提下去配置。/etc/fstab的最后一列叫做pass它有 0/1/2 三种取值0启动时不检查这个文件系统1只有根文件系统通常设为 1表示最先检查2其他需要检查的分区通常在根文件系统之后并行检查。举个例子你的系统盘想正常检查数据盘想跳过UUIDxxxx-xxxx / ext4 defaults 0 1 UUIDyyyy-yyyy /data ext4 defaults 0 0把/data的 pass 设为 0 之后启动时系统就不会对这块盘执行 fsck 了。但代价是这块盘如果之前在写入过程中掉过电上面的文件系统错误不会被自动修复可能等到你手动访问时才爆雷。我在实际运维中一般采取折中方案重要的根分区保持 pass1大容量冷数据盘可以 pass0但每个月定时在业务低峰手动fsck -n一次起一个“备份体检”的作用。你要是图省事全设 0那和把数据裸奔没区别。5.3 千万别忘记fsck 不能在挂载状态下乱跑这一段是写给看到fsckd-cancel-msg之后临时想手动修复的朋友的**对正在使用的分区直接执行 fsck是真正能把系统搞挂的行为。**在文件系统挂载状态下fsck 会拿一份不一致的视图去“修正”元数据很容易造成二次破坏。正确的做法是重启进入 GRUB 菜单选 “Advanced options for Ubuntu”进入带有 “(recovery mode)” 的内核项在 recovery menu 里选fsck它会提示你是否重新挂载根文件系统为只读选“是”等 fsck 跑完再选resume正常启动。如果你用的是服务器没有本地显示器也可以通过 systemd 的 emergency 模式操作在 GRUB 启动参数里追加systemd.unitemergency.target进入后先执行mount -o remount,rw /让根文件系统可写再对相应分区做修复最后reboot。6. 从踩坑中提炼的日常维护清单6.1 做好“脏标记”的应急预案文件系统检查本身不可怕可怕的是它发生后你不知道怎么处理。我建议每台 Ubuntu 机器都提前准备一个简单的应急预案牢记 recovery mode 入口的位置记录每块数据盘对应的 UUID避免 fsck 时搞错设备提前备份/etc/fstab和grub.cfg出问题时有对比依据确认服务器是否有远程管理卡/IPMI 的访问方式看不到 console 的话fsck 交互提示基本上无解。这个清单看起来很基础但在事故现场真的能救命。我处理过一次同事的机器系统卡在 fsck 提示但他连的是 SSH 不是管理卡完全看不到屏幕只能远程强制关机重来结果多折腾了两个小时。6.2 把系统日志持久化打开发现 fsck 反复出现后你一定会去翻日志。但如果 Ubuntu 默认不开 persistent journal重启后上次启动的日志很可能已经不在了排查就会难上加难。可以这样打开持久化日志sudo mkdir -p /var/log/journal sudo systemd-tmpfiles --create --prefix /var/log/journal sudo systemctl restart systemd-journald配合前面提到的journalctl --list-boots你就能看到每个启动轮次的 fsck 记录彻底告别“重启后失忆”。6.3 给家用机/工作站的建议如果你只是个人电脑突然遇到这个提示又不想折腾服务器那套运维手法我的建议更简单不赶时间就让检查跑完跑完之后看看有没有 “FILE SYSTEM WAS MODIFIED” 的记录如果两周内反复出现果断全盘备份然后用smartctl查硬盘健康如果是 SSD 且有校验和错误优先考虑换数据线或换个 SATA 接口再观察一阵子如果块设备是 NVMe重点看nvme smart-log里的percentage_used和media_errors分别对应寿命消耗和介质错误。别把“按 CtrlC 跳过检查”变成习惯。它应该是一道应急出口而不是日常操作。真把文件系统当成能无限跳过检查的免费午餐迟早有一天你会收到一份“无法挂载数据丢失”的账单。6.4 记一次让我改变习惯的经历最后分享一次真实的教训。某次我给一台旧笔记本装 Ubuntu 做测试图省事直接从 Windows 里强制重启了系统结果开机后看到 fsckd 提示当时赶时间顺手就 CtrlC 了。之后两周这台机器每次开机都要跑一遍 fsck我忍无可忍终于在一个周末用 live USB 做了完整检查结果发现文件系统里有一堆目录项错误其中就包含我后来一直写不进去文件的那个目录。如果第一次就等它检查完可能几分钟就解决问题也就不会有后续那一周反复见到提示满屏飘的烦躁了。现在我在任何机器上看到fsckd-cancel-msg: Press CtrlC to cancel all filesystem checks第一反应永远是先把屏幕拍下来看一眼当前是什么分区、什么状态再决定要不要打断。如果手头有备份我可以放心跳过如果没有备份我宁愿泡杯咖啡等它转完。启动慢一点不丢人数据丢了才真的麻烦。
返回列表