尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
共享存储双挂报错busy?dmsetup remove_all 排障与恢复指南
简介面向Linux运维与存储管理人员的实用技术文档聚焦同一存储设备挂载到两台服务器时因其中一台已挂载而导致另一台无法挂载或提示存储正忙的经典故障系统梳理问题成因与完整排查思路。内容以Linux存储管理与dmsetup命令详解为主线从设备文件映射机制讲起深入分析多服务器并发访问底层存储时的设备冲突并给出使用dmsetup remove_all清理映射关系、重新挂载存储的可行方案帮助运维人员快速恢复共享存储的可用性。文档在故障处理之外还延伸介绍了dmsetup在快照、克隆与镜像等高级存储管理场景中的用法便于读者拓展技能、举一反三提升数据安全与存储管理效率。整个过程从故障现象、底层原理到操作命令逐步拆解结构清晰便于按需查阅。整个资源包共1个docx文档容量仅11KB轻量便携内容精炼适合备查。自发布以来已有1648人学习是处理多服务器共享存储挂载问题的实用参考。1. 同一个存储挂两台服务器一台宕机后另一台报存储正忙的真相做双机或 HA 集群的兄弟大概率遇到过这个场景一套存储 LUN 同时映射给两台数据库服务器某天一台机器重启或者异常掉电另外一台想重新挂载这个共享存储结果要么 mount 卡住不动要么直接报device is busy/storage is busy更诡异的还会在/var/log/messages里看到一堆 I/O error。多数人第一反应是存储端出了问题反复找存储厂商排查最后发现罪魁祸首在 Linux 主机侧的 Device-Mapper 映射残留里。这篇文章不打算从存储协议讲起直接把排障路径和目标写清楚同一个 LUN 双挂场景下一台服务器挂掉之后另一台为什么起不来、怎么快速恢复、如何避免下次再翻车。全文围绕一个核心命令dmsetup remove_all展开但它远不是敲一下回车那么简单执行前不核查会牵连本地系统盘执行后不重建映射盘就恢复不了业务。这套流程适合做数据库双机、虚拟化宿主机共享存储、以及任何用到共享 SAN/iSCSI LUN 的运维和交付工程师。2. Device-Mapper 与 dmsetup先搞懂存储正忙到底是谁在忙2.1 设备映射机制为什么 LUN 在 Linux 里不是一个裸设备Linux 访问块设备不是直接读写sdb或者sdc在存储映射场景下几乎都会经过 Device-MapperDM这一层。DM 是内核里的一个框架它把物理块设备重映射成逻辑设备常见产品包括 LVM2、软 RAIDmdadm 之外的 dm-raid、multipath 多路径软件以及容器存储用的 thin provision 都是基于 DM 实现的。当你把一个 LUN 映射给服务器后内核会生成/dev/sdX这类 SCSI 设备节点但 multipath 随后会把多个路径比如两个 HBA 卡出来的四个路径绑定成一个逻辑设备/dev/mapper/mpathX。这个绑定动作就是通过 DM 完成的设备号通常是dm-0、dm-1这样的编号。dmsetup 是用户态管理 DM 设备的命令行工具它的作用就是查看、创建、删除这些映射关系。回到存储正忙这个问题上——当服务器 A 挂了存储端可能还保持着它发出的 SCSI 预留Persistent Reservation或者锁状态服务器 B 在访问同一个 LUN 时DM 层还保留着旧的映射表和持锁状态。此时你执行 mount内核去查询这个 DM 设备发现它仍然被一个无效的路径占用就返回 busy。换句话说busy 不是来自进程而是来自 DM 层的旧映射没有释放干净。2.2 dmsetup 命令全家桶查看、删除、重建映射排障的第一步永远是先看当前 DM 设备的状态不要上来就 remove_all。以下命令是我每次处理双挂共享存储问题时必查的# 查看当前所有 DM 设备的简要状态 dmsetup ls # 查看某个设备比如 mpatha的详细映射表 dmsetup table /dev/mapper/mpatha # 查看某个设备当前是否有打开的句柄 dmsetup info /dev/mapper/mpatha # 查看 DM 设备的依赖关系父设备、子设备 dmsetup deps /dev/mapper/mpathadmsetup ls输出会显示设备名和主次设备号dmsetup table能看到映射目标类型linear、multipath、mirror 等以及底层依赖的物理路径。dmsetup info里有几项关键内容Open count表示当前有几个进程或内核模块持有该设备Event number表示变更次数。提示Open count 如果大于 0说明有东西正在使用这个 DM 设备直接 remove 会失败。这时候要先找到持有者常见的元凶是 LVM 的 VG 没停、文件系统没卸载、或者数据库进程还挂着句柄。2.3 什么时候必须用 remove_all什么时候不能碰dmsetup remove_all的作用是删除当前所有 DM 设备映射。注意是所有——它不区分你挂的是共享存储还是本地系统盘。如果服务器根分区是用 LVM 做的绝大多数生产机器都是那/dev/mapper/centos-root或ubuntu--vg-root这类设备也是 DM 设备执行 remove_all 会把它们一并删掉。后果就是系统直接失联必须重启才能恢复。哪些场景必须用 remove_all我总结下来有两类第一类是共享存储双挂场景下某台机器异常宕机后另一台机器上残留了一堆 stale 的 multipath 或 LVM 映射单个设备 remove 不掉因为 DM 设备的依赖关系已经被打乱了必须一次性清空再重建。第二类是存储端 LUN 被重新分配过比如从一个阵列迁移到另一个阵列WWN 变了但服务器上还有旧的映射指向已经不存在的路径。哪些场景坚决不能用本地 LVM 设备活跃的时候、有文件系统正在读写的时候、以及根分区在 DM 设备上且你没把握在 remove 之后能从外部触发重新扫描的时候。后面避坑章节会详细拆这几个场景。3. 实战排障从报错到恢复的完整操作流程3.1 第一步确认环境与收集证据拿到一台报存储正忙的服务器不要急着执行任何删除命令。先按下面的清单确认环境和状态# 1. 看当前挂载情况确认哪些文件系统关联到共享存储 mount | grep -E mpath|mapper|sd[bcdef] # 2. 看多路径拓扑确认路径状态 multipath -ll # 3. 看 LVM 卷组状态确认哪些 VG 是共享存储上的 vgs lvs # 4. 查看内核日志中关于 SCSI/多路径的报错 dmesg -T | grep -E multipath|mpath|scsi|I/O error|busy | tail -50重点看multipath -ll的输出。正常状态下每个 LUN 应该显示为一条mpathX且路径状态是active ready。出问题的时候你会看到路径状态变成failed、timeout或者同一个 WWID 下路径数目不对更典型的是出现多条mpatha的重复条目——这说明 multipath 的映射表和实际存储拓扑已经对不上了。还有一个必须注意的点vgs里如果看到同一个 VG 出现在两台服务器上比如共享存储上的 VG 名字叫vg_shared且两台机器都在用那问题可能不只是 DM 残留还有 LVM 的锁机制在起作用。这里先不展开排障流程会提到 LVM 锁的处理方法。3.2 第二步逐级卸载与停用从最上层往下拆只要是双挂场景我建议的操作顺序是从上往下逐层释放直接 remove_all 属于最后手段。正确顺序是这样# 1. 先卸载文件系统如果还能卸载的话 umount /mnt/shared_data # 2. 停用 LVM 卷组这一步会释放 VG 层面的锁 vgchange -an vg_shared # 3. 刷新多路径设备把路径状态重新扫一遍 multipath -r multipath -ll # 4. 再尝试移除 DM 设备 dmsetup remove /dev/mapper/mpatha这段命令的逻辑是文件系统不卸载DM 设备 Open count 不可能归零VG 不 deactivateLVM 会一直持有设备引用multipath 不刷新路径表里还是旧的映射信息。vgchange -an这里的-a表示 activate-n表示 no合起来就是把所有卷组设置为不激活。不激活实际上就是把 LVM 内部的设备映射从活动状态变为非活动状态这时候 LVM 持有的 DM 映射会被释放。如果dmsetup remove提示device busy说明还有进程拿着句柄。这时候用fuser -v /mnt/shared_data查进程确认后再处理# 查看谁占用了这个挂载点 fuser -v /mnt/shared_data # 强制终止占用进程不适合数据库场景数据库需要先停实例 fuser -km /mnt/shared_data注意fuser -km适合清理无用的堵塞进程但对于数据库双机场景要谨慎——直接把数据库进程 kill 掉存储上还可能有未完成的写事务切回时要先走数据库恢复流程。3.3 第三步remove_all 的精确使用方式如果上面逐级释放到一半就卡住——比如某个 DM 设备dmsetup remove一直报 busy但fuser又查不到占用进程——这就是典型的 DM 层映射损坏。此时需要跳过单个设备删除直接执行# 在执行前先确认当前 DM 设备列表 dmsetup ls # 确认根分区等关键设备的状态 lsblk | grep -E dm-|NAME # 执行全部移除不影响已卸载的普通设备但会删掉所有 DM 映射 dmsetup remove_alldmsetup remove_all执行完后系统里所有 DM 设备映射都会被清掉。此时你会看到lsblk里的dm-0、dm-1等设备全部消失但底层的/dev/sda、/dev/sdb等物理设备还在。这一步很关键——执行完 remove_all 不代表结束还得重建映射。重建有两种方式# 方式一手动重新扫描并重建 multipath 映射 multipath -r multipath -ll # 方式二如果系统盘是 LVM需要重新激活卷组恢复根分区挂载 vgscan vgchange -ay mount -amultipath -r会重新读取/etc/multipath.conf配置并重新发现所有存储路径对应的 WWID然后创建新的 DM 映射。vgscan是重新扫描系统中所有 LVM 卷组元数据vgchange -ay将所有卷组重新激活。注意执行顺序必须是先 multipath 后 LVM因为 LVM 的 PV 是构建在多路径设备之上的。如果先把 VG 激活了而 multipath 设备还没建好LVM 会扫描不到 PV。3.4 第四步验证恢复结果清理和重建做完需要确认三件事底层路径正常、映射关系正确、业务可以重新挂载# 确认多路径状态正常 multipath -ll # 确认 DM 设备已经重新生成 dmsetup ls lsblk # 激活卷组并挂载文件系统 vgchange -ay vg_shared mount /dev/mapper/vg_shared-lv_data /mnt/shared_data # 验证读写正常 dd if/dev/zero of/mnt/shared_data/testfile bs1M count100 oflagdirectoflagdirect是直接 IO绕过文件系统缓存直写块设备这样验证的是物理链路是否真的通了而不是写进了 page cache。实测中这一步很有用之前遇到过一次多路径显示 normal但实际 IO 路径断开用dd验证立刻暴露问题。4. 双挂场景中的 LVM 锁与多路径边界为什么 remove_all 不总是万能药4.1 LVM 锁机制共享卷组的隐性问题双挂场景下如果共享存储上建了 LVM 卷组比如vg_shared问题会更加复杂。LVM 默认情况下假设一块 PV 只有一个主机在访问不会做跨节点的锁管理。两台服务器同时激活同一个 VG 时LVM 元数据会被后者覆盖造成逻辑卷信息丢失。这就是为啥双挂场景推荐用集群文件系统或存储端的锁服务而不是裸 LVM。但如果项目已经用上了裸共享 LVM很多老项目确实这么干一台宕机后另外一台激活 VG 时会看到 LVM 报device not seen或者元数据不一致的警告。这里有个参数要知道/etc/lvm/lvm.conf里的volume_list和locking_type。如果locking_type用的是 1默认 posix locking那么同一时间只有一台机器能持有 VG 的锁。这时候vgchange -ay可能直接失败提示锁不可用。这个报错非常容易和三台服务器的 DM busy 问题混淆但排查逻辑不同——先看 VG 锁再查 DM 映射。# 查看 LVM 锁类型 cat /etc/lvm/lvm.conf | grep -E locking_type|fallback_to_clustered # 激活共享 VG加 --force 前先确认没有其他节点在激活状态 vgchange -ay vg_shared --force4.2 多路径配置边界prio 和 path_grouping_policy 的坑dmsetup remove_all之后执行multipath -r重建但如果 multipath 配置本身有问题重建出来的映射还是错的。最常见的坑是path_grouping_policy配置不当。存储双活场景两个控制器同时工作推荐用multipath的默认配置——按优先级组划分路径。但有些存储设备不同控制器的路径优先级一样或者需要根据阵列实际拓扑手动定义defaults { path_grouping_policy multibus path_selector round-robin 0 path_checker tur failback immediate no_path_retry 5 }上面配置的解释path_grouping_policy multibus表示所有路径放在一个组里适合双活存储path_selector round-robin 0是轮询算法读写压力均匀分摊到所有路径path_checker tur用 Test Unit Ready 检查路径状态failback immediate是路径恢复后立刻切回no_path_retry 5是所有路径断开后重试 5 次再报错。真实场景里如果存储是主备模式两个控制器一主一从multibus会导致 IO 跑到备用控制器上然后被存储端拒绝表现为间歇性 IO 错误。这时候必须改成defaults { path_grouping_policy failover path_selector service-time 0 }failover策略下只有一条路径处于活动状态其他路径作为冗余IO 不会乱跑。这两者在共享存储双挂排障中的差异很大尤其是 remove_all 之后重建映射配错了会在日志里看到path down和path up频繁交替的现象。4.3 存储端的 SCSI 预留remove_all 清不掉的锁还有一个 dmsetup remove_all 解决不了的问题存储端 SCSI PRPersistent Reservation锁。如果是用了 SCSI-3 Persistent Reservation 的场景比如集群文件系统、VMware 的 Metro Cluster一台机器宕机后它的 PR KEY 还留在存储端。另一台机器访问这个 LUN 时存储端直接就返回 reservation conflict。错误现象是mount报错或者 dmesg 里出现RESERVATION CONFLICT此时 DM 层其实是干净的remove_all 也清不掉锁。这种锁的清理通常要在存储端或者通过 sg3_utils 工具来做# 查看 LUN 上的 PR 信息 sg_persist --in --read-reservation /dev/sdb # 查看所有注册的 PR KEY sg_persist --in --read-keys /dev/sdb # 清除指定 KEY需要知道发起者的 transport id sg_persist --out --clear /dev/sdb注意sg_persist --out --clear会清掉 LUN 上所有 PR 注册信息执行前务必确认没有其他集群节点还在正常使用这台存储。所以做双挂场景排障时判断方向很重要如果是 IO 超时、mount 卡死大概率是 DM 和路径问题走 dmsetup 流程如果 dmesg 直接报RESERVATION CONFLICT先查 PR 锁别在主机侧白折腾。5. dmsetup remove_all 高频踩坑5 个会让你翻车的细节5.1 坑一remove_all 把本地系统盘的 DM 映射也删了现象执行dmsetup remove_all后终端立刻断开服务器失去响应ping 不通。重启后才恢复但挂载的共享存储还是没起来。原因系统盘如果用 LVM 做的根分区/dev/mapper/centos-root就是个 DM 设备。remove_all不会区分本地盘和共享盘一视同仁全部删掉。根分区的 DM 映射消失后内核虽然还有文件系统元数据在内存里但一旦产生新的 IO 请求需要访问块设备就会因为找不到映射而卡死系统直接假死。解决在执行 remove_all 之前先确认系统盘是不是 DM 设备lsblk /dev/sda # 如果输出里有 dm-0 或 mapper/xxx说明系统盘是 LVM如果是建议改用精确删除手动指定设备名逐个移除共享存储对应的 DM 设备或者先vgchange -an停用本地和非共享的 VG把需要保留的映射先缩小范围。5.2 坑二remove_all 后不再执行 multipath -r直接挂存储现象执行完dmsetup remove_all然后直接mount /dev/sdb1 /mnt能挂上但 IO 极慢dd测试每秒只有几十 MB而且日志里全是路径错误。原因remove_all 之后多路径映射完全被清掉底层 SD 设备是直通裸盘路径。如果存储有多条路径双 HBA、双控制器此时只走了一条物理链路单链路带宽受限而且缺少路径冗余和故障切换。解决remove_all 之后务必执行multipath -r重建映射等multipath -ll显示路径数量和状态正常后再挂载/dev/mapper/mpathX而不是/dev/sdbX。5.3 坑三数据库进程持有文件句柄不释放现象umount报target is busyfuser -v能看到数据库进程杀掉后立刻重挂没问题但业务侧后续出现文件损坏或数据不一致。原因数据库尤其是 Oracle、MySQL 这类对 IO 有强一致性要求的软件异常被 kill缓冲池里的脏数据没有被安全下盘redo/undo 日志不一致下次启动要走恢复流程。fuser -km属于暴力清进程但数据库的恢复必须由数据库自身完成。解决双机场景下如果还能连上数据库先执行shutdown immediate或等价的安全停止流程确认进程退出后再 umount。如果连不上宁可等它 hang 住也不要用-9强杀。血的教训有一次生产库就是被fuser -km清掉起库时花了 6 小时做实例恢复。5.4 坑四执行 remove_all 后 LVM 元数据缓存导致 VG 找不回来现象vgscan扫描后 VG 还在但vgchange -ay提示 PV 不存在或者激活后 LV 设备没有生成。原因LVM 的元数据和过滤器缓存。/etc/lvm/cache/下的.cache文件记录了之前扫描到的设备状态。remove_all 清掉 DM 映射后缓存还指着旧的设备 ID导致 LVM 使用了过期的缓存信息。解决# 清除 LVM 缓存 rm -rf /etc/lvm/cache/* # 重新扫描 PV pvscan --cache # 再次激活 VG vgchange -ay vg_sharedpvscan --cache会用当前实际的设备拓扑重建缓存这相当于 LVM 层面的后悔药机制。如果不执行这一步LVM 可能永远看不到新重建的 multipath 设备。5.5 坑五双挂场景下没考虑对方节点remove_all 后存储被抢挂现象两台服务器共享同一个存储在服务器 B 上执行 remove_all 和 multipath -r存储上的数据卷组被 B 抢先激活服务器 A 恢复后挂载报 VG 已锁定。原因共享存储的 LVM 卷组没有做集群感知。B 在 remove_all 之后重新激活了 VGA 的 DM 映射也重建了但 LVM 锁不允许两个节点同时激活同一 VG。这不是 DM 的问题是整个架构缺少共享存储的锁管理。解决双挂 LVM 场景要么改用集群文件系统如 GFS2配合 DLM 锁要么用存储端 PR 锁要么把 LVM 换成裸设备或集群 LVMlvmconf --enable-cluster。如果没有这些机制至少在业务切换时约定好严格的顺序明确谁先挂、谁后挂不要两边同时操作。6. 验证与预防从一次事故中固化的双挂存储操作清单经历过一次双挂存储故障后我给自己定了一套强制验证流程每次处理共享存储挂载问题都必须走完。这套流程并不复杂但能在恢复之后快速暴露隐患也能防住上述 5 个坑复发。第一步是重建映射后的可视化验证。执行完multipath -r之后不要只看multipath -ll显示正常就急着挂载我会额外用dmsetup table对照映射表里的 WWID 是否与存储端分配的一致。有一次存储端被人改过 LUN 的 WWIDmultipath -ll显示一切正常但dmsetup table里的底层设备路径和预期不对最终定位到存储端配置错误。第二步是强制检查路径状态与 IO 时延。用fio或dd直接写入并对比耗时不能用普通文件系统 IO 代替。之前遇到过路径状态显示活跃但实际吞吐异常的案例dd直写把问题暴露得干净利落。第三步是启动时的自动扫描脚本。我会在/usr/local/sbin/下放一个恢复脚本内容大致如下#!/bin/bash # 双挂存储恢复脚本remove_all 后自动重建映射 # 适用场景共享存储异常后另一台服务器无法挂载 # 1. 清除 LVM 过期的设备缓存 rm -rf /etc/lvm/cache/* # 2. 重新扫描 multipath 路径 multipath -r multipath -ll # 3. 激活 LVM 卷组等待 5 秒确保多路径稳定 sleep 5 vgscan vgchange -ay vg_shared # 4. 挂载文件系统 mount /dev/mapper/vg_shared-lv_data /mnt/shared_data这个脚本的逻辑是先清除 LVM 缓存防止旧拓扑信息干扰然后重建 multipath 映射确认路径状态等 5 秒是为了让 sysfs 中的设备节点和 udev 规则全部生效最后激活卷组并挂载。从那以后我每次处理双挂存储问题都强制走一遍先查 PR 锁、再看 LVM 锁、最后才动 DM的顺序。PR 锁用sg_persist看LVM 锁看vgchange的返回信息DM 层问题才用dmsetup系列命令。这个顺序帮我区分了很多次看起来像 DM 问题但实际是存储端问题的假象。希望这套排查思路能帮到你少走一些我当初趟过的弯路。本文还有配套的精品资源点击获取
RELATED

