尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Linux磁盘扩容实战:用growpart扩展分区与文件系统

Linux磁盘扩容实战:用growpart扩展分区与文件系统 你如果管理过云服务器或者自己用虚拟化平台搭过机器大概率碰到过这种诡异情况明明是给虚机/磁盘扩容了重启也重启了但df -h一看根分区还是原来的老容量。别怀疑你操作错了这才是正常现象——宿主机层面的磁盘变大只是让底层块设备有了更多空间分区表里头的分区边界还死死守着原来的位置。这时候就该growpart出场了。growpart是一个专门干扩分区这件事的小工具它做的事情说白了就是把某个分区表的末尾边界往后挪让分区吃满整个磁盘剩余空间。它解决的是磁盘有空间但分区用不到这个最别扭的中间层问题。这篇文章我会从为什么需要它讲到完整实操流程再把这几年的踩坑记录一并倒给你。适合刚接触 Linux 分区管理的新手也适合想把手头命令用得更明白的运维同学。1. 先搞清楚 growpart 解决的是什么问题1.1 为什么分区会不够用很多人第一次遇到磁盘扩容下意识觉得磁盘变大了文件系统应该自动跟着变大。但这其实是三个独立层次的问题物理磁盘/虚拟磁盘是底层载体分区是磁盘上的逻辑划分用分区表记录起始和结束位置文件系统是构建在分区之上的存储结构。三层各管各的谁也不自动替谁干活。虚拟机场景最常见你在 ESXi、Proxmox、KVM 这类虚拟化平台上把虚拟磁盘从 20G 扩到 50G进系统后/dev/sda这个块设备确实变成 50G 了但/dev/sda1这个分区的结束扇区还停留在 20G 的位置分区本身还是 20G。文件系统建在分区上所以文件系统也只能看到 20G。相当于你给一栋楼加盖了楼层但电梯按钮还只到原来的楼层楼上根本进不去。growpart干的就是把电梯按钮往上加这件事重写分区表中某个分区的结束位置让它延伸到磁盘末尾的可用空间。它不动分区里的数据只在分区表的元数据层面做修改。1.2 growpart 和 fdisk、parted 的区别你可能会问fdisk 和 parted 不也能改分区吗确实能但用法和风险等级完全不同。fdisk/parted是交互式或脚本化的分区编辑工具可以创建、删除、调整分区功能很全但操作错了容易把分区表搞坏。而且它们调整分区大小时通常需要你手动指定起始扇区、结束扇区事情一多就容易算错。growpart是单任务专用工具只做扩容这一件事语法极简一个命令就完成。它自动计算目标分区的结束扇区直接扩展到磁盘末尾不需要你去算柱面、扇区。底层实现上growpart 本质是对 parted 的封装但它把扩展特定分区到可用空间这个高频操作收敛成了固定参数大大降低了出错概率。在磁盘已经变大、只想把某个分区扩满这个场景下growpart /dev/sda 1就是最直接的做法完全不用碰复杂的分区编辑流程。2. 动手之前把磁盘现状摸清楚2.1 先确认几个关键信息不要拿到命令就敲先花三分钟把现状看清楚。我每次扩容前的标准动作就是用三条命令把家底摸一遍# 查看块设备树和大小 lsblk # 查看分区表详情 sudo parted -l # 查看现有文件系统类型和挂载情况 df -hTlsblk能一眼看出磁盘总大小和分区大小是否已经出现磁盘大、分区小的差距。parted -l会告诉你分区表类型是 MBRmsdos还是 GPT以及每个分区的起止扇区。df -hT则是看文件系统类型和挂载点这决定了下一步用什么命令来扩展文件系统。举个例子lsblk输出如下的时候说明磁盘已经扩容、但分区没跟上NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 50G 0 disk └─sda1 8:1 0 20G 0 part /磁盘是 50G分区才 20G这就是标准的待处理状态。2.2 MBR 和 GPT 对扩容的影响分区表类型直接决定了你能扩到哪里、有没有限制。MBRmsdos最老牌的分区表格式单分区最大支持 2T实际上受扇区逻辑块地址影响2T 是一个常见硬上限。MBR 里最多 4 个主分区扩展分区和逻辑分区的路子也比较绕。如果磁盘整块大于 2TMBR 分区表根本没法直接用满必须转 GPT。GPT现代默认选择分区数量几乎没有限制单分区容量上限大到不用考虑。当前所有主流云平台和虚拟化方案默认建出来的都是 GPT。growpart对两种分区表都支持但 GPT 下有时候还需要配合sgdisk来刷新分区表信息后面会讲。另外有个细节如果磁盘总容量超过 2T 而分区表还是 MBR你扩容后会遇到磁盘显示很大但分区最多只能扩到 2T的尴尬这种得先做 MBR 转 GPT 的迁移但那属于另一个大话题本文不展开。2.3 什么情况下不能直接 growpartgrowpart不是万能药下面几种情况你要先绕个弯LVM 场景如果根分区是 LVM比如/dev/mapper/ubuntu--vg-ubuntu--lv那光扩分区还不够。LVM 的链路是物理磁盘 → 物理卷PV→ 卷组VG→ 逻辑卷LV→ 文件系统。四个层级逐级放大每一级都要做对应操作。此时growpart只是第一步后面还得pvresize、lvextend、resize2fs跟上。分区是正在使用的根分区growpart修改分区表时如果对应分区处于挂载状态而且内核还在用旧的分区表信息它可能会提示需要重新读取分区表。根分区通常都能在线扩因为 growpart 只改分区表末尾大多数内核版本支持在线重新读取但确实有遇到Device or resource busy的情况。分区表已经满了MBR 格式下四个主分区都用满了或者 GPT 下没有可用分区表空间这种属于极端情况一般不会在典型的单根分区场景出现。磁盘上有其他分区阻挡growpart只能把目标分区扩展到相邻空闲空间的末尾。如果目标分区后面还有别的分区它不会越过那个分区去扩展。换句话说目标分区必须是磁盘上最后一个分区才能吃到全部剩余空间。注意扩容前务必备份。虽然 growpart 操作很安全但任何分区表修改都有风险特别是数据无价的服务器。3. 完整实操从磁盘扩容到文件系统识别我拿一个典型场景走完整流程假设你有一台 Linux 虚机系统盘sda单分区sda1根分区/ext4 文件系统。你要把磁盘从 20G 扩到 50G目标是让根分区和文件系统都用满 50G。3.1 第一步宿主机/云平台层把磁盘变大这一步在虚拟化平台或者云控制台操作不同平台入口不同但本质上就是把虚拟磁盘的容量上限调大。Proxmox VE选中虚拟机 → 硬件 → 磁盘 → 调整大小Resize输入新的容量。VMware vSphere编辑设置 → 硬盘 → 扩展填新大小。KVM/libvirt可以用virsh blockresize命令或者改 XML 里的 capacity 后热插拔。云平台控制台里扩容云盘之类的入口有些还需要先在控制台完成额外步骤再回系统里操作。这一步做完后在系统里执行lsblk你会看到磁盘大小已经变了但分区没变。注意有些虚拟化平台需要关机后再扩容才安全最好看平台说明操作。在线扩的时候SCSI 设备可能需要先触发重新扫描。3.2 第二步让系统重新识别磁盘容量大多数虚拟化平台热扩容后操作系统里lsblk就能直接看到新大小。但偶尔会遇到内核还抱着旧容量不放的现象这时需要强制重新扫描 SCSI 设备# 重新扫描所有 SCSI 设备 echo 1 /sys/class/scsi_disk/0:0:0:0/device/rescan # 或者更粗暴一点用 partprobe 刷新分区表 sudo partprobe /dev/sda这里0:0:0:0是lsscsi或/sys/class/scsi_device里看到的设备地址不同机器可能不同。云环境里如果系统是 virtio 磁盘一般不用扫描直接能看到新容量。3.3 第三步安装 growpart 并用它扩展分区先确认系统里有没有 growpart没有就装# Debian/Ubuntu sudo apt update sudo apt install -y cloud-guest-utils # 注意Debian/Ubuntu 的 growpart 在 cloud-guest-utils 包里 # CentOS/RHEL/Fedora sudo yum install -y cloud-utils-growpart装好之后先做一次预演看 growpart 会做什么sudo growpart --dry-run /dev/sda 1输出大致是CHANGE: partition1 start2048 old: size41940992 end41943040 new: size104855519 end104857567这是在告诉你分区的结束扇区将从 41943040 调整到 104857567也就是扩到磁盘末尾。看到这个信息没问题后去掉--dry-run真执行sudo growpart /dev/sda 1正常会输出类似CHANGE: partition1 start2048 old: size... new: size...如果它输出了NOCHANGE: partition 1 partition size is what it was说明分区已经是最大了不用再扩。这里要特别强调命令格式growpart 磁盘设备 分区号分区号不是sda1这种完整设备名而是数字。第二个参数是硬盘设备路径不需要带分区号。写错成growpart /dev/sda1 1会直接报错。3.4 第四步扩展文件系统分区扩完之后文件系统还是旧大小这一步是让操作系统真正吃到容量的关键。ext4 / ext2 / ext3 文件系统sudo resize2fs /dev/sda1resize2fs不需要手动指定大小它会自动把文件系统扩展到整个分区。如果在线扩容过程中碰到文件系统已被挂载的提示通常也没事ext4 支持在线 resize。XFS 文件系统# xfs 必须在挂载状态下扩容且指定挂载点 sudo xfs_growfs /注意顺序完全不同ext 系是操作设备文件xfs 是操作挂载点而且 xfs 扩容时必须挂载着弄。很多从 ext4 习惯转过来的人在这里踩坑对着/dev/sda1敲xfs_growfs结果报错说设备不存在或者不是挂载点。查看文件系统类型再动手df -hT /这个命令的输出里第二列就是类型比如ext4或xfs。不同的类型对应不同的命令千万不要搞混。3.5 第五步验证结果df -h / lsblk sudo parted /dev/sda unit MiB printdf -h应该显示根分区已经变成 50G 左右lsblk里的分区大小也跟着变。再顺便看一眼df -i检查 inode 使用率避免以后出现 inode 满的隐性问题。如果用的是 LVM流程会变成这样# 1. 扩物理卷 sudo pvresize /dev/sda1 # 2. 扩展逻辑卷把 VG 里剩余空间全给 LV sudo lvextend -l 100%FREE /dev/mapper/vg-lv # 3. 扩文件系统 sudo resize2fs /dev/mapper/vg-lv # ext4 # 或 sudo xfs_growfs /挂载点 # xfsLVM 的链路里有四层每一层都有对应命令少了哪一步都会发现容量没到最终文件系统。这也是新手最容易漏的一环——明明growpart也跑了lsblk显示分区也大了但df -h就是没变十有八九是卡在 PV/VG/LV 层没扩。4. 踩坑实录我遇到过的几个典型问题4.1 lsblk 看不到新容量系统里看不到磁盘扩容后的新大小最可能的原因是虚拟化平台的热插拔没生效。这时候优先尝试重新扫描 SCSI 设备前面 3.2 节那两条命令。如果扫描后还是没有检查一下是不是 virtio-blk 设备这类设备通常不需要扫描直接 reboot 一次最省事。另外有一种情况磁盘在宿主机层面扩容了但虚机的 SCSI 控制器识别上限还是旧值。这个纯属虚拟化平台的配置问题往往需要关机再开机注意不是重启是真正关机再启动才能触发控制器重新上报容量。4.2 提示 device or resource busygrowpart /dev/sda 1如果报failed to read partition table或者Device or resource busy通常是因为内核还在使用旧的分区表。比较有效的处理顺序# 先尝试刷新分区表 sudo partprobe /dev/sda # 不行就重跑一遍 sudo growpart /dev/sda 1如果partprobe也不好使看看是不是有进程正在使用该分区比如系统盘根分区建议直接重启一次再执行。绝大多数busy问题重启后都会消失。4.3 resize2fs 报错 Couldnt find valid filesystem superblock这种情况多数是文件系统类型判断错了。比如实际是 xfs却对设备执行了resize2fs自然会报找不到 ext 超级块。先df -hT看清楚类型再选对应命令。还有一个容易忽略的细节如果文件系统是 xfs而且你在线扩容后忘了xfs_growfs那么df -h完全没变化但不会报错。xfs 的分区变大但文件系统没跟是最安静的故障没有任何报错很多人以为操作失败了其实只是忘了最后一步。4.4 LVM 场景下只扩了分区我在帮朋友排查的时候遇到过好几次执行完growpart后lsblk显示sda1分区确实变大了但df -h还是老样子。原因很简单——系统盘是 LVM 布局LV 没跟着扩。这种布局在 Ubuntu 默认安装里有CentOS 的默认安装也经常是 LVM。排查方法# 看是否 LVM lsblk # 如果输出里有 sda1 └─ vg-lv 这种层级就是 LVM # 看 PV 大小 sudo pvs # 看 VG 剩余空间 sudo vgs如果pvs显示 PV 还是旧大小说明pvresize没跑如果 PV 大了但 LV 小说明lvextend没跑LV 大了但文件系统小就是resize2fs/xfs_growfs没跑。按这个链路逐级检查很快就能定位卡在哪一层。4.5 分区表变成 unrecognized disk label极端情况手滑执行了growpart时指定了错误的设备或分区号导致分区表结构异常。比如磁盘原本用 GPT结果你执行的命令把保护性 MBR 区域搞坏了parted -l就可能显示不认识的分区表。此时最稳妥的方案是如果数据重要立刻停止所有写操作用gdisk的恢复功能gdisk /dev/sda后选r进入恢复模式再选b备份、c加载备份分区表来恢复。这也是为什么我在前面强调操作前备份分区表和关键数据。作为日常预防建议先把分区表导出来存一份sgdisk --backup/root/partition-table-backup /dev/sda出问题时用sgdisk --load-backup/root/partition-table-backup /dev/sda两条命令能救你于水火这个习惯建议从今天开始养成。5. 一些值得记住的实践经验5.1 永远先跑 --dry-rungrowpart --dry-run这个参数是我最喜欢的功能。它只会输出将要做的变更不会真正修改任何东西。跑一遍确认 new: size 的数值接近磁盘总容量再决定是否真跑。这个习惯成本极低收益极高——至少能让你在敲回车之前发现哦原来分区后面还有别的分区或者磁盘根本没变大。5.2 分清分区扩容和文件系统扩容是两件事这是整个流程里最容易迷糊的地方。growpart只是第一步它负责的是分区变大。之后必须根据文件系统类型执行resize2fsext4或xfs_growfsxfs才等于真正完成。一个衡量标准是lsblk显示分区变大了但df -h还没变你就知道你只做了一半。我把这个完整流程做成了速查表方便你贴在笔记里层级查看命令扩容命令说明磁盘lsblk / parted -l虚拟化平台或云控制台操作先让磁盘变大分区lsblk / parted -lgrowpart /dev/sda NN 是分区号不含 sdaPVLVMpvspvresize /dev/sdaN仅在 LVM 场景需要LVLVMlvs / vgslvextend -l 100%FREE 路径仅在 LVM 场景需要文件系统 extdf -hTresize2fs /dev/sdaN在线执行即可文件系统 xfsdf -hTxfs_growfs 挂载点必须挂载状态下执行5.3 操作顺序别乱每一步后都验证虽然每一步独立来看都不难但串起来的时候顺序错了会很难排查。我的习惯是每完成一步就做一次lsblk加df -h快照确认当前层级到位了再走下一步。这样出问题的时候你很清楚是卡在哪个环节不用从头到尾对比日志。扩分区这种操作虽然看起来风险不大但先备份、再预演、逐步执行、持续验证这套保守打法能让你稳稳地把事情做完。尤其是生产服务器宁可多花几分钟确认也不要图快给自己埋雷。5.4 关于分区号的一个小坑growpart /dev/sda 1里的1是分区号不是设备路径。如果你执行growpart /dev/sda1会收到类似unexpected number of arguments的报错。另外如果磁盘有多个分区确认你要扩的是第几个分区别扩错。lsblk输出里sda2的最后一个数字就是分区号对应关系一目了然。最后一个实际经验如果你是在云主机上扩容系统盘很多云厂商有自己的控制台一键扩容入口会自动帮你做完growpart和文件系统扩容。但如果你用的是自建虚拟化平台或者只是临时挂载的数据盘老老实实手动走一遍上面的流程是最靠谱的。工具虽然小用对了地方能省下不少折腾时间。
返回列表