三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

从fdisk到parted:现代磁盘分区工具的核心原理与实战指南

从fdisk到parted:现代磁盘分区工具的核心原理与实战指南

1. 从fdisk到parted:为什么我们需要更现代的磁盘分区工具

如果你在Linux服务器上折腾过磁盘,尤其是处理过超过2TB的大容量硬盘,那你大概率对fdisk这个老牌工具又爱又恨。爱它的简单直接,恨它在面对现代存储需求时的力不从心。我第一次在数据中心给一台新服务器配置4块8TB的硬盘做RAID时,就栽在了fdisk上——它压根不支持创建大于2TB的分区。那一刻,我意识到是时候让工具箱里的parted命令站到C位了。

parted是一个功能强大的磁盘分区和分区调整工具,它生来就是为了解决fdisk的局限性。它原生支持GPT(GUID分区表)分区方案,轻松应对数TB乃至数ZB的磁盘容量,同时还提供了交互式和命令行两种操作模式,以及更直观的“对齐”等高级功能。无论是为全新的CentOS/Ubuntu系统规划复杂的磁盘布局,还是在线调整一个正在运行的生产数据库的分区大小,parted都是更可靠的选择。这篇文章,我就以一个老运维的身份,带你彻底吃透parted,从核心概念到实战操作,再到那些手册里不会写的避坑技巧,让你下次面对磁盘时,心里更有底。

2. parted核心概念与设计思路解析

2.1 分区表类型:MBR与GPT的本质区别

要玩转parted,必须先理解它背后的“战场”——分区表。这就像一本书的目录,告诉系统数据存放在磁盘的哪个位置。传统工具fdisk主要服务于MBR分区表,而parted则是为GPT分区表而生的现代工具。

MBR,即主引导记录,是一个存在了数十年的标准。它把分区信息保存在磁盘最开始的512字节里。这直接导致了它的几个致命伤:首先,它只能记录4个主分区(想更多就得用扩展分区和逻辑分区,非常绕);其次,每个分区的起始和结束位置用32位表示,这限制了单个分区最大只能到2TB;最后,MBR没有备份,一旦这512字节损坏,整个磁盘的分区信息就可能丢失。

GPT,全局唯一标识分区表,是UEFI标准的一部分,旨在彻底取代MBR。它的设计就现代多了:分区表本身在磁盘头部和尾部分别存有一份,互为备份,安全性大增;它使用64位地址,理论支持的分区大小上限是9.4ZB(这是个天文数字);并且它不再有4个主分区的限制,通常支持128个分区以上。现在新买的服务器和电脑,只要不是特别老的系统,默认都使用GPT分区表。parted从设计之初就完美支持GPT,这是它相比fdisk的根本优势。

2.2 parted的核心设计哲学:面向大容量与脚本化

理解了GPT,就能明白parted的设计思路。它不仅仅是一个分区创建工具,更是一个磁盘布局管理器。其核心设计围绕两点展开:

第一是对大容量磁盘的原生友好parted操作磁盘时,默认单位是更符合现代存储的MiB、GiB、TiB(注意,这是1024进制单位,区别于厂商常用的1000进制的MB、GB)。你可以直接用mkpart primary 1MiB 100GiB这样的命令创建一个精确大小的分区,而不用像在fdisk里那样去计算令人头疼的柱面号。

第二是强大的非交互与脚本化能力parted支持在一条命令中完成所有操作,例如parted /dev/sdb mklabel gpt mkpart primary ext4 1MiB 100%。这个特性在自动化部署(如使用Ansible、Puppet)时极其有用。你可以将整个磁盘分区方案写成一个脚本,在成百上千台服务器上快速、一致地执行,这是fdisk的交互模式难以实现的。

2.3 与fdisk的工具选型决策

那么,什么时候该用parted,什么时候fdisk还能凑合?我的经验法则是:

  • 必须使用parted的场景:磁盘容量大于2TB;需要使用GPT分区表;计划在脚本或自动化工具中调用分区操作。
  • fdisk仍可一用的场景:处理小容量U盘或旧硬盘(小于2TB且为MBR分区);进行非常简单的、一次性的分区操作,且你对fdisk的交互界面更熟悉。

