4. 常见错误排查工具:dmesg、journalctl、mount、findmnt、blkid 命令详解
启动挂不上,说白了就是系统在某个环节卡住了。这时候你手里得有趁手的工具,才能快速定位问题。我这些年排查下来,真正高频使用的就五个命令:dmesg、journalctl、mount、findmnt 和 blkid。今天咱们一个一个掰开揉碎了讲。
核心思路:先看内核日志(dmesg)找硬件/驱动错误,再看系统日志(journalctl)找服务启动失败,然后用 blkid 确认磁盘 UUID,最后用 mount/findmnt 验证挂载状态。这个顺序能帮你少走很多弯路。
4.1 dmesg —— 内核的「第一手现场」
dmesg 是内核环缓冲区的内容。系统刚启动时,硬件初始化、驱动加载、磁盘识别这些信息都会写到这里。我习惯在排查启动问题时,第一个就跑 dmesg | grep -i error,先看有没有明显的错误。
举个例子,有一次客户反馈服务器启动后找不到根分区。我远程上去一看,dmesg 里赫然写着:
[ 3.456789] sd 0:0:0:0: [sda] No Caching mode page found
[ 3.456790] sd 0:0:0:0: [sda] Assuming drive cache: write through
[ 5.123456] EXT4-fs (sda2): VFS: Can't find ext4 filesystem
看到最后一行了吗?"Can't find ext4 filesystem"。这说明内核认出了磁盘,但文件系统头损坏了。后来用 fsck 修复了一下就好了。如果没有 dmesg,你根本不知道是磁盘没识别还是文件系统坏了。
实用技巧:dmesg -T 可以把时间戳转成人类可读的时间格式。另外 dmesg -w 可以实时监控新产生的内核消息,适合插拔设备时用。
4.2 journalctl —— 系统服务的「黑匣子」
journalctl 是 systemd 的日志管理工具。它比 dmesg 更上层,记录的是服务级别的信息。比如某个挂载服务启动失败、网络服务超时,这些在 dmesg 里看不到,但 journalctl 里一查一个准。
我个人最常用的几个参数:
journalctl -u xxx.service—— 只看某个服务的日志journalctl -b -1—— 看上一次启动的日志(系统挂了进不去的时候特别有用)journalctl -p err—— 只看错误级别的日志
有一次我排查一个 NFS 挂载失败的问题,dmesg 里干干净净,但 journalctl -u nfs-client.target 里显示:
Mar 15 09:12:34 server systemd[1]: Mounting /mnt/nfs...
Mar 15 09:12:34 server mount[1234]: mount.nfs: Connection timed out
Mar 15 09:12:34 server systemd[1]: mnt-nfs.mount: Mount process exited, code=exited, status=32
Mar 15 09:12:34 server systemd[1]: mnt-nfs.mount: Failed with result 'exit-code'.
看到 "Connection timed out" 我就明白了——网络不通,不是配置问题。所以你看,不同工具解决不同层面的问题。
注意:journalctl 默认只保留最近的日志。如果系统频繁重启,旧日志可能被覆盖。建议在生产环境上配置 SystemMaxUse=500M 来保留更多历史日志。
4.3 blkid —— 磁盘的「身份证」
blkid 用来查看块设备的 UUID、文件系统类型、LABEL 等信息。为什么这个重要?因为 /etc/fstab 里挂载磁盘时,通常用的是 UUID 而不是设备名(比如 /dev/sda1)。设备名可能会变,但 UUID 是唯一的。
执行一下看看:
# blkid
/dev/sda1: UUID="a1b2c3d4-..." TYPE="ext4" PARTUUID="00012345-01"
/dev/sda2: UUID="e5f6g7h8-..." TYPE="xfs" PARTUUID="00012345-02"
/dev/sdb1: UUID="i9j0k1l2-..." TYPE="ntfs" PARTUUID="00067890-01"
我记得有一次,同事把一块硬盘从一台服务器拔到另一台,结果启动时挂载失败。一查 blkid,发现新机器的 /dev/sdb 变成了 /dev/sdc,但 fstab 里写的是 /dev/sdb1。这就是典型的「设备名漂移」问题。用 UUID 就能完美避开。
最佳实践:在 /etc/fstab 里永远用 UUID 或 LABEL 来指定设备,不要用 /dev/sdX。UUID 不会变,设备名会变。
4.4 mount —— 挂载操作的「执行者」
mount 大家应该不陌生。但排查问题时,我更多用它来手动测试挂载。比如:
# mount -t ext4 /dev/sda1 /mnt/test
mount: /mnt/test: wrong fs type, bad option, bad superblock on /dev/sda1.
这个错误信息很直接——文件系统类型不对或者超级块坏了。这时候我会先用 blkid 确认一下文件系统类型,再决定下一步。
另外,mount -a 可以挂载 /etc/fstab 里所有条目,适合在修改 fstab 后做验证。我习惯在改完 fstab 后先跑一遍 mount -a,没问题再重启。否则重启后起不来,你就得进救援模式了。
小技巧:mount -o remount,rw / 可以在单用户模式下把根分区重新挂载为可读写,方便你修改 fstab 或修复文件系统。
4.5 findmnt —— 挂载状态的「体检报告」
findmnt 是 mount 命令的增强版。它把挂载信息以树形结构展示,一目了然。我最喜欢它的 --df 模式,可以模拟 df -h 的输出,但信息更详细。
# findmnt --df
TARGET SOURCE FSTYPE SIZE USED AVAIL USE%
/ /dev/sda2 ext4 100G 45G 55G 45%
/boot /dev/sda1 ext4 500M 120M 380M 24%
/mnt/data /dev/sdb1 xfs 2T 1.2T 800G 60%
排查挂载问题时,findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS 可以快速查看每个挂载点的挂载选项。比如:
# findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sda2 ext4 rw,relatime,errors=remount-ro
/boot /dev/sda1 ext4 rw,relatime
/mnt/data /dev/sdb1 xfs rw,noatime,nodiratime
看到 errors=remount-ro 了吗?这意味着如果根分区发生文件系统错误,内核会自动把它重新挂载为只读。这是 ext4 的默认行为,能防止数据进一步损坏。
避坑指南:我曾经遇到一个案例,findmnt 显示挂载正常,但实际写入文件时报 "Read-only file system"。后来发现是磁盘硬件故障导致内核自动 remount 为只读了。所以 findmnt 只能看状态,不能替代 dmesg 的硬件检查。
4.6 实战组合拳
说了这么多,咱们来一个完整的排查流程。假设系统启动后,/data 分区没有挂载上:
- 第一步:
dmesg | grep -i "sdb\|xfs\|error"—— 看内核有没有报磁盘或文件系统错误 - 第二步:
journalctl -u data.mount -p err—— 看挂载服务的具体错误日志 - 第三步:
blkid /dev/sdb1—— 确认磁盘的 UUID 和文件系统类型 - 第四步:
mount -t xfs /dev/sdb1 /data—— 手动挂载测试 - 第五步:
findmnt /data—— 确认挂载成功,并检查挂载选项
这个流程我用了好多年,基本覆盖了 90% 的挂载问题。剩下的 10% 可能是硬件故障、内核 bug 或者配置错误,那就需要更深入的分析了。
总结一下:dmesg 看内核、journalctl 看服务、blkid 看设备、mount 做操作、findmnt 看结果。五个工具各司其职,配合使用才能高效排查。