ARTICLE DETAIL

资讯详情

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

Linux存储故障排查:dmsetup remove_all清不掉“存储正忙”怎么办

Linux存储故障排查:dmsetup remove_all清不掉“存储正忙”怎么办 简介面向Linux服务器运维与存储管理人员的实战型资料聚焦同一存储设备需共享挂载至两台服务器却因一台服务器故障导致另一台无法挂载或提示“存储正忙”的常见问题。文档以dmsetup命令为主线从设备文件与Device-Mapper映射机制入手先梳理共享存储冲突的产生原理再给出在故障服务器上执行dmsetup remove_all清理映射后重新挂载的解决步骤并延伸到快照、克隆、镜像等高级用法使读者既能快速应急排障也能系统掌握dmsetup在存储管理中的典型应用场景。全文按问题分析、解决方案、结论组织重点突出排错路径可复现便于运维人员快速定位关键命令。包体为1个docx文档仅11KB内容精炼适合快速查阅。已有1646人学习/下载适合需要处理共享存储冲突、学习dmsetup命令的Linux运维和存储工程师参考。1. 双机共享存储的“夺命”现场一台宕机另一台报存储正忙做存储运维的人大概率都碰过这种场面一套双控存储通过光纤或者 iSCSI 同时挂给了两台 Linux 服务器本来跑得好好的结果其中一台因为断电、内核 panic 或者重启就“猝死”了。剩下的这台服务器想接管存储挂载时却直接弹“storage is busy”或者“设备或资源忙”。第一反应是拔线重插不行重启 multipathd不行最后被老前辈指点在备机上敲了一行dmsetup remove_all世界才安静下来。这行命令解决的不是“抢盘”本身而是把主机侧 Device-Mapper 层残留的映射关系也就是另一台服务器控制权消失后留下的“僵尸锁”清干净。很多刚接触多路径存储的同事甚至不少干了几年系统运维的人都以为dmsetup remove_all是万能的“卸载命令”其实它只是清空 Device-Mapper 的设备映射表用错场景轻则重启失效重则把系统盘的 LVM 映射也一并干掉。这篇笔记不绕弯子直接拆开这台“存储正忙”背后的机制把我处理这类问题时的完整排查路径和踩过的坑写出来适合负责 Linux 服务器存储挂载、双机共享存储、多路径环境的运维和 DBA 同事参考。2. 先看懂 Device-Mapper 与多路径为什么“存储正忙”是必然结果2.1 Device-Mapper内核里的“磁盘翻译层”Linux 里访问磁盘最终都要经过块设备层。而 Device-Mapper 是内核提供的一个通用块设备映射框架它的核心作用是把一个物理块设备重新映射成一个或多个逻辑设备。像 LVM 的逻辑卷、软 RAIDmdadm 的某些模式、DM 快照、dm-crypt 加密盘底层全都是 Device-Mapper 在起作用。我们用dmsetup ls能看到当前系统上所有 Device-Mapper 的逻辑设备它们被统一归纳在/dev/mapper/目录下面。比如 LVM 的逻辑卷常显示为/dev/mapper/vgdata-lvdata多路径盘显示为/dev/mapper/mpatha或者/dev/mapper/3600c0ff000...。这里最容易混淆的是很多人把/dev/mapper/目录里的设备理解成“物理磁盘”实际上它只是一个映射关系。Device-Mapper 设备有三个关键属性设备名name、映射表table、唯一标识uuid。dmsetup table可以看到某台逻辑设备底层对应的真实物理设备。比如一个多路径设备mpatha的 table 里通常有 4 个条目对应四个存储控制器端口路径这也就解释了为什么/dev/mapper/目录下的设备能“屏蔽”底层物理路径的差异。2.2 multipath 把四路路径合并成一块“逻辑盘”企业级存储一般都有双控制器每个控制器再出两个前端端口这样一台服务器到存储就有 4 条物理路径。如果不用多路径软件系统会看到 4 个独立的/dev/sdX设备指向同一个 LUN后果是裸设备直接读写会产生元数据错乱因为操作系统根本不知道这 4 个盘其实是同一块数据。multipathd的作用就是根据每个 SCSI 设备的 WWID也就是全球唯一标识符把这 4 条路径合并成一个/dev/mapper/mpathX。这个动作的关键在/etc/multipath.conf里的配置比如cat /etc/multipath.conf输出中的wwid绑定和alias命名规则决定了 multipath 怎么识别和命名设备。我一般会在里面显式指定需要合并的设备列表防止它误把两块不同 LUN 的盘当成同一块盘。这里有个很多新手会犯的错误他们以为multipath -ll里看到 mpath 设备就是物理盘直接在/etc/fstab里写/dev/mapper/mpatha也没问题。但一旦存储侧调整过 LUN 映射比如更换了控制器旧 WWID 遗留在系统里multipathd就会重新生成一套新映射/dev/mapper/mpatha可能指向完全不同的 LUN这就是后续“存储正忙”或者说挂载异常的隐患源头之一。2.3 存储正忙的真实链路SCSI 预留与残留映射回到最原始的问题为什么一台服务器崩了另一台挂不上大多数双机共享存储场景要么跑的是集群文件系统如 GFS2、OCFS2要么是数据库裸设备如 Oracle ASM要么被第三方集群软件接管。这些场景下存储侧会启用 SCSI-3 Persistent Reservation也就是持久预留锁。节点 A 通过 PR 注册一个 reservation key 并占有 LUN节点 B 作为后备节点虽然路径也能看到 LUN但没有合法的 key并发写入会被存储拒掉。当节点 A 异常宕机比如断电它的 PR key 不会主动释放是 lease 超时之后由存储控制器自动清除的超时时间通常是 30 到 60 秒。但如果节点 A 只是被强制重启操作系统没来得及走正常卸载流程那么主机侧遗留的 Device-Mapper 映射里还“粘着”这个旧 key。节点 B 尝试挂载时SCSI 层交互就出现冲突表现就是mount卡住或者直接报device busy。还有一种更常见的非集群场景两台服务器不加任何集群锁直接把同一个 LUN 用 ext4/xfs 挂到各自的/data目录这种配置本身就是高危的。一台挂了另一台对存储发出的指令会因为缓存不一致、文件系统日志错乱而被拒绝dmesg里通常能看到I/O error和sdX: reservation conflict之类的信息。所以dmsetup remove_all能解决的是“主机侧的映射残留”根源上的“锁”和“数据一致性”问题是避免不了的这个边界务必要清楚。3. 实操dmsetup remove_all 与完整排障流程3.1 第一步别急着 remove先看清现场接到故障我习惯先收集 4 个输出分别是 multipath 状态、dm 映射列表、LVM 卷状态、SCSI 设备状态multipath -ll dmsetup ls pvs lvs cat /proc/scsi/scsi为什么先做这一步因为dmsetup remove_all是无差别清理所有 Device-Mapper 设备都会被尝试移除。如果存在一个 LVM 卷组正在被系统盘根文件系统使用盲目执行会有不可逆后果比如/dev/mapper/centos-root里的 root 逻辑卷是被系统挂载着的remove_all 对它是无效的但同样会报错其他未挂载的映射则被清理掉。这个“先看后动”的习惯能帮你判断哪些映射是有价值的哪些是残留的僵尸映射。关键看两点multipath -ll里active/passive状态以及dmsetup ls里设备名。如果一台服务器宕机后这台服务器上的 mpath 设备变成了undef状态或者路径数从 4 变成 0这种映射就是失效的是清理对象。3.2 第二步按依赖顺序卸载与停用正常的清理顺序必须遵循“从顶往下”的原则也就是先卸载文件系统再停止 LVM 卷组再刷新 multipath 状态最后才是dmsetup remove_allumount /data vgchange -an vgdata multipath -F dmsetup remove_allumount是释放文件系统层的占用vgchange -an是停用卷组告诉 LVM 不再管理这些物理卷对应的 dm-linear 映射会被释放multipath -F是刷新 multipath 设备表让 multipathd 放弃当前路径的管理权。当这三步做完dmsetup 再执行 remove_all 时就能把剩余残留映射一次性清掉。如果之前的步骤有遗漏比如卷组没有停用remove_all 通常会报 target is busy。参数说明multipath -F里的F是大写表示 flush all multipath devices不是-fflush a specific device。dmsetup remove_all后系统里/dev/mapper下应该只剩系统盘自身的映射。3.3 第三步重新识别存储并挂载清理只是半程后半程是把盘重新认回来。很多时候这台服务器是作为“接管方”存储侧本身的 LUN 还在需要重新扫描 SCSI 总线让内核重新发现设备echo - - - /sys/class/scsi_host/host0/scan echo - - - /sys/class/scsi_host/host1/scan这里的- - -是三个通配符分别表示 channel、target、lun意思是对该 HBA 的所有通道、所有目标、所有 LUN 做全量扫描。扫描完成后dmesg和/dev/disk/by-id能看到新的 sd 设备出现。之后再启动 multipath 重新合并路径并挂载验证systemctl restart multipathd multipath -ll mount /dev/mapper/mpatha /data常见做法是重启 multipathd 后再执行multipath -F和multipath -v2重新生成设备最后确认/data下的数据能看到之前的内容再正常对外提供业务。这里有个细节扫描之前要看 HBA 号的列表不同机器 HBA 数量不同用下面的命令确认ls /sys/class/scsi_host/3.4 强制清理的场景与风险边界如果在执行dmsetup remove_all时系统提示Device or resource busy而且你已经确认对应的文件系统和卷组都已经停用说明有残留进程占用了块设备。这时候可以加--forcedmsetup remove_all --force这个选项会强制删除映射不检查设备是否在使用的状态。但是强烈不建议在业务运行中的生产环境直接这样搞因为它跳过的是内核的引用计数检查强制删除后进程对这块盘的读写会直接卡死。只有在确认这台机器已经彻底不需要该存储比如存储侧已经释放、业务已切走、当前服务器只是“残留”状态时才用。一个我常用的确认手段是fuser -vm /dev/mapper/mpatha这个命令会列出哪些进程正在使用该设备。如果没有进程输出说明只是映射残留force 是安全的。4. 避坑清单remove_all 没删掉、误删盘、重启失效4.1 remove_all 执行了但提示 Device or resource busy现象在故障机上执行dmsetup remove_all命令一直在刷Device or resource busy看起来没效果。原因dmsetup remove_all只能清理没有 in-use 的映射。这个 in-use 不只是文件系统挂载还可能是正在被某进程直接打开的/dev/mapper/xxx设备比如 Oracle ASM 的裸设备就是直接绑定/dev/mapper/3600...的此时没有经过文件系统层umount根本管不到。解决先用lsof或者fuser找到打开该设备的进程。如果是数据库实例先停数据库服务再执行dmsetup remove_all。如果是集群软件控制的设备比如 Pacemaker 的资源代理需要先把资源 disable 掉。有些时候/dev/mapper设备被 udev 或 systemd 引用需要先清理引用关系直接用dmsetup remove /dev/mapper/xxx针对单个设备操作。4.2 remove 之后 multipathd 又把 mpath 拉回来了现象dmsetup remove_all执行完dmsetup ls里已经空了但过了几秒multipath -ll又看到 mpath 设备出现而且路径状态正常重新进入 pending 或 active 状态。原因multipathd是一个常驻守护进程它会周期性地重新检查 SCSI 设备并自动创建多路径设备。你执行dmsetup remove_all删掉映射后multipathd 检测到底层 sd 设备仍然存在就把映射重新建立了。这在故障处理中其实不是坏事但如果你需要把这块盘“晾”在一边等待存储侧动作这个行为就会造成干扰。解决先停掉 multipathd 再 removesystemctl stop multipathd dmsetup remove_all在/etc/multipath.conf里设置blacklist把暂时不需要的 LUN 加进去防止后续再被自动接管。处理完问题后把黑名单里的条目移除启动 multipathd 才能正常识别这块盘。4.3 本想删存储盘映射结果把系统盘的 LVM 也删了现象remove_all 执行完重启之后系统直接进入 rescue 模式root 逻辑卷找不到。原因系统盘如果用 LVM 配置/dev/mapper/centos-root本身就是 Device-Mapper 映射一个remove_all会把它也尝试删掉。如果当时系统没有挂载根文件系统的冲突或者你在 rescue 模式下手动执行了这条命令逻辑卷的映射就被彻底删除了这时 LVM 元数据在磁盘上虽然还在但内核里没有了映射关系。解决永远不要在系统盘还作为 LVM 卷组活跃时执行dmsetup remove_all。处理共享存储问题时先通过vgdisplay确认哪些卷组属于共享存储哪些属于本机系统盘。只对故障存储对应的卷组执行vgchange -an然后删除该卷组对应的 dm 设备。真误删了系统盘映射也不要慌重启进入系统后执行vgscan和vgchange -ay重新激活卷组通常能恢复前提是你没有同时执行过vgremove。这一点非常关键不要在紧张的时候狂敲 remove_all。4.4 存储侧重启后服务器怎么都认不到盘现象存储控制器升级或重启完成LUN 正常但服务器执行multipath -ll看不到路径dmesg里也没有识别到新设备。原因很多情况是服务器 SCSI 设备层还保留着故障前状态。存储侧重启会断开链路服务器上的 scsi_device 变成 offline 或 deleted 状态需要先删除旧的 scsi 设备对象再重新扫描。直接执行 scan 往往没用因为内核认为该设备还在。解决先删掉对应 HBA 上所有失效设备对象再重新扫描echo 1 /sys/class/scsi_device/2:0:0:1/delete echo - - - /sys/class/scsi_host/host2/scan这里的2:0:0:1对应 HBA 号:通道:目标:LUN。要确认哪些设备处于 offlined 状态看dmesg | grep -i offline或者直接cat /sys/class/scsi_device/*/state。删除时可以先用multipath -l拿到路径信息再从路径的sysfs链接反查 scsi_device 编号。4.5 多路径 wwid 冲突导致两块 LUN 被合并成一块现象挂载后发现文件系统数据“错乱”两块不同用途的 LUN 显示成同一个 mpath 设备存储上的数据不敢用了。原因multipath.conf的wwid配置写错或者底层磁盘无 WWID 时 multipath 错误使用了设备的序列号做合并依据。通常发生在存储厂商自带的序列号不唯一或者某些虚拟化平台对 WWID 的传递不完整。解决在multipath.conf里显式书写正确绑定multipaths { multipath { wwid 3600c0ff0000000000000000000000000 alias datalun } }配置完后执行multipath -r重建设备映射确认multipath -ll里 datalun 对应的是正确的物理路径集合。不同 LUN 一定要用不同 alias不要用默认的 mpathN 命名这样即使出现异常也能一眼看出来。5. 从命令到习惯处理共享存储故障的复验动作dmsetup remove_all本身并不神秘几十个字符的事情。真正容易翻车的是操作前后少做了几次校验导致你以为恢复了几天后才发现问题。现在我处理这类故障固定强制走一遍“三板斧”验证流程缺一步就不算完。第一板斧是验证映射表。恢复挂载后把dmsetup ls输出存成一个文件再和故障发生前的输出对比确认没有多出莫名其妙的新映射。特别是那些uuid和故障时不一样的设备一定要查清楚来源。第二板斧是验证读写链路不能只看挂载成功就收工。对关键目录做过一次真实写读dd if/dev/zero of/data/testfile bs1M count1024 convfdatasync dd if/data/testfile of/dev/null bs1M count1024convfdatasync会让数据绕过 page cache 直接落到存储这一步能抓到 multipath 路径配置错误导致的写失效问题。第三板斧是重启环境验证。生产环境不敢重启至少也要在主备机之间做一次切换演练确认下次一台宕机时另一台能在 60 秒内完成挂载接管。这一步暴露过很多“隐藏配置”比如/etc/fstab里挂载参数写死或者 udev 规则里残留旧 wwid 映射这些在平时的运行中完全看不出来。这个故障处理中最深刻的一次教训是我最开始处理“存储正忙”时只知道闷头执行dmsetup remove_all结果在北向监控里看到系统盘 LVM 映射丢失的报警才意识到自己差点把生产系统搞挂。从那以后我每次执行 remove 类命令之前都会强制走一遍后面的动作先multipath -ll和pvs、lvs三连摸底确认系统盘卷组和共享存储卷组是干净隔离的再动手。这种故障处理处理的是映射表和锁状态赌的就是你对现状的把握足够准确。希望这篇笔记能帮你少踩我踩过的那些坑。本文还有配套的精品资源点击获取
返回列表