不过,我强烈建议,即使在小容量磁盘上,也优先尝试使用parted来熟悉其工作流。一旦掌握,你会发现它在逻辑清晰度和操作效率上更胜一筹。

3. parted命令详解与实操要点

3.1 基础命令结构与常用参数

parted命令的基本语法是parted [选项] [设备 [命令 [参数...]]]。最常用的有两种模式:

  1. 交互模式:直接输入parted /dev/sdX,会进入一个(parted)提示符的环境,可以连续输入多条命令。
  2. 命令行模式:直接在Shell中执行一条完整的parted命令,如parted /dev/sdb mklabel gpt

几个你必须熟记于心的核心命令:

  • mklabel:创建新的磁盘标签(即分区表类型),如gpt,msdos(即MBR)。
  • mkpart:创建新分区。需要指定分区类型(primary/logical)、文件系统类型(仅作提示,不格式化)、起始点和结束点。
  • rm:删除分区,只需指定分区号。
  • print:打印分区表信息。print all可以查看所有磁盘信息。
  • resizepart:调整分区大小(注意:调整前需确保分区未挂载,且文件系统本身支持并已完成调整)。
  • unit:设置输入输出的显示单位,如unit MiB,unit GB

注意parted的很多命令是即时生效的!它不像fdisk那样有一个“写入”命令。在parted中,mkpartrm命令一旦执行,分区表会立刻被修改。操作前务必双倍确认设备名(/dev/sdb还是/dev/sdc?)。

3.2 实战演练:为Ubuntu系统创建GPT分区

假设我们有一块全新的4TB硬盘/dev/sdb,需要为Ubuntu系统创建三个分区:1GB的EFI系统分区、100GB的根分区、以及剩余所有空间的家目录分区。

# 1. 启动parted,指定设备 sudo parted /dev/sdb # 2. 创建GPT分区表 (parted) mklabel gpt # 3. 创建EFI系统分区(通常需要FAT32文件系统,且要有boot和esp标志) (parted) mkpart primary fat32 1MiB 1025MiB (parted) set 1 boot on (parted) set 1 esp on # 4. 创建根分区(ext4文件系统) (parted) mkpart primary ext4 1025MiB 101025MiB # 大约100GB # 5. 创建家目录分区,占用剩余所有空间 (parted) mkpart primary ext4 101025MiB 100% # 6. 查看分区结果 (parted) print Model: ATA ST4000DM004-2CV1 (scsi) Disk /dev/sdb: 4001GB Sector size (logical/physical): 512B/4096B Partition Table: gpt Disk Flags: Number Start End Size File system Name Flags 1 1049kB 1075MB 1074MB fat32 primary boot, esp 2 1075MB 106GB 105GB ext4 primary 3 106GB 4001GB 3895GB ext4 primary # 7. 退出parted (parted) quit

退出parted后,我们还需要使用mkfs系列命令为这些分区实际创建文件系统:

sudo mkfs.vfat -F 32 /dev/sdb1 # 格式化EFI分区为FAT32 sudo mkfs.ext4 /dev/sdb2 # 格式化根分区为ext4 sudo mkfs.ext4 /dev/sdb3 # 格式化家目录分区为ext4

3.3 分区对齐:一个影响性能的关键细节

在机械硬盘时代,我们常听说要对齐“柱面”。在固态硬盘和现代高级格式硬盘(Advanced Format,扇区常为4KB)时代,分区对齐同样至关重要,且parted让它变得很简单。未对齐的分区会导致读写操作跨越物理扇区边界,引发额外的读写开销,显著降低IO性能,尤其是对于SSD。

parted从某个版本开始,默认会将分区的起始位置对齐到1MiB的边界(即2048个512B扇区),这完美对齐了绝大多数现代存储设备的物理扇区大小(4KB)和操作系统内存页大小。在上面的例子中,你看到分区的Start值都是1049kB(约1MiB)的倍数,这就是自动对齐的结果。

