ARTICLE DETAIL

资讯详情

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

Linux磁盘空间重新分配实战:LVM扩容、GParted调整与fdisk命令行全攻略

Linux磁盘空间重新分配实战:LVM扩容、GParted调整与fdisk命令行全攻略 “磁盘满了/home 还剩不少能不能把 / 扩一下”这是我这两年被问到最多的问题之一。无论你是自己折腾一台 Linux 台式机还是在维护线上的服务器只要当初分区规划时没想清楚迟早会遇到“某个分区不够用、另一个分区闲着”的尴尬局面。这篇文章就聚焦一个经典场景Linux 系统已创建分区的空间重新分配。我不打算只给你一套照抄的命令而是把背后的原理、常见的三种调整路径、每种方案的适用场景和坑都讲清楚。读完你应该能判断自己该用 LVM 在线扩容、GParted 图形化调整还是走 fdisk 命令行硬核路线。文章面向的读者包括刚接触 Linux 命令行的新手、准备重装系统前想抢救磁盘空间的普通用户以及负责云主机和物理服务器扩容的运维。放心基础概念我会讲但不会啰嗦到让你睡着。1. 动手之前先搞清楚你到底要调哪个盘1.1 三种常见“空间不足”场景先说结论所有分区调整方案本质上都是“挪空间”和“扩空间”的组合但具体操作完全取决于你的文件系统类型、分区表格式以及那块磁盘当初是怎么规划的。我归纳了一下实际工作中遇到“空间重新分配”的需求大概逃不出下面三种场景**场景A根分区 / 不够用其他分区还有余量。**典型例子是/home分了 200G结果数据全堆在/下/home才用了 20G。这时候你想把/home的剩余空间划给/。**场景B物理磁盘本身满了但同机器上还有一块新加的盘没利用。**这时候不是“重新分配现有分区”而是把新盘做成 PV 并进卷组再分配给需要的逻辑卷。**场景C磁盘剩余空间充足但某个挂载点所在的逻辑卷LV容量太小需要直接扩大 LV 和文件系统。**比如 Docker 的/var/lib/docker目录所在分区写满了但同卷组里还有几百 G free。场景B和C对 LVM 来说几乎是一行命令的事场景A才是最需要小心操作的。因为大多数发行版默认都开了 LVM但**根分区 / 和 /home 如果都是独立的 LV它们同属于一个卷组这时候完全可以在线把 /home 缩回去再把空间加到 /**上。如果你是传统分区没有 LVM直接挂载/dev/sda2这种那就得用 GParted 或者 fdisk 删了重建稍有不慎就是数据全毁。1.2 用 df、lsblk、fdisk 摸清磁盘现状不管哪种场景第一步永远不是动手而是看清当前的布局。我每次接手别人的机器都会固定敲下面三条命令df -hT lsblk sudo fdisk -ldf -hT是最直观的能看到每个挂载点的文件系统类型、总容量、已用、可用。-T参数很关键它会显示 ext4、xfs、btrfs 这类类型因为不同文件系统的扩容命令完全不同。lsblk看的是块设备树能一眼看出哪个分区属于哪个磁盘有没有 LVM 的 PV/LV 层级。输出里有└─centos-root这种缩进时说明你机器上确实在用 LVM后面的操作会简单很多。sudo fdisk -l是看磁盘分区表的终极武器能看清是 MBR 还是 GPT 布局分区起始扇区在哪儿。调整传统分区时这个信息能救命。把这三条命令的输出记录下来再对照后面要讲的方法基本就不会出现“我扩了半天结果扩错盘”的惨剧。1.3 关键概念MBR与GPT、主分区与逻辑分区为什么要单独提分区表格式因为 MBR 和 GPT 对分区调整的支持力度完全不同。MBRMaster Boot Record是老古董了一块盘最多只能有 4 个主分区。想要超过 4 个就得把其中一个主分区改成“扩展分区”然后在扩展分区里再切“逻辑分区”。逻辑分区在动态调整上非常麻烦而且 MBR 对单分区大小上限是 2TB现在一块 NVMe 随便就是 4T、8TMBR 早就扛不住了。GPTGUID Partition Table是现代 UEFI 引导的标准格式最多支持 128 个分区单分区容量上限取决于文件系统基本可以认为没有上限。GPT 的另一个好处是可以无损调整分区边界因为它在磁盘末尾和开头都保留了分区表信息容错性也更好。怎么快速判断自己是 MBR 还是 GPTsudo fdisk -l输出里如果看到Disklabel type: gpt就是 GPT看到dos就是 MBR。也可以用sudo parted -l查看输出更明确。2. 能在线扩的优先在线扩LVM方案详解2.1 为什么LVM才是“空间重新分配”的最优解如果你当初装系统时用了 LVMLogical Volume Manager那么恭喜你绝大部分“重新分配空间”的需求都能在线完成不用卸载分区、不用重启、不用 Live CD生产环境也能放心操作。LVM 的逻辑就像把多个物理硬盘合并成一个“空间池子”卷组 VG然后从池子里切出任意大小的“逻辑卷”LV给系统用。真正存数据的物理分区我们叫它“物理卷”PV。整个层级是物理磁盘 → 分区 → PVpvcreate多个 PV 组成 VGvgcreate从 VG 里切出 LVlvcreateLV 上格式化文件系统再挂载使用因为 LV 是从“池子”里动态切出来的所以只要 VG 里还有剩余空间lvresize命令就能随时把 LV 调大或调小。最关键的是ext4 文件系统支持在线扩容xfs 支持在线扩容但不支持缩容。实际运维中“临时把 /home 的空间让给 /”这种操作LVM 十分钟内就能搞定而且全程不丢数据、不中断服务。这也是我一直建议新装机用户“尽量默认 LVM”的原因。虽然 LVM 比直接分区多了一层抽象性能损耗在 1% 以内但换来的是随时可以动态调整的灵活性这买卖太值了。2.2 LVM扩容的完整操作流程先看一个最简单的场景VG 里还有空闲空间想把 LV 直接扩大。# 1. 查看卷组剩余空间 sudo vgs # 2. 查看逻辑卷路径 sudo lvs # 3. 假设要扩展 / 所在 LV路径是 /dev/vg0/root sudo lvextend -L 20G /dev/vg0/root # 或者直接扩到指定大小 sudo lvextend -L 100G /dev/vg0/root # 4. 扩容文件系统ext4 用 resize2fsxfs 用 xfs_growfs # ext4 sudo resize2fs /dev/vg0/root # xfs sudo xfs_growfs /注意第 4 步是新手最容易忽略的。很多人执行完lvextend就以为成功了结果df -h一看容量根本没变。原因很简单LVM 的 LV 扩容了但文件系统还没“感知”到这个变化。目标挂载点是/时xfs_growfs /可以直接写挂载点而resize2fs必须要写设备路径。如果你要把文件系统缩容比如把 /home 缩小 10G顺序则完全相反# 1. 先卸载文件系统必须 sudo umount /home # 2. 检查文件系统必须否则可能损坏数据 sudo e2fsck -f /dev/vg0/home # 3. 缩小文件系统到目标大小比如 90G sudo resize2fs /dev/vg0/home 90G # 4. 缩小 LV 到同样大小 sudo lvreduce -L 90G /dev/vg0/home # 5. 重新挂载 sudo mount /home这里有个铁律先缩文件系统再缩 LV顺序不能反。如果先缩了 LV文件系统还认为自己有 100G 的空间一旦数据区超过了缩容后的边界分区直接损坏。我见过有同事在这个步骤上翻车恢复数据的代价比重新部署整个系统还大。还有一点要特别强调xfs 文件系统不支持缩容。如果你的 /home 是 xfsresize2fs根本不能用只能通过“备份数据 → 删除 LV → 重建更小的 LV → 恢复数据”这种曲线方案来处理。所以生产环境我一般建议 ext4 兼容性好xfs 适合大文件存储但千万别指望它缩容。2.3 LVM缩容的注意事项与实操心得实际操作中LVM 缩容最大的障碍不是命令而是“目标分区必须卸载”。根分区/是没法卸载的——你总不能把正在运行的操作系统根目录卸掉吧所以如果你要把/缩小光靠 LVM 在线操作做不到必须进 Live CD 环境或者从另一块硬盘启动系统后再缩。我在真实项目里的处理思路一般是这样的如果只是临时让出空间给其他 LV最稳的做法不是缩根分区而是直接把整块盘上没用的数据清掉或者把/home这种独立 LV 缩容。因为独立的挂载点/home、/var、/opt都可以卸载缩容操作完全不受“根被占用”的限制。如果是根分区真的大到离谱需要调整原来的 PV 大小那就得用 Live CD 引导。启动到 Live 环境后LV 组不激活用vgchange -an 卷组名禁用卷组然后用pvmresize调整物理卷再走“缩文件系统→缩LV→缩PV→调分区表”全流程。建议给 /home 分配合理初始大小经验值来看根分区留 50~80G 完全够用除非你把 Docker 镜像和日志全堆在 /其余空间全部划给 /home后续有需要再从 /home 转给其他目录。因为 /home 卸载容易转空间方便。3. 没有LVM用GParted图形化调整分区3.1 GParted的适用场景与准备工作如果你的系统没有用 LVM分区就是最传统的“一块磁盘切成 /dev/sda1、/dev/sda2”那空间重新分配就只能靠分区级别的操作。在命令行用 fdisk 删了重建风险极高一个起始扇区不对就是全线崩溃。这时候我强烈推荐 GParted它是一个图形化的分区编辑工具可以无损调整分区大小。GParted 支持 ext2/3/4、ntfs、fat32、btrfs但对 xfs 的支持不够完美不能收缩。它的核心思路是先收缩一个分区在磁盘上腾出空闲空间再扩展另一个分区把空闲空间吸收进来。准备工作有两件事**备份备份备份。**这话我说一百遍都不嫌多。分区表级别的操作哪怕再小心断电、误操作、程序 bug 都可能造成不可逆损失。用 Clonezilla 做整盘镜像或者至少把重要数据 copy 到另一块盘上。**准备一个 U 盘启动盘加载 GParted Live 环境。**为什么不能用系统自带的 GParted因为你要调整的分区通常是挂载状态比如根分区系统运行期间没办法卸载它。就算你用 GParted 看到分区调整按钮也是灰的。所以正确姿势是下载 GParted Live ISO用 Rufus 或 dd 写入 U 盘从 U 盘启动到独立的精简系统里操作。3.2 使用GParted调整分区完整步骤启动 GParted Live 后它会自动进入一个带图形界面的环境。基本操作流程如下在右上角选择要操作的物理磁盘比如/dev/sda。右键点击要缩小的分区比如/dev/sda5的 /home选“Resize/Move”。在弹出的窗口里把“Free space following”调大或者直接输入目标大小。注意图形界面里拖动滑块非常方便但是建议直接在数字框里输入精确值。点击“Resize/Move”后面板下方会出现一条待办操作。GParted 并不是立即执行而是先把操作记下来。用同样方法右键点击要扩大的分区比如/dev/sda2的 /选“Resize/Move”把新腾出来的空间加进去。确认所有操作无误后点击工具栏上的绿色对勾“Apply All Operations”。等待进度条走完。这个时间取决于分区大小和磁盘速度几十 G 的分区可能半小时。需要注意的细节是操作顺序很重要。如果扩大的是根分区前面的空间、缩小的是根分区后面的空间操作之间可能有依赖关系。GParted 会自动帮你排好顺序但你最好自己心里有数。另外调整完分区表后重启系统时会检查文件系统这是正常的别慌。3.3 遇到“无法卸载分区”怎么办这是 GParted 使用中最常见的卡壳点。你在 Live CD 环境里操作理论上所有分区都是未挂载状态但有的系统版本的 GParted Live 会自动挂载某些分区比如把原系统的根挂到 /mnt导致你调整分区时报“分区正忙”。解决办法很简单打开终端用umount卸载它。umount /dev/sda2如果提示 target is busy用lsof或fuser查一下是哪个进程占用lsof /dev/sda2 sudo fuser -km /dev/sda2在 GParted Live 这个精简环境里绝大多数情况fuser -km能直接杀掉占用进程。杀完再卸载然后回到 GParted 界面菜单栏选“Device → Refresh Devices”刷新一下。另外提醒一句GParted Live 里调整分区时如果断点了或者进度条卡住千万不要强制重启。可以等一段时间因为大分区镜像移动很慢界面可能处于“假死”状态。4. 命令行硬核方案fdisk/resize2fs/xfs_growfs4.1 新盘挂载到指定目录的傻瓜教程如果说 LVM 重分配是“用池子里的水浇灌稻田”那传统分区操作就是“直接挖水渠”。没有 LVM 时最省心的扩容方式其实是加一块新物理磁盘分区格式化后挂载到目标目录把数据迁过去再把旧目录清空。这样避免了直接动分区表风险小得多。完整流程是# 1. 查看新盘设备名假设是 /dev/sdb sudo lsblk # 2. 分区用 parted 或者 fdisk sudo parted /dev/sdb mklabel gpt sudo parted /dev/sdb mkpart primary ext4 1MiB 100% sudo partprobe /dev/sdb # 3. 格式化 sudo mkfs.ext4 /dev/sdb1 # 4. 临时挂载备份数据 sudo mkdir /mnt/new_disk sudo mount /dev/sdb1 /mnt/new_disk sudo cp -a /var/lib/docker/* /mnt/new_disk/ # 5. 写入 fstab 实现开机自动挂载可选但强烈建议 echo /dev/sdb1 /var/lib/docker ext4 defaults 0 2 | sudo tee -a /etc/fstab sudo systemctl daemon-reload这个方案的好处是全程不碰现有分区最大程度降低风险。坏处是你得有第二块物理盘。如果是云主机直接在控制台挂一块云盘操作逻辑完全一样。我之前给一台 Grafana 服务器扩容就是用这个方法把 Prometheus 数据目录挂到了新盘上全程服务没停过。4.2 ext4文件系统扩容与缩容的底层原理如果你确实需要在同一块盘上调整 ext4 分区的边界命令行的核心工具是fdiskresize2fs。注意传统分区下resize2fs只能扩大分区不能在线缩小 ext4 分区缩小需要离线操作也就是 unmount 状态下先resize2fs缩小文件系统再用fdisk缩小分区。扩大流程是这样的# 1. 查看当前分区边界 sudo fdisk -l /dev/sda # 2. 用 fdisk 删除原分区再重建记住起始扇区不能变 sudo fdisk /dev/sda进入 fdisk 交互界面后输入p查看分区表记下要调整分区的起始扇区。输入d删除该分区只是分区表记录被删除数据还在。输入n新建分区。起始扇区必须和之前保持一致结束时直接按 Enter 用末尾最大扇区。最后输入w写入分区表。这里有个超级大坑删除分区后如果没有立即重建系统崩溃或停电可能导致分区表信息丢失看起来就像整个硬盘被清空了。所以执行这个操作前一定要确保电源稳定并且确认起始扇区没有输错。有经验的运维会提前用sudo sgdisk --backuptable.bak /dev/sda备份 GPT 分区表。分区写完后让内核重新读取分区表sudo partprobe /dev/sda然后扩大文件系统sudo e2fsck -f /dev/sda2 sudo resize2fs /dev/sda2总结一下 ext4 调整的底层逻辑分区表告诉你“哪些扇区属于哪个分区”文件系统告诉你“数据在这些扇区里怎么组织”。resize2fs的作用是让文件系统感知到分区边界变化——扩大的部分会被文件系统格式化为新的可用空间缩小的部分要先把数据搬到安全区域再释放。所以先缩文件系统再缩分区等于先把数据搬到前段再把“后门”安全关掉。4.3 xfs只能扩不能缩的“坑”xfs 是老牌高性能文件系统默认就是 RHEL/CentOS 7 的根文件系统。它有个让运维又爱又恨的特性支持在线扩容不支持缩容。扩容命令极其简单sudo xfs_growfs /dev/sda3 # 或者挂载点 sudo xfs_growfs /data实际上你连参数都不用给它自己会扫描分区上的可用空间把文件系统扩满。这也是为什么“根分区不够了想扩 xfs”在 LVM 下很轻松但是在传统分区下就基本没法现场处理的原因——你不能缩 xfs也就没法腾出空间给别的分区。如果一个 xfs 分区真的不够用了我能想到的几种路线找另一块盘把数据迁过去把大的挂载点放到新盘上。如果有 LVM 且 VG 有空间直接lvextend -L 10G /dev/vg/lv然后xfs_growfs挂载点这是最顺滑的。如果连整个磁盘都快满了那就只能考虑用xfsdump备份 → 重建分区→xfsrestore恢复。虽然能解决但过程繁琐且耗时一般不到万不得已不干。还有一个容易踩的低级误区resize2fs对 xfs 根本不适用会直接报superblock 无法读取之类的错误。先df -T确认文件系统类型再选命令省得白忙一场。5. 常见问题与实战排错5.1 分区表被占用partprobe 不生效执行partprobe时如果报Failed to update partition table通常原因是某个分区还在被系统使用。你可以查看占用情况sudo lsof /dev/sda2 sudo fuser -vm /dev/sda2如果是根分区或 swap 分区partprobe确实是拿它没办法的因为内核不能卸载自己正在使用的设备。这时候要么直接重启如果你修改的是非启动分区但挂载了要么进入 rescue 模式执行。所以顺序上我通常建议能卸载的分区先卸载不能卸的分区比如 /在 Live CD 下操作。5.2 resize2fs 执行后空间没变化这个坑我踩过不止一次。resize2fs跑完了结果df -h看容量还是老样子。排查方向有这么几个你执行了lvextend但扩展的是 LV文件系统没扩。此时再看一眼lsblk确认 LV 大小是否已经变大。命令对错对象。比如你想扩/dev/sda2但写成了/dev/sdaresize2fs 会很礼貌地告诉你设备不是分区。ext4 文件系统有 reserved blocks默认 5%df -h显示的不是完整空间。用sudo tune2fs -l /dev/sda2 | grep Block count查看块数量再乘以块大小就知道了。有些情况下缩小 reserved 比例也能“省”出几个 Gsudo tune2fs -m 1 /dev/sda2另外df -h显示的 Used 包含了文件系统元数据刚扩完空间时看到的使用率数字好像变化不大其实是容量被隐藏了一部分。容量变大值 新分区扇区数 * 扇区大小 / 1024^3可以用fdisk -l对比前后 Output 里的 Total size 估算。5.3 误删除分区后的紧急恢复虽然我不希望大家遇到但“fdisk 里按了个 d 然后手贱把 w 敲了”这种事在运维圈真不少见。如果删除分区后没有重建数据其实还在磁盘上只是没有分区指向它。紧急恢复的思路是尽快停掉一切写操作防止数据覆盖。根据分区表备份恢复。如果你之前执行过sgdisk --backuptable.bak /dev/sda直接sgdisk --load-backuptable.bak /dev/sda就能恢复。没有备份的话用testdisk扫描并重建分区表。testdisk 是交互式工具选择磁盘 → 分区表类型 → Analyze → 找到丢失的分区 → 标记为 P主分区→ Write。这个方案能救回大部分分区但不是 100%所以再次强调动分区之前先备份分区表这是几十秒钟的事能救命。5.4 空间释放了但 df 显示依然满还有一种更隐蔽的情况你明明删掉了几十个 G 的文件df -h还是红的。这通常是因为某个进程仍然持有被删除文件的文件句柄。Linux 下删除文件只有最后一个进程关了句柄后磁盘空间才能真正释放。排查命令# 找出所有已删除但仍被占用的文件 lsof | grep (deleted)输出里会看到一行process_name (deleted)记下 PIDsudo ls -l /proc/PID/fd/* # 找到对应的文件描述符杀不掉的关键进程可以sudo truncate -s 0 /proc/PID/fd/文件描述符直接把文件内容清空空间立刻释放。这个坑在日志场景和数据库场景特别常见。比如 PostgreSQL 重写了某个大表但旧数据文件还没被释放df显示满实际上数据库内部已经看不到这个文件了。处理完句柄之后再用 LVM 扩容或者分区调整方案才能真正解决问题。结尾一点个人体会做分区空间重新分配这几年我最大的体会是能不动分区表就不动分区表能用 LVM 就不碰传统分区。分区是给“保守”场景用的LVM 才是给“生产环境”用的。如果你现在正在规划一台新服务器花五分钟把 LVM 方案配好比以后灾难时花两小时抢救数据划算得多。最后再分享一个小技巧每次调整完分区无论成功与否我都会在/etc/fstab文件里备份一份注释好的原始挂载信息并在服务器维护文档中记录调整前和调整后的分区表截图。一旦出问题还能照着快照快速恢复。别怕麻烦这不是多余的仪式感而是千锤百炼之后留下的职业病。
返回列表