ARTICLE DETAIL

资讯详情

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

Linux磁盘故障定位:从内核日志到物理槽位的完整方法

Linux磁盘故障定位:从内核日志到物理槽位的完整方法 1. 从一条报错日志说起为什么定位坏盘这么难凌晨两点监控告警群弹出一条消息“节点三磁盘 I/O 错误率突增”。你登上系统dmesg里刷了几百行报错/var/log/messages里混杂着文件系统、内核、应用层的各种信息。问题来了到底是哪块盘出问题了这不是一个靠“看日志”就能秒答的问题。现代服务器动辄十几块盘SATA、SAS、NVMe 混插还叠了 RAID 卡、LVM、文件系统好几层抽象。内核报错里出现的设备名可能是sdb也可能是nvme0n1还可能是dm-3这种映射设备甚至只给你一个ata5或者host12这样的控制器编号。你如果直接照着报错里的名字去拔盘大概率会拔错。这篇内容就是把我这些年处理磁盘故障时从系统日志快速、准确判断物理硬盘位置的一套方法完整拆出来。核心思路只有一句话顺着“内核设备名 → 控制器/通道 → 物理槽位”这条链路一层层把逻辑名字翻译成物理位置。不管你是运维、装机爱好者还是自己攒了 NAS 的玩家这套方法都能直接用。我会先讲清楚 Linux 下磁盘设备命名的逻辑再讲怎么从日志里提取关键线索然后给出从设备名反查物理槽位的完整实操最后整理一份常见报错对照表和踩坑经验。涉及的命令都是系统自带工具不需要额外装什么重型软件。2. 先搞懂内核怎么给硬盘起名字2.1 设备命名规则sd、nvme、vd 分别代表什么Linux 内核识别到一块块设备后会按驱动类型给它分配一个名字。理解这套命名规则是看懂日志的第一步。sd*走 SCSI 子系统的一类包括 SATA 盘、SAS 盘、USB 移动硬盘。sda、sdb、sdc按内核探测顺序分配注意这个顺序不固定加一块盘、换个插槽都可能变。nvme*n1NVMe 固态盘。nvme0n1表示第 0 个 NVMe 控制器的第 1 个命名空间nvme1n1是第二个控制器。vd*虚拟化环境里的 virtio 磁盘常见于 KVM 虚拟机。dm-*device mapper 设备LVM、软 RAID、加密卷都会生成这种映射设备。md*Linux 软 RAID 阵列设备。关键点在于日志里报错的设备名往往不是你能直接对应到物理槽位的名字。比如文件系统报错可能指向dm-2而dm-2背后可能是md0md0又由sdb1和sdc1组成。你得把这条链走完。2.2 为什么设备名会“漂移”很多人踩过的坑今天sdb是第二块盘重启一次变成sdc了。原因是内核按探测顺序分配sd字母而探测顺序受 BIOS 枚举、控制器初始化速度、甚至插槽供电时序影响。这就导致一个严重后果你昨天记的“sdb 是坏盘”今天可能指向另一块好盘。所以生产环境里判断物理位置绝不能依赖sd字母必须依赖更稳定的标识比如WWNWorld Wide Name、序列号、PCI 地址或者by-path 链接。提示/dev/disk/by-id/和/dev/disk/by-path/这两个目录下的软链接就是内核给你准备的“稳定名字”后面实操会重点用到。2.3 日志里常见的几类磁盘报错关键词不同层级的报错指向的严重程度和排查方向完全不同。先建立一个分类意识报错关键词出现位置大致含义严重程度I/O error内核、文件系统读写失败可能是坏道或线缆问题高medium error内核 SCSI 层介质本身损坏坏道高ata bus error内核 libataSATA 链路层错误线缆/背板中高nvme timeout内核 NVMe 驱动NVMe 命令超时盘或 PCIe 问题高failed command内核 libata命令执行失败常伴随上面几类高SMART errorsmartd盘自检预警预故障中EXT4-fs error文件系统文件系统层错误可能是上层后果视情况看懂这张表你就知道文件系统报错往往是“结果”真正的“原因”藏在内核 SCSI/ATA/NVMe 层的报错里。排查要往底层看。3. 从日志提取线索把报错翻译成设备信息3.1 用 dmesg 和 journalctl 抓关键行第一步永远是抓日志。我习惯用dmesg -T带时间戳看内核环形缓冲区配合journalctl -k看持久化的内核日志。# 带可读时间戳看内核日志过滤磁盘相关 dmesg -T | grep -iE error|fail|timeout|ata|nvme|sd[a-z] # 用 journalctl 看本次启动的内核日志 journalctl -k -b | grep -iE I/O error|medium error|ata[0-9] # 只看某块盘相关的假设怀疑 sdb dmesg -T | grep -i sdb抓的时候有个技巧优先看报错第一次出现的位置而不是最后刷屏的那一堆。第一次报错往往带着最完整的上下文比如控制器编号、通道号、LUN 号。3.2 读懂 ata 编号和 host 编号SATA 盘报错经常长这样ata5.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0 ata5.00: irq_stat 0x40000008 ata5.00: failed command: READ DMA ata5.00: status: { DRDY ERR } ata5.00: error: { UNC }这里的ata5就是关键线索。ata5表示第 5 个 ATA 端口port.00是该端口上的第 0 个设备主/从设备概念SATA 一般就是 00。这个ata5是相对稳定的它对应的是控制器上的物理通道。再看 NVMe 的报错nvme nvme0: I/O 123 QID 4 timeout, aborting nvme nvme0: I/O 123 QID 4 timeout, reset controllernvme0就是控制器编号对应一块具体的 NVMe 盘。3.3 用 lsblk 和 lsscsi 建立设备树抓到ata5或nvme0之后下一步是把它和块设备名对应起来。# 看块设备树状结构带设备名和挂载点 lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,MODEL,SERIAL # 看 SCSI/ATA 设备列表含通道、目标、LUN lsscsi -v # 更详细地看某块盘 lsscsi -glsscsi的输出里[5:0:0:0]这种格式就是host:channel:target:lun。第一个数字 5 通常就对应ata5或host5。这样你就把日志里的ata5和lsscsi里的设备、进而和/dev/sdX串起来了。3.4 用 /sys 目录直接查映射关系/sys是内核暴露给用户空间的窗口信息最权威。几个我常用的路径# 查看某个块设备的详细信息包括它属于哪个控制器 ls -l /sys/block/sdb # 查看 sdb 对应的 SCSI 设备路径 ls -l /sys/block/sdb/device # 查看 ata5 端口下挂了什么设备 ls /sys/class/ata_port/ ls /sys/class/ata_link/ # 查看 NVMe 控制器信息 ls /sys/class/nvme/比如ls -l /sys/block/sdb会显示sdb - ../devices/pci0000:00/.../ata5/host5/target5:0:0/5:0:0:0/block/sdb。这条路径里就包含了ata5、host5、PCI 地址信息量极大。顺着这条路径你能一路追溯到物理插槽。4. 从设备名反查物理槽位完整实操4.1 第一步拿到稳定的硬盘标识前面说了sd字母会漂移所以先拿稳定标识。三种方式我按推荐度排序方式一WWN最推荐# 查看所有盘的 WWN ls -l /dev/disk/by-id/ | grep wwn # 或者直接读 for d in /dev/sd?; do echo -n $d: ; cat /sys/block/$(basename $d)/device/wwid 2/dev/null; doneWWN 是全球唯一标识刻在盘上换机器、换插槽都不变。RAID 卡和 HBA 卡一般都能读到。方式二序列号# 用 lsblk 直接看 lsblk -d -o NAME,SERIAL,MODEL # 用 smartctl 看需要 root smartctl -i /dev/sdb | grep -i serial方式三by-path 链接ls -l /dev/disk/by-path/by-path里的名字包含 PCI 地址和 ata 编号比如pci-0000:00:1f.2-ata-5这个和物理插槽的对应关系最直接。4.2 第二步把 ata 编号映射到物理槽位这是整个流程里最考验经验的一步。ata5到底对应机箱上哪个槽分几种情况情况一主板直连 SATA主板上的 SATA 口一般有丝印编号SATA0、SATA1...BIOS 里也能看到每个口的设备。ata编号和主板丝印的对应关系通常按控制器初始化顺序来但不绝对。最靠谱的办法是看主板手册 实际插拔验证。情况二RAID 卡/HBA 卡下挂盘这种情况ata编号意义不大要看Enclosure ID 和 Slot Number。用lsscsi -v或者厂商工具如storcli、sas2ircu能读到# LSI/Broadcom 卡查看物理槽位 storcli /c0/eall/sall show # 输出里 Enclosure 和 Slot 就是物理位置情况三NVMe 盘NVMe 一般直插主板 M.2 或 PCIe 转接卡。用nvme list和lspci结合看# 列出所有 NVMe 盘 nvme list # 看 NVMe 控制器的 PCI 地址 lspci | grep -i nvme # 对应关系 ls -l /sys/class/nvme/nvme0PCI 地址如0000:03:00.0能对应到主板上的具体插槽查主板手册即可。4.3 第三步用 LED 定位如果有服务器一般有硬盘活动/故障 LED。定位到槽位后可以用厂商工具点亮 LED 确认# 以 storcli 为例点亮某槽位 LED storcli /c0/e252/s3 start locate # 关闭 storcli /c0/e252/s3 stop locate这一步是“眼见为实”避免拔错盘。生产环境换盘前我一定先点 LED 确认这是铁律。4.4 完整实操案例从一条报错到定位坏盘假设日志里出现ata7.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0 ata7.00: failed command: READ FPDMA QUEUED ata7.00: error: { UNC }按下面步骤走# 1. 找到 ata7 对应的块设备 ls -l /sys/class/ata_port/ata7/ # 顺着链接找到 host7再找到 target再找到 block 设备 # 2. 或者直接反查 for d in /sys/block/sd*; do if readlink -f $d | grep -q ata7; then echo $d 对应 ata7 fi done # 3. 假设输出是 /sys/block/sdc拿到它的稳定标识 lsblk -d -o NAME,SERIAL,MODEL /dev/sdc cat /sys/block/sdc/device/wwid # 4. 查物理槽位假设是 RAID 卡下挂 storcli /c0/eall/sall show | grep -i sdc的序列号 # 5. 点亮 LED 确认 storcli /c0/e252/s5 start locate走完这五步你就能准确知道该拔哪块盘。整个过程熟练的话两三分钟。5. 常见报错对照与排查速查表5.1 报错信息与可能原因对照报错信息可能原因优先排查方向I/O error, dev sdb, sector xxx坏道、线缆、背板先换线缆再查 SMARTmedium error介质损坏立即备份准备换盘ata bus errorSATA 链路问题换线、换背板口nvme timeout盘固件、PCIe 接触重插、升级固件UNC(Uncorrectable)不可纠正读错误坏道换盘SMART: Reallocated_Sector_Ct增长重映射扇区增多预故障计划更换failed command: WRITE DMA写失败检查盘和线缆device offline设备掉线检查供电和连接5.2 用 SMART 做预判日志报错是“已经出事”SMART 是“可能要出事”。养成定期看 SMART 的习惯# 快速健康检查 smartctl -H /dev/sdb # 看关键属性 smartctl -A /dev/sdb | grep -iE Reallocated|Pending|Uncorrectable|Temperature # 短自检 smartctl -t short /dev/sdb重点关注三个属性Reallocated_Sector_Ct重映射扇区、Current_Pending_Sector待映射扇区、Offline_Uncorrectable离线不可纠正。这三个只要有一个非零且在增长这块盘就该列入更换计划了。5.3 排查思路速查流程遇到磁盘报错我一般按这个顺序走抓日志dmesg -T | grep -i error找到第一次报错。提线索提取ata编号、nvme编号、sd设备名。建映射用lsblk、lsscsi、/sys把逻辑名和控制器对应。拿标识用 WWN 或序列号锁定物理盘。定槽位查 RAID 卡工具或主板手册定位物理槽。点 LED确认无误再动手。看 SMART判断是换盘还是修线缆。6. 实操心得与避坑经验6.1 别信 sd 字母信 WWN这是我踩过最多次的坑。早期做运维看到sdb报错就去拔第二块盘结果拔错了把好盘拔了导致阵列降级。后来养成习惯任何换盘操作前先lsblk -o NAME,SERIAL核对序列号。序列号对不上坚决不动手。6.2 虚拟化环境要穿透看宿主机如果你在虚拟机里看到磁盘报错别急着在虚拟机里折腾。虚拟磁盘的报错往往是宿主机物理盘问题的“投影”。正确做法是# 在宿主机上看物理盘 lsblk -o NAME,SIZE,TYPE,MODEL,SERIAL # 看虚拟机和物理盘的对应以 KVM 为例 virsh domblklist 虚拟机名找到虚拟盘对应的物理盘再按前面的流程定位。虚拟机里的vda报错根因可能在宿主机的sdc上。6.3 线缆和背板是隐形杀手很多ata bus error、I/O error最后查下来不是盘坏而是SATA 线老化、背板接触不良、供电不稳。我的经验是先换线缆再换盘。换线成本几块钱换盘成本几百上千而且换盘还要重建阵列。曾经有一台机器反复报ata bus error换了三次盘都没解决最后发现是背板上一根电源线松动。6.4 RAID 卡下别用系统工具直接操作RAID 卡下挂的盘操作系统看到的是卡虚拟出来的逻辑盘如sdb物理盘被卡“藏”起来了。这时候smartctl直接读sdb可能读不到物理盘 SMART需要加-d参数穿透# 通过 RAID 卡读物理盘 SMART以 LSI 为例 smartctl -d megaraid,0 /dev/sdb smartctl -d megaraid,1 /dev/sdbmegaraid,0里的 0 是卡的设备 ID不是系统设备名。具体 ID 用storcli查。6.5 日志轮转可能吃掉关键证据/var/log/messages会轮转报错刷得快的时候关键的第一条可能被冲掉。我的做法是关键服务器把内核日志级别调高或者单独配rsyslog把kern.*存到独立文件。出问题时第一时间dmesg -T /tmp/disk_issue_$(date %s).log存档。用journalctl --since 1 hour ago -k按时间窗口捞。6.6 NVMe 盘的特殊性NVMe 盘走 PCIe没有 SATA 那套 ata 编号。它的报错定位靠PCI 地址 控制器编号。另外 NVMe 盘温度高过热会降速甚至掉盘日志里可能出现nvme timeout。遇到这种情况先看温度# 看 NVMe 温度 nvme smart-log /dev/nvme0 | grep -i temp sensors | grep -i nvme温度超过 70 度就要考虑加散热片或改善风道了。7. 把定位流程固化成习惯处理磁盘报错最怕的不是技术难而是慌乱中拔错盘。我现在的习惯是不管多急先花两分钟走完“抓日志 → 提线索 → 建映射 → 拿标识 → 定槽位 → 点 LED”这套流程。两分钟换来的是一次拔对比事后重建阵列划算太多。另外建议把常用命令做成脚本或别名比如# 加到 ~/.bashrc alias diskmaplsblk -o NAME,SIZE,TYPE,MOUNTPOINT,MODEL,SERIAL alias diskerrdmesg -T | grep -iE error|fail|timeout | tail -50 alias smartallfor d in /dev/sd? /dev/nvme?n1; do echo $d ; smartctl -H $d 2/dev/null | grep -i result; done平时多跑smartall看看盘的健康状况比等报错再救火从容得多。磁盘这东西预故障阶段处理是维护故障后处理是事故两者的代价差着数量级。最后分享一个我用了很多年的小技巧给每台服务器的盘位建一张“序列号-槽位”对照表存在本地或配置管理里。换盘时直接查表比现场用工具查快得多也避免了工具在某些环境下读不到信息时的尴尬。这张表在机器刚上架、盘都是好的时候建最省事。
返回列表