实操心得:除非有极其特殊的旧系统兼容性需求,否则永远信任并利用parted的默认对齐。在mkpart时,起始位置使用1MiB2MiB这样的值,或者直接使用百分比时,parted通常会帮你处理对齐。你可以用(parted) align-check optimal 分区号命令来检查某个分区的对齐是否是最优的。

4. 高级操作与生产环境应用

4.1 非交互式脚本化分区

自动化是运维的核心价值。下面是一个在Shell脚本中使用parted自动初始化一块磁盘的例子:

#!/bin/bash DISK="/dev/sdc" # 确保磁盘未被挂载 umount ${DISK}* 2>/dev/null # 创建GPT标签 parted -s $DISK mklabel gpt # 创建单个占用全部空间的分区 parted -s $DISK mkpart primary ext4 1MiB 100% # 格式化分区 mkfs.ext4 -F ${DISK}1 # 创建挂载点并挂载 mkdir -p /data mount ${DISK}1 /data # 写入fstab实现开机自动挂载 echo "${DISK}1 /data ext4 defaults 0 0" >> /etc/fstab

这个脚本使用了-s(或--script)选项,让parted进入脚本模式,不显示任何提示信息,非常适合嵌入到自动化流程中。

4.2 调整现有分区大小

调整分区大小是高风险操作,务必先备份数据!这里演示如何将/dev/sdb3(家目录分区)缩小100GB,并将这100GB用于扩展/dev/sdb2(根分区)。这通常需要先从/dev/sdb3中“挖”出一块空闲空间。

前提条件

  1. 目标分区(/dev/sdb3)必须未挂载
  2. 文件系统本身必须支持缩小(如ext4/xfs通常支持在线缩小,但操作前最好卸载)。resize2fsxfs_growfs等工具用于实际调整文件系统大小,parted只调整分区表信息。
  3. 操作顺序永远是:先缩小文件系统 -> 再缩小分区。
# 1. 卸载分区 sudo umount /dev/sdb3 # 2. 检查文件系统(ext4为例) sudo e2fsck -f /dev/sdb3 # 3. 缩小文件系统。假设当前是3895GB,要缩小100GB到3795GB。 # 注意:resize2fs参数是目标文件系统大小,不是减少的量。 sudo resize2fs /dev/sdb3 3795G # 4. 使用parted缩小分区。需要计算新的结束点。 # 假设原分区从106GB开始,大小3795GB,那么新结束点 = 106GB + 3795GB = 3901GB sudo parted /dev/sdb (parted) resizepart 3 3901GB (parted) print # 确认3号分区已缩小 # 5. 现在,在3号分区之后有了一段空闲空间。我们需要先删除2号分区,再以更大的结束点重建它吗? # 不!对于相邻分区,更安全的做法是使用专业工具如`gparted`(图形界面)或`fdisk`的删除重建。 # 因为parted的resizepart不能直接扩展一个被后续分区挡住的分区。 # 一个相对安全的命令行方案是: # a. 备份/dev/sdb2的数据。 # b. 删除/dev/sdb2分区: (parted) rm 2 # c. 重新创建更大的/dev/sdb2分区,起始点不变,结束点设为3901GB(即原3号分区的新起点)。 # d. 恢复数据,并重新创建文件系统或使用`resize2fs`扩展(如果文件系统还在)。

重要警告:在线调整分区,特别是涉及多个分区的位置变动,是极其危险的操作。在生产环境中,如果条件允许,我更倾向于备份数据、重新分区、恢复数据。如果必须在线操作,强烈建议先在虚拟机上完整演练整个流程。

4.3 处理“磁盘分区显示状态良好恢复分区”的疑难杂症

网络热词中提到了“磁盘分区显示状态良好恢复分区”,这通常指在Windows的“磁盘管理”中看到某个分区显示为“状态良好(恢复分区)”或“状态良好(EFI系统分区)”等。在Linux的parted视角下,这些分区只是带有特定标志的普通GPT分区。

例如,Windows的“恢复分区”通常是一个类型为“Microsoft recovery”的GPT分区。在parted中,你可以用print看到所有分区的类型GUID。如果你想在Linux下处理或删除一个Windows恢复分区(请谨慎,这可能影响系统恢复功能),可以:

  1. parted /dev/sdX print找到对应分区的Number。
  2. 使用parted /dev/sdX rm [分区号]删除它。

对于“EFI系统分区”,就是我们在3.2节创建的那个带有bootesp标志的分区。partedset命令可以管理这些标志。

5. 常见问题排查与操作实录

5.1 典型错误与解决方案速查表

问题现象可能原因解决方案
Error: The location ... is outside of the device /dev/sdX指定的分区起始或结束位置超出了磁盘的实际大小。使用parted /dev/sdX print确认磁盘总容量,确保分区范围在0B[磁盘大小]之间。通常结束点用100%最安全。
Warning: The resulting partition is not properly aligned for best performance.分区起始位置未对齐。mkpart时,起始位置使用1MiB的倍数。使用align-check optimal [分区号]验证。
Error: Partition(s) on /dev/sdX are being used.尝试修改的分区正在被系统使用(已挂载)。必须先用umount命令卸载该分区。对于系统盘的关键分区(如//boot),需要从Live CD/USB环境启动进行操作。
parted命令执行后系统不识别新分区分区表变更未被内核重新读取。运行partprobe /dev/sdX命令通知内核重新读取分区表。或者最简单的方法是重启系统
删除分区后,print仍然显示旧分区可能是缓存,或者分区表未成功写入。尝试退出parted再重新进入。如果问题依旧,检查磁盘是否只读(hdparm -r /dev/sdX),或者尝试使用wipefs命令清理分区签名。
无法对磁盘执行任何操作磁盘可能被系统锁定或存在活跃的进程。检查是否有lvmmdadm(RAID)或文件系统进程占用。使用lsblkfuser -m /dev/sdX1lsof /dev/sdX1查找并终止相关进程。

5.2 数据安全操作黄金法则

在我多年的运维生涯中,用血泪教训总结了几条关于磁盘操作的铁律:

  1. 三重确认设备名:在按下回车键前,问自己三遍“我当前操作的是/dev/sdb还是/dev/sdc?”尤其是在拥有多块硬盘的服务器上。一个有用的技巧是使用lsblk -fblkid命令,根据分区大小、标签或UUID来辅助确认。
  2. 备份先行:任何非创建新分区的操作(删除、调整大小),都必须先确保数据已备份。没有备份的操作等于赌博。
  3. 使用-s选项的风险:在脚本中使用parted -s非常方便,但也意味着它不会给出任何确认提示。在将脚本投入生产环境前,务必在测试环境用相同磁盘布局进行验证。
  4. 理解操作顺序:调整分区大小的正确顺序是:备份 -> 卸载 -> 检查文件系统 -> 调整文件系统 -> 调整分区。扩大分区则顺序相反:调整分区 -> 调整文件系统
  5. Live环境是救星:对于操作系统所在磁盘的分区操作,永远在Live CD/USB(如Ubuntu安装盘)环境下进行。这能确保所有系统分区都处于未挂载状态。

5.3 性能调优相关技巧

除了分区对齐,parted结合其他工具还能做一些性能调优:

  • 为SSD优化:对于固态硬盘,在分区时可以考虑留出一部分空间不分区(OP,预留空间),这有助于提升垃圾回收效率和延长寿命。例如,一块512GB的SSD,你可以只分区到480GB。
  • 文件系统选择:在mkpart时指定的文件系统类型(如ext4,xfs)只是一个标签,真正的格式化由mkfs完成。对于SSD,ext4(启用discard挂载选项)或f2fs是不错的选择。对于大容量机械硬盘仓库盘,xfs在处理大文件时可能有优势。
  • 分区规划:对于数据库服务器,将日志文件和数据文件放在不同的物理磁盘分区(甚至是不同的物理磁盘)上,可以显著提升IO性能。parted可以帮助你精确规划每块磁盘的布局。

最后,记住parted是你的工具,不是魔法棒。它强大而危险。每一次操作前,深呼吸,核对命令,想象一下操作的结果。当你能够熟练地用它规划整个存储架构时,那种一切尽在掌控的感觉,才是运维工作最大的乐趣所在。

← 返回列表