相关推荐

智诺方AI|期刊论文结论与展望,AIGC检测实操要点

智诺方AI|期刊论文结论与展望,AIGC检测实操要点

同学最常问的「结论与展望」问题 我坚持一点:智诺方AI是定点手术刀,不是整篇代写按钮。 结论与展望最忌复读结果、或写成万能展望。它应回答研究问题、收束贡献,并诚实写局限——而不是再开一篇新论文。 直接回答 先说观点:检测分…

📅 2026/10/16 17:41:39
变电站设备检测数据集 | 5000张YOLO电力巡检数据集

变电站设备检测数据集 | 5000张YOLO电力巡检数据集

变电站设备检测数据集 | 5000张YOLO电力巡检数据集 适用于变电站智能巡检、设备台账盘点与目标检测研究 一、数据集概述 本数据集面向计算机视觉目标检测任务,专为变电站高压电气设备部件检测模型训练、验证与测试设计,共包含约5000张高质量标注图像&a…

📅 2026/10/16 17:41:39
C#日期时间处理避坑指南:DateTime与DateTimeOffset选型实战

C#日期时间处理避坑指南:DateTime与DateTimeOffset选型实战

1. 为什么日期时间处理是C#开发中“看似简单却最容易翻车”的环节在某高校的.NET实训课上,我带过一批刚学完语法基础的学生做课程设计。项目需求很朴素:做一个学生考勤系统,要求能按“本周”“本月”“本学期”统计出勤率。结果交上来的代码里…

📅 2026/10/16 17:36:37
MORE NEWS

更多资讯

📰

Java Swing文件管理器:跨平台生产级实现指南

1. 这不是又一个“Hello World”式的Swing练习——它是一套能真正在本地桌面跑起来的文件管理工具你可能在大学Java课上写过带按钮和文本框的Swing小demo,也可能在某次课程设计里拖拽过JFrame、JTable和JTree,但最后保存成jar双击运行时,要么…

📰

STM32 Modbus RTU从站移植实战:RS-485通信与寄存器映射

简介:面向嵌入式开发者的STM32F10x标准外设库Modbus通信工程包,适合需要移植Modbus主从协议、完成STM32与上位机或传感器数据联调的工程师与学生。核心程序经过作者多次实测,确认稳定可用,可直接在Keil工程中打开、编译和烧录&…

📰

ROS控制DJI Ronin云台的原理与避坑指南

简介:本资源是一套基于ROS的DJI Ronin三轴云台控制方案,面向机器人开发、嵌入式控制与ROS应用进阶学习者,解决DJI官方未开放API导致的云台无法直接集成到ROS系统的核心痛点。方案采用创新的‘ADB图像识别Arduino’链路:通过Androi…

📰

Steam本地游戏一键入库:合规注册appmanifest与steam_appid.txt

简介:Steam一键入库工具是一款面向独立游戏开发者与小型开发团队的效率工具,专为简化Steam平台游戏上架流程而设计,解决手动配置产品页、上传构建、设置区域与定价等重复性高、易出错的后台操作问题。资源包共3个文件(12.7MB&…

📰

Shadow Dexterous Hand Plus高维运动控制原理与实践

简介:本资源是面向机器人学、人工智能及先进控制研究者的《Shadow Dexterous Hand Plus五指灵巧手使用教程 V1.1.1》官方培训文档,聚焦ROS环境下高精度灵巧操作系统的部署与开发。教程系统覆盖产品结构(24关节/20自由度)、硬件组成…

📰

电器元件-浮球开关

简介浮球开关就是跟着水位上下漂浮的水位自动开关,专门用来检测水箱、水池里水位高低,自动控制水泵抽水或者停水。它的外壳是一个塑料浮球,连着电缆线,球里面有钢珠和微动开关。水位高,浮球漂起来,球朝上&a…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