4. 常见错误排查工具:dmesg、journalctl、mount、findmnt、blkid 命令详解

启动挂不上,说白了就是系统在某个环节卡住了。这时候你手里得有趁手的工具,才能快速定位问题。我这些年排查下来,真正高频使用的就五个命令:dmesg、journalctl、mount、findmnt 和 blkid。今天咱们一个一个掰开揉碎了讲。

核心思路:先看内核日志(dmesg)找硬件/驱动错误,再看系统日志(journalctl)找服务启动失败,然后用 blkid 确认磁盘 UUID,最后用 mount/findmnt 验证挂载状态。这个顺序能帮你少走很多弯路。

启动挂载排查工具链 问题现象 dmesg(内核日志) journalctl(系统日志) blkid(设备标识) mount(挂载操作) findmnt(挂载状态) 排查顺序:dmesg → journalctl → blkid → 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 分区没有挂载上:

  1. 第一步:dmesg | grep -i "sdb\|xfs\|error" —— 看内核有没有报磁盘或文件系统错误
  2. 第二步:journalctl -u data.mount -p err —— 看挂载服务的具体错误日志
  3. 第三步:blkid /dev/sdb1 —— 确认磁盘的 UUID 和文件系统类型
  4. 第四步:mount -t xfs /dev/sdb1 /data —— 手动挂载测试
  5. 第五步:findmnt /data —— 确认挂载成功,并检查挂载选项

这个流程我用了好多年,基本覆盖了 90% 的挂载问题。剩下的 10% 可能是硬件故障、内核 bug 或者配置错误,那就需要更深入的分析了。

总结一下:dmesg 看内核、journalctl 看服务、blkid 看设备、mount 做操作、findmnt 看结果。五个工具各司其职,配合使用才能高效排查。