某个深夜给服务器加完新分区,fdisk /dev/sda退出前屏幕弹出一行提示:内核还在使用旧分区表,新表将在重启后生效,或者你可以运行partprobe(8)或partx(8)。如果这是台测试机,直接重启就完事了,但摆在面前的是跑着业务的机器,重启代价实在不小。这时候就需要把分区表热重载这件事搞明白——让内核在不重启的前提下重新读取磁盘上的分区信息。我见过太多人卡在这个环节:要么直接reboot,图省事但代价大;要么敲了partprobe没反应就慌;要么报错之后不知道是哪个进程占用了分区,只能硬着头皮重启。这篇文章把 Linux 下分区表重载的常见工具、原理、实操链路和排查思路完整过一遍,适合 Linux 运维、系统管理员,以及自己折腾 NAS 和服务器但对/dev下设备节点机制不太熟悉的朋友。1. 为什么改了分区表,内核还要单独“刷一遍”1.1 内核为何看不到新分区磁盘上的分区表就是一块磁盘的“目录”,记录着每个分区从哪个扇区开始、到哪里结束,以及分区类型、GPT 备份表位置等信息。内核在系统启动时读取这块目录,然后在内存中构建一份块设备视图,创建出/dev/sda1、/dev/sda2这类设备节点,之后所有读写操作都走这套视图。问题来了:你用fdisk、parted或sgdisk修改分区表,本质上只是把新表写到了磁盘扇区上,内核并不知情。它内存里还保留着旧视图,所以你看不到新分区、也看不到扩容后的新容量。热重载就是主动通知内核“磁盘上的分区表变了,去重新解析一下”,让内存视图和磁盘实际内容保持一致。这个设计不是偷懒,而是一种安全机制。内核如果每次读取磁盘时都重新解析分区表,那些已经挂载并正在读写的分区随时可能因为表的变化而失效,数据损坏风险极高。所以内核选择只在启动、或收到明确通知时更新视图。partprobe、partx这些工具做的事情,都是在触发这个“明确通知”。1.2 热重载方案的底层逻辑与选型先给一个直观的对比,把最常见的几种方式放在一起看:工具所属软件包底层机制典型适用场景使用限制partprobeutil-linux(由 parted 套件调用)通知内核重新读取所有/指定块设备的分区表分区表整体改动后快速刷新分区被挂载或占用时可能失败partxutil-linux按分区号精确添加、删除或更新内核所见分区只新增/删除某几个分区,不触碰已有分区需要指定分区号,操作粒度较细blockdev --rereadptutil-linux直接向内核发起 BLKRRPART ioctl希望内核按原语级方式重读整张分区表被占用时直接报 Device or resource busyhdparm -zhdparm同样是 BLKRRPART ioctl老式 SCSI/SATA 环境兼容性较好NVMe 场景支持一般重启无内核完整重扫所有块设备热重载失败、设备被占用且无法释放,或数据安全要求极高停机窗口代价大选型逻辑其实很简单:先用最省事的方式,不行再精确处理。绝大多数分区表变更场景,partprobe /dev/sda一步就能解决。如果它报了 busy 之类的错误,则根据报错内容选择partx精细操作,或排查占用进程后再重试。理解这个顺序,比背命令本身更重要。2. 四个常用工具,分清楚再动手2.1 最快最省事:partprobepartprobe是大多数人第一次接触热重载时用到的命令,它的核心行为是告诉内核“某块磁盘上的分区表可能已经被外部修改了,请重新读一下”。不带参数执行时,它会遍历系统里所有的块设备,逐个发出重新检测信号;带设备参数时只处理指定设备,例如:partprobe /dev/sdb检查结果可以用-s参数输出简洁状态:partprobe -s /dev/sdb这条命令会列出该磁盘上每个分区在内核中的注册状态。如果返回 0,一般说明内核已经接受了新表;返回非 0,则需要看具体报错。这也是它在“快速和简单”两个维度上最突出的原因,因为不需要记忆太多参数,一条命令就能覆盖大部分重载需求。不过“简单”不等于“万能”。partprobe在对所有块设备广播时,只要其中某个分区还处于挂载状态,就可能拒绝更新对应设备。比如你修改了/dev/sda的分区表,而/dev/sda1正挂载在/boot,内核为了保证现有文件系统一致性,通常不会让整块磁盘重新解析,命令结果就会报错。此时不要硬来,要么先卸载相关分区,要么改用partx做针对性操作。2.2 精细化控制:partxpartx和partprobe同属 util-linux 家族,但思路完全不同。它不要求内核把整张盘“推倒重读”,而是基于磁盘当前的分区表内容,按分区号逐个通知内核添加、删除或更新某个分区。这种精细粒度让它在“部分分区被占用”的场景下非常有用。新增分区时用-a:partx -a /dev/sdb这条命令会扫描/dev/sdb当前分区表中所有分区,并把内核里尚未存在的分区加进去。如果内核已有的分区号和新表一致,它不会去动那些旧条目,因此不会因为某个分区被挂载而全面失败。删除分区时用-d配合--nr:partx -d --nr 2 /dev/sdb更新某个已存在分区的尺寸或位置信息时用-u:partx -u /dev/sdb --nr 1最后一个场景常见于你在原分区基础上调整了结束位置实现扩容,这时内核里的分区大小仍是旧值,-u能直接把新尺寸同步给内核,而不需要把分区删除重建。相比partprobe的全盘广播,partx的“指哪打哪”能力更像外科手术——当你只想让内核认识新加的第五个分区,而第一到第四个分区都在被系统使用、不能有任何闪失的时候,这个优势就很明显了。2.3 备用方案:blockdev --rereadpt 与 hdparm -zblockdev --rereadpt是把请求直接发给内核块设备层的低级方式。它内部走 BLKRRPART ioctl,让内核“完全按照磁盘上的内容重新解析一次分区表”。用法:blockdev --rereadpt /dev/sda这个命令的优点是直接、语义清晰,缺点也很明显:只要该磁盘上任意一个分区正在被使用,内核就会返回 “BLKRRPART: Device or resource busy”。它不像partprobe那样会“尽量广播”,而是彻底拒绝。因此在已经确认没有分区被占用的环境下,它是个可靠的备选;一旦遇到 busy,就不要反复尝试,应当转向排查占用来源。hdparm -z走的是同一个 ioctl,只是由 hdparm 这个工具发起。在一些老内核和旧 SCSI/SATA 环境下,它可能比blockdev --rereadpt更稳,但对 NVMe 设备支持普遍一般。就我个人经验,现在新装的系统通常都自带 util-linux,所以日常还是以partprobe和partx为主,blockdev --rereadpt作为确认“到底是不是内核层面拒绝”的验证手段更好用。注意:不要被网上讨论中“加个参数强制重读”的说法误导。内核在分区被占用时拒绝更新,是设计上的安全策略,不存在可靠的手段绕过它而不引入数据风险。命令换了一个又一个,问题根源往往还是占用没释放。3. 一个完整的实操链路:从扩盘到容量真正可用3.1 让系统先感知新容量很多人在“扩容”场景下碰到的第一个坑,不是分区表重载本身,而是系统根本还没感知到磁盘物理容量的变化。以虚拟机为例,如果在虚拟化平台里把 100G 系统盘扩大到了 200G,进系统后lsblk可能仍显示 sda 为 100G——不是平台没生效,是块设备层还没来得及扫描新容量。这种情况先重扫整个 SCSI 总线或指定设备。对单块磁盘,尝试:echo 1 > /sys/block/sda/device/rescan对整个 host 总线执行扫描:echo "- - -" > /sys/class/scsi_host/host0/scan/sys/class/scsi_host/下可能有多个 host 目录,逐个写入这三条短线是常见的全量重扫方式。完成后再执行lsblk,确认 sda 总容量已经变成 200G。这一步做对了,后面分区表重载才有意义;否则你连新空间都看不到,重载自然“无效”。物理机和部分虚拟化平台还要确认磁盘类型是 SCSI 还是 virtio-blk,不同总线对应的 sysfs 路径略有差异。判断方法并不复杂:lsblk -d -o name,tran看传输类型,就可以决定该去/sys/block/sda/device/rescan还是走hostN/scan。3.2 修改分区表并热重载假设磁盘整块容量已正确显示为 200G,但根分区/dev/sda3还停留在原来的 100G。接下来用parted查看并调整分区:parted /dev/sda (parted) unit s (parted) print free (parted) resizepart 3 100% (parted) quitresizepart需要指明分区号和新的结束位置,100%表示把分区扩展到磁盘末尾。修改完并退出后,立即执行热重载:partprobe /dev/sda命令安静地返回后,不要急着看lsblk,先去/proc/partitions里确认内核真实状态:cat /proc/partitions这个文件列出的是内核当前注册的块设备和各分区占用的扇区数,是判断热重载生效与否的金标准。对比 sda3 的 size 字段是否变大,比看lsblk输出可靠得多,因为lsblk在某些场景下可能读取到 libblkid 缓存,不完全是内核视图。如果partprobe报错,或者返回成功后/proc/partitions里没有新大小,就换成partx更新指定分区:partx -u /dev/sda --nr 3这一条只更新 3 号分区的尺寸,不动其他分区,风险面小很多。3.3 重载之后不要漏掉文件系统这层分区表热重载只是第一层,文件系统通常不会自动跟着扩容。这时要根据文件系统类型选择工具:# ext4 文件系统 resize2fs /dev/sda3 # XFS 文件系统,注意 xfs 只能在线扩,且命令后面跟挂载点 xfs_growfs / # 如果根分区是 LVM 物理卷,则先让 PV 吃进新空间 pvresize /dev/sda3 lvextend -l +100%FREE /dev/vg_root/lv_root resize2fs /dev/vg_root/lv_root很多人扩完盘,发现df -h里根分区还是老容量,就回头怀疑分区表重载没成功。其实/proc/partitions里内核已经看到新分区大小,只要把文件系统和 LVM 层也扩一下,容量才会真正落到可用空间。分区表重载解决的是“内核看不看得到”,文件系统调整解决的是“应用用不用得上”,两者缺一不可。整个流程做完,用lsblk和df -h各看一眼。lsblk确认分区大小,df -h确认文件系统容量,全部对上才算走完一整套。4. 热重载失败排查:Busy、假成功与设备节点不出现4.1 经典报错:Device or resource busy这是分区表重载场景里最常遇到的报错,主要原因是内核认为“有进程或子系统正在使用该磁盘上的某个分区”。常见占用来源包括:占用类型典型表现排查/释放手段文件系统已挂载findmnt /dev/sda1能查到挂载点确认可离线后执行umountswap 分区在占用swapon --show显示该分区执行swapoff /dev/sda2临时释放LVM 卷组引用pvs或lvs显示相关 PV/LVlvchange -an停用逻辑卷后重试普通进程占用lsof /dev/sda1有输出停止对应服务后重试排查顺序从轻到重:先用findmnt看有没有挂载,再用lsof看有没有进程直接打开设备文件,然后检查 swap 和 LVM。一个容易忽略的细节是,某些监控进程、杀毒软件或备份任务会长期持有设备文件句柄,lsof一下就能发现问题。如果确认是 LVM 占用,但又不想动整个卷组的可用性,可以先执行pvscan或pvdisplay观察新旧路径关系。多数情况下,根分区所在磁盘的被占用是无法完全避免的,因为系统本身就在运行,这时应考虑只更新单个分区而非整个设备,或者安排维护窗口重启。实操心得:partx之所以在 busy 场景比partprobe更从容,是因为它按分区号操作,另一个分区被挂载不影响新分区添加。养成“能只加一个分区就绝不全盘重读”的习惯,能显著降低生产环境里的操作风险。4.2 partprobe“假成功”却没新节点还有一种更隐蔽的情况:partprobe返回 0,你连/proc/partitions都没看,直接去找/dev/sda4,发现设备节点不存在,于是以为命令没用。实际上内核可能已经注册了,只是 udev 还没来得及创建节点,或者节点路径确实没刷新。处理方式很简单:udevadm settle这条命令会阻塞当前 shell,直到 udev 事件队列处理完毕。之后再查/dev/sda4,节点通常会补上。如果仍然没有,再用partx -a /dev/sda直接让内核把“缺少的分区”加进来。这个追加动作会触发内核创建对应分区的part设备,udev 随之生成/dev节点。“假成功”还可能是partprobe执行时磁盘正在被某设备映射器引用,它选择“静默接受请求但实际不更新”——代码上了没错,但事情没办成。判断标准始终以/proc/partitions为准,而不是以命令行返回值或一句“看到新分区节点”为准。总结成习惯就是:重载之后第一件事cat /proc/partitions,没有就partx -a,再没有才考虑重启。4.3 扩容后系统容量不变,别忘了重扫 SCSI有些情况下反复热重载都没问题,分区表也显示正常,但系统总容量还是老样子。这通常意味着不是在分区表层面出问题,而是底层块设备容量都没更新。物理机里的硬盘即使支持热插拔,操作系统也未必自动刷新尺寸;虚拟机的 virtio 磁盘同理。执行系统盘所在 host 的重新扫描:for host in /sys/class/scsi_host/host*; do echo "- - -" > "$host/scan" done扫描完再cat /sys/block/sda/size确认总扇区数。如果这里已经是新容量,接下来走第三章的完整链路就行;如果这里还是旧值,说明虚拟化平台或外置存储层面需要先完成“热添加”操作,而这个动作因平台而异,需要到对应管理界面确认。NVMe 磁盘则一般不通过 SCSI 重扫,而是检查/sys/class/nvme/下的控制器状态。如果nvme list显示容量没变,而平台侧确认已扩展,这种情况下热重载的优先级反而要降低——多数生产环境可以直接在维护窗口重启,省去一系列不确定的扫描流程。5. 哪些情况不建议硬热重载5.1 数据安全高于“快速”热重载看起来只是几条命令,但它的本质是打破内核原有的一致性假设,强制重建块设备视图。对纯粹的空闲磁盘这么做非常安全,但对有数据在读写、有集群依赖设备路径的系统,强行重读可能引发比“看不到分区”更严重的连锁问题。多路径存储环境下,分区表重载应在多路径层重新识别设备后进行,而不是直接对底层物理设备动手;文件系统若处于高压力写入状态,内核拒绝更新反而是保护机制,不要为了省一次重启去尝试各种强制手段。如果满足以下任一条件,强烈建议主动规划重启:该磁盘的部分分区挂载着重要数据,且无法停止相关服务。内核版本较老,对热重载支持不完善。之前已经尝试过多种热重载方式,依然报 busy,且无法定位占用来源。这是生产数据库或集群共享存储,任何块设备视图变化都可能引发 IO 错误。重启不是“没办法的办法”,而是“安全优先的选择”。把重启视为一种一致性最高的重载方式,它虽然不快,但足够确定。运维工作的目标从来不是“不重启”,而是在明确风险的前提下做正确决策。5.2 GPT 主表与备份表不一致MBR 分区表只有磁盘开头一份,修改后重载即可;GPT 则不同,它在磁盘头有主表,在磁盘末尾还有一份备份表。热重载过程中,如果主表和备份表不一致,内核可能只认其中一个,而一些分区管理工具则会报 CRC 错误或备份表无效。如果改动过 GPT 分区表且不确定备份表状态,可以用sgdisk查看:sgdisk -v /dev/sda这条命令专门检查 GPT 主表与备份表的一致性。发现问题后,用-e参数把备份表移动到磁盘末尾并修复:sgdisk -e /dev/sda执行成功后再做分区表重载,状态才会稳定。partprobe本身不会替你做备份表修复,所以不要以为重载成功就万事大吉。对长期运行的服务器,建议每完成一次 GPT 改动,都顺手跑一遍sgdisk -v,这是成本极低却能避免后患的习惯。如果你用的是parted的 GUI 版本或某些发行版自带的磁盘工具,它们在写表时可能会尝试修复备份表,但命令行环境下手动确认更稳妥。分区位置接近磁盘末尾时,备份表修复尤其重要,因为算法稍有偏差就可能覆盖掉其他数据区,这类问题往往要等重启后才暴露,到时再排查就麻烦了。以我个人经验,热重载不是一门“背命令”的手艺,而是要理解内核为什么拒绝你。第一次给虚拟机扩盘失败,连续换了partprobe、blockdev --rereadpt都没用,最后发现是一个监控进程握着旧分区节点不放,杀掉进程后重试立刻成功。另一次partprobe静默返回成功,但/proc/partitions里就是不见 sda5,换成partx -a才把新分区补进去。这两件事之后,我养成了两个习惯:每个新分区创建完都先看/proc/partitions;任何重载失败,第一时间用lsof定位占用者,而不是盲目重启或换命令硬试。
某个深夜给服务器加完新分区,fdisk /dev/sda退出前屏幕弹出一行提示:内核还在使用旧分区表,新表将在重启后生效,或者你可以运行partprobe(8)或partx(8)。如果这是台测试机,直接重启就完事了,但摆在面前的是跑着业务的机器,重启代价实在不小。这时候就需要把分区表热重载这件事搞明白——让内核在不重启的前提下重新读取磁盘上的分区信息。我见过太多人卡在这个环节:要么直接reboot,图省事但代价大;要么敲了partprobe没反应就慌;要么报错之后不知道是哪个进程占用了分区,只能硬着头皮重启。这篇文章把 Linux 下分区表重载的常见工具、原理、实操链路和排查思路完整过一遍,适合 Linux 运维、系统管理员,以及自己折腾 NAS 和服务器但对/dev下设备节点机制不太熟悉的朋友。1. 为什么改了分区表,内核还要单独“刷一遍”1.1 内核为何看不到新分区磁盘上的分区表就是一块磁盘的“目录”,记录着每个分区从哪个扇区开始、到哪里结束,以及分区类型、GPT 备份表位置等信息。内核在系统启动时读取这块目录,然后在内存中构建一份块设备视图,创建出/dev/sda1、/dev/sda2这类设备节点,之后所有读写操作都走这套视图。问题来了:你用fdisk、parted或sgdisk修改分区表,本质上只是把新表写到了磁盘扇区上,内核并不知情。它内存里还保留着旧视图,所以你看不到新分区、也看不到扩容后的新容量。热重载就是主动通知内核“磁盘上的分区表变了,去重新解析一下”,让内存视图和磁盘实际内容保持一致。这个设计不是偷懒,而是一种安全机制。内核如果每次读取磁盘时都重新解析分区表,那些已经挂载并正在读写的分区随时可能因为表的变化而失效,数据损坏风险极高。所以内核选择只在启动、或收到明确通知时更新视图。partprobe、partx这些工具做的事情,都是在触发这个“明确通知”。1.2 热重载方案的底层逻辑与选型先给一个直观的对比,把最常见的几种方式放在一起看:工具所属软件包底层机制典型适用场景使用限制partprobeutil-linux(由 parted 套件调用)通知内核重新读取所有/指定块设备的分区表分区表整体改动后快速刷新分区被挂载或占用时可能失败partxutil-linux按分区号精确添加、删除或更新内核所见分区只新增/删除某几个分区,不触碰已有分区需要指定分区号,操作粒度较细blockdev --rereadptutil-linux直接向内核发起 BLKRRPART ioctl希望内核按原语级方式重读整张分区表被占用时直接报 Device or resource busyhdparm -zhdparm同样是 BLKRRPART ioctl老式 SCSI/SATA 环境兼容性较好NVMe 场景支持一般重启无内核完整重扫所有块设备热重载失败、设备被占用且无法释放,或数据安全要求极高停机窗口代价大选型逻辑其实很简单:先用最省事的方式,不行再精确处理。绝大多数分区表变更场景,partprobe /dev/sda一步就能解决。如果它报了 busy 之类的错误,则根据报错内容选择partx精细操作,或排查占用进程后再重试。理解这个顺序,比背命令本身更重要。2. 四个常用工具,分清楚再动手2.1 最快最省事:partprobepartprobe是大多数人第一次接触热重载时用到的命令,它的核心行为是告诉内核“某块磁盘上的分区表可能已经被外部修改了,请重新读一下”。不带参数执行时,它会遍历系统里所有的块设备,逐个发出重新检测信号;带设备参数时只处理指定设备,例如:partprobe /dev/sdb检查结果可以用-s参数输出简洁状态:partprobe -s /dev/sdb这条命令会列出该磁盘上每个分区在内核中的注册状态。如果返回 0,一般说明内核已经接受了新表;返回非 0,则需要看具体报错。这也是它在“快速和简单”两个维度上最突出的原因,因为不需要记忆太多参数,一条命令就能覆盖大部分重载需求。不过“简单”不等于“万能”。partprobe在对所有块设备广播时,只要其中某个分区还处于挂载状态,就可能拒绝更新对应设备。比如你修改了/dev/sda的分区表,而/dev/sda1正挂载在/boot,内核为了保证现有文件系统一致性,通常不会让整块磁盘重新解析,命令结果就会报错。此时不要硬来,要么先卸载相关分区,要么改用partx做针对性操作。2.2 精细化控制:partxpartx和partprobe同属 util-linux 家族,但思路完全不同。它不要求内核把整张盘“推倒重读”,而是基于磁盘当前的分区表内容,按分区号逐个通知内核添加、删除或更新某个分区。这种精细粒度让它在“部分分区被占用”的场景下非常有用。新增分区时用-a:partx -a /dev/sdb这条命令会扫描/dev/sdb当前分区表中所有分区,并把内核里尚未存在的分区加进去。如果内核已有的分区号和新表一致,它不会去动那些旧条目,因此不会因为某个分区被挂载而全面失败。删除分区时用-d配合--nr:partx -d --nr 2 /dev/sdb更新某个已存在分区的尺寸或位置信息时用-u:partx -u /dev/sdb --nr 1最后一个场景常见于你在原分区基础上调整了结束位置实现扩容,这时内核里的分区大小仍是旧值,-u能直接把新尺寸同步给内核,而不需要把分区删除重建。相比partprobe的全盘广播,partx的“指哪打哪”能力更像外科手术——当你只想让内核认识新加的第五个分区,而第一到第四个分区都在被系统使用、不能有任何闪失的时候,这个优势就很明显了。2.3 备用方案:blockdev --rereadpt 与 hdparm -zblockdev --rereadpt是把请求直接发给内核块设备层的低级方式。它内部走 BLKRRPART ioctl,让内核“完全按照磁盘上的内容重新解析一次分区表”。用法:blockdev --rereadpt /dev/sda这个命令的优点是直接、语义清晰,缺点也很明显:只要该磁盘上任意一个分区正在被使用,内核就会返回 “BLKRRPART: Device or resource busy”。它不像partprobe那样会“尽量广播”,而是彻底拒绝。因此在已经确认没有分区被占用的环境下,它是个可靠的备选;一旦遇到 busy,就不要反复尝试,应当转向排查占用来源。hdparm -z走的是同一个 ioctl,只是由 hdparm 这个工具发起。在一些老内核和旧 SCSI/SATA 环境下,它可能比blockdev --rereadpt更稳,但对 NVMe 设备支持普遍一般。就我个人经验,现在新装的系统通常都自带 util-linux,所以日常还是以partprobe和partx为主,blockdev --rereadpt作为确认“到底是不是内核层面拒绝”的验证手段更好用。注意:不要被网上讨论中“加个参数强制重读”的说法误导。内核在分区被占用时拒绝更新,是设计上的安全策略,不存在可靠的手段绕过它而不引入数据风险。命令换了一个又一个,问题根源往往还是占用没释放。3. 一个完整的实操链路:从扩盘到容量真正可用3.1 让系统先感知新容量很多人在“扩容”场景下碰到的第一个坑,不是分区表重载本身,而是系统根本还没感知到磁盘物理容量的变化。以虚拟机为例,如果在虚拟化平台里把 100G 系统盘扩大到了 200G,进系统后lsblk可能仍显示 sda 为 100G——不是平台没生效,是块设备层还没来得及扫描新容量。这种情况先重扫整个 SCSI 总线或指定设备。对单块磁盘,尝试:echo 1 > /sys/block/sda/device/rescan对整个 host 总线执行扫描:echo "- - -" > /sys/class/scsi_host/host0/scan/sys/class/scsi_host/下可能有多个 host 目录,逐个写入这三条短线是常见的全量重扫方式。完成后再执行lsblk,确认 sda 总容量已经变成 200G。这一步做对了,后面分区表重载才有意义;否则你连新空间都看不到,重载自然“无效”。物理机和部分虚拟化平台还要确认磁盘类型是 SCSI 还是 virtio-blk,不同总线对应的 sysfs 路径略有差异。判断方法并不复杂:lsblk -d -o name,tran看传输类型,就可以决定该去/sys/block/sda/device/rescan还是走hostN/scan。3.2 修改分区表并热重载假设磁盘整块容量已正确显示为 200G,但根分区/dev/sda3还停留在原来的 100G。接下来用parted查看并调整分区:parted /dev/sda (parted) unit s (parted) print free (parted) resizepart 3 100% (parted) quitresizepart需要指明分区号和新的结束位置,100%表示把分区扩展到磁盘末尾。修改完并退出后,立即执行热重载:partprobe /dev/sda命令安静地返回后,不要急着看lsblk,先去/proc/partitions里确认内核真实状态:cat /proc/partitions这个文件列出的是内核当前注册的块设备和各分区占用的扇区数,是判断热重载生效与否的金标准。对比 sda3 的 size 字段是否变大,比看lsblk输出可靠得多,因为lsblk在某些场景下可能读取到 libblkid 缓存,不完全是内核视图。如果partprobe报错,或者返回成功后/proc/partitions里没有新大小,就换成partx更新指定分区:partx -u /dev/sda --nr 3这一条只更新 3 号分区的尺寸,不动其他分区,风险面小很多。3.3 重载之后不要漏掉文件系统这层分区表热重载只是第一层,文件系统通常不会自动跟着扩容。这时要根据文件系统类型选择工具:# ext4 文件系统 resize2fs /dev/sda3 # XFS 文件系统,注意 xfs 只能在线扩,且命令后面跟挂载点 xfs_growfs / # 如果根分区是 LVM 物理卷,则先让 PV 吃进新空间 pvresize /dev/sda3 lvextend -l +100%FREE /dev/vg_root/lv_root resize2fs /dev/vg_root/lv_root很多人扩完盘,发现df -h里根分区还是老容量,就回头怀疑分区表重载没成功。其实/proc/partitions里内核已经看到新分区大小,只要把文件系统和 LVM 层也扩一下,容量才会真正落到可用空间。分区表重载解决的是“内核看不看得到”,文件系统调整解决的是“应用用不用得上”,两者缺一不可。整个流程做完,用lsblk和df -h各看一眼。lsblk确认分区大小,df -h确认文件系统容量,全部对上才算走完一整套。4. 热重载失败排查:Busy、假成功与设备节点不出现4.1 经典报错:Device or resource busy这是分区表重载场景里最常遇到的报错,主要原因是内核认为“有进程或子系统正在使用该磁盘上的某个分区”。常见占用来源包括:占用类型典型表现排查/释放手段文件系统已挂载findmnt /dev/sda1能查到挂载点确认可离线后执行umountswap 分区在占用swapon --show显示该分区执行swapoff /dev/sda2临时释放LVM 卷组引用pvs或lvs显示相关 PV/LVlvchange -an停用逻辑卷后重试普通进程占用lsof /dev/sda1有输出停止对应服务后重试排查顺序从轻到重:先用findmnt看有没有挂载,再用lsof看有没有进程直接打开设备文件,然后检查 swap 和 LVM。一个容易忽略的细节是,某些监控进程、杀毒软件或备份任务会长期持有设备文件句柄,lsof一下就能发现问题。如果确认是 LVM 占用,但又不想动整个卷组的可用性,可以先执行pvscan或pvdisplay观察新旧路径关系。多数情况下,根分区所在磁盘的被占用是无法完全避免的,因为系统本身就在运行,这时应考虑只更新单个分区而非整个设备,或者安排维护窗口重启。实操心得:partx之所以在 busy 场景比partprobe更从容,是因为它按分区号操作,另一个分区被挂载不影响新分区添加。养成“能只加一个分区就绝不全盘重读”的习惯,能显著降低生产环境里的操作风险。4.2 partprobe“假成功”却没新节点还有一种更隐蔽的情况:partprobe返回 0,你连/proc/partitions都没看,直接去找/dev/sda4,发现设备节点不存在,于是以为命令没用。实际上内核可能已经注册了,只是 udev 还没来得及创建节点,或者节点路径确实没刷新。处理方式很简单:udevadm settle这条命令会阻塞当前 shell,直到 udev 事件队列处理完毕。之后再查/dev/sda4,节点通常会补上。如果仍然没有,再用partx -a /dev/sda直接让内核把“缺少的分区”加进来。这个追加动作会触发内核创建对应分区的part设备,udev 随之生成/dev节点。“假成功”还可能是partprobe执行时磁盘正在被某设备映射器引用,它选择“静默接受请求但实际不更新”——代码上了没错,但事情没办成。判断标准始终以/proc/partitions为准,而不是以命令行返回值或一句“看到新分区节点”为准。总结成习惯就是:重载之后第一件事cat /proc/partitions,没有就partx -a,再没有才考虑重启。4.3 扩容后系统容量不变,别忘了重扫 SCSI有些情况下反复热重载都没问题,分区表也显示正常,但系统总容量还是老样子。这通常意味着不是在分区表层面出问题,而是底层块设备容量都没更新。物理机里的硬盘即使支持热插拔,操作系统也未必自动刷新尺寸;虚拟机的 virtio 磁盘同理。执行系统盘所在 host 的重新扫描:for host in /sys/class/scsi_host/host*; do echo "- - -" > "$host/scan" done扫描完再cat /sys/block/sda/size确认总扇区数。如果这里已经是新容量,接下来走第三章的完整链路就行;如果这里还是旧值,说明虚拟化平台或外置存储层面需要先完成“热添加”操作,而这个动作因平台而异,需要到对应管理界面确认。NVMe 磁盘则一般不通过 SCSI 重扫,而是检查/sys/class/nvme/下的控制器状态。如果nvme list显示容量没变,而平台侧确认已扩展,这种情况下热重载的优先级反而要降低——多数生产环境可以直接在维护窗口重启,省去一系列不确定的扫描流程。5. 哪些情况不建议硬热重载5.1 数据安全高于“快速”热重载看起来只是几条命令,但它的本质是打破内核原有的一致性假设,强制重建块设备视图。对纯粹的空闲磁盘这么做非常安全,但对有数据在读写、有集群依赖设备路径的系统,强行重读可能引发比“看不到分区”更严重的连锁问题。多路径存储环境下,分区表重载应在多路径层重新识别设备后进行,而不是直接对底层物理设备动手;文件系统若处于高压力写入状态,内核拒绝更新反而是保护机制,不要为了省一次重启去尝试各种强制手段。如果满足以下任一条件,强烈建议主动规划重启:该磁盘的部分分区挂载着重要数据,且无法停止相关服务。内核版本较老,对热重载支持不完善。之前已经尝试过多种热重载方式,依然报 busy,且无法定位占用来源。这是生产数据库或集群共享存储,任何块设备视图变化都可能引发 IO 错误。重启不是“没办法的办法”,而是“安全优先的选择”。把重启视为一种一致性最高的重载方式,它虽然不快,但足够确定。运维工作的目标从来不是“不重启”,而是在明确风险的前提下做正确决策。5.2 GPT 主表与备份表不一致MBR 分区表只有磁盘开头一份,修改后重载即可;GPT 则不同,它在磁盘头有主表,在磁盘末尾还有一份备份表。热重载过程中,如果主表和备份表不一致,内核可能只认其中一个,而一些分区管理工具则会报 CRC 错误或备份表无效。如果改动过 GPT 分区表且不确定备份表状态,可以用sgdisk查看:sgdisk -v /dev/sda这条命令专门检查 GPT 主表与备份表的一致性。发现问题后,用-e参数把备份表移动到磁盘末尾并修复:sgdisk -e /dev/sda执行成功后再做分区表重载,状态才会稳定。partprobe本身不会替你做备份表修复,所以不要以为重载成功就万事大吉。对长期运行的服务器,建议每完成一次 GPT 改动,都顺手跑一遍sgdisk -v,这是成本极低却能避免后患的习惯。如果你用的是parted的 GUI 版本或某些发行版自带的磁盘工具,它们在写表时可能会尝试修复备份表,但命令行环境下手动确认更稳妥。分区位置接近磁盘末尾时,备份表修复尤其重要,因为算法稍有偏差就可能覆盖掉其他数据区,这类问题往往要等重启后才暴露,到时再排查就麻烦了。以我个人经验,热重载不是一门“背命令”的手艺,而是要理解内核为什么拒绝你。第一次给虚拟机扩盘失败,连续换了partprobe、blockdev --rereadpt都没用,最后发现是一个监控进程握着旧分区节点不放,杀掉进程后重试立刻成功。另一次partprobe静默返回成功,但/proc/partitions里就是不见 sda5,换成partx -a才把新分区补进去。这两件事之后,我养成了两个习惯:每个新分区创建完都先看/proc/partitions;任何重载失败,第一时间用lsof定位占用者,而不是盲目重启或换命令硬试。