1. 为什么 fdisk 至今仍是磁盘管理的首选工具
很多人第一次接触 Linux 磁盘管理,脑子里冒出来的第一个词就是fdisk。这个工具年纪不小了,从早期 Unix 时代一路活到现在,界面朴素、交互直接,没有花哨的图形化包装,但偏偏就是这种"老派"风格让它在服务器运维场景里经久不衰。你登录一台刚装好的 CentOS 或者 Ubuntu Server,手头没有任何图形界面,想把一块新挂载的数据盘分区、格式化、挂载,fdisk几乎是你唯一能立刻上手的工具。
它的核心定位很明确:管理磁盘分区表。注意,是分区表,不是文件系统。很多人会把"分区"和"格式化"混为一谈,实际上这是两个完全独立的步骤。fdisk负责在物理磁盘上划分出逻辑区域(分区),而mkfs系列命令才负责在这些区域上建立文件系统。理解这个分界线,是掌握磁盘管理的第一课。
fdisk能做的事情包括:查看现有分区表、创建新分区、删除分区、修改分区类型、调整分区起始位置、写入或放弃更改。它支持两种主流分区表格式——MBR和GPT。MBR 是传统方案,最大支持 2TB 磁盘和 4 个主分区;GPT 是较新的标准,支持超大容量磁盘和几乎无限的分区数量。你在fdisk里用g命令创建 GPT 分区表,用o命令创建 MBR 分区表,切换非常方便。
这篇文章适合谁看?如果你刚接触 Linux 运维,或者平时用虚拟机做实验需要手动分区,又或者你手上有一块新硬盘要挂载到服务器上,那这篇内容就是为你准备的。我会从最基础的查看磁盘信息开始,一步步带你走完创建分区、删除分区、修改分区类型的完整流程,同时把那些文档里不会写的坑和细节一并交代清楚。
提示:
fdisk只能操作 2TB 以下的磁盘分区表(MBR 限制)。如果你的磁盘超过 2TB,必须使用 GPT 分区表,或者改用parted/gdisk工具。不过fdisk本身也支持 GPT,所以大容量磁盘用fdisk配合 GPT 也是完全可行的。
2. 动手之前:搞清楚你的磁盘现状
2.1 用 lsblk 快速摸清磁盘拓扑
在动任何分区操作之前,第一件事永远是看清楚当前系统里有哪些磁盘、哪些分区、挂载在哪里。我见过太多人上来就fdisk /dev/sda,结果把系统盘的分区表给改了,机器直接起不来。这种事故在测试环境里可能只是重装系统的事,在生产环境里就是重大故障。
最直观的命令是lsblk:
lsblk输出大概长这样:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 50G 0 disk ├─sda1 8:1 0 1M 0 part ├─sda2 8:2 0 2G 0 part /boot └─sda3 8:3 0 48G 0 part / sdb 8:16 0 100G 0 disk sr0 11:0 1 1024M 0 rom这个输出信息量很大。NAME列告诉你设备名,SIZE是容量,TYPE区分 disk(整块磁盘)和 part(分区),MOUNTPOINT显示挂载点。你可以一眼看出sda是系统盘,因为它的分区挂载了/和/boot;sdb是一块全新的 100G 磁盘,没有任何分区,这就是我们可以安全操作的目标。
lsblk的好处是它以树形结构展示,父子关系一目了然。相比fdisk -l那种平铺直叙的输出,lsblk更适合快速判断"哪块盘是空的、哪块盘不能碰"。
2.2 fdisk -l 看分区表的细节
lsblk给你的是概览,要看分区表的细节还得靠fdisk -l:
fdisk -l /dev/sdb如果sdb是一块全新磁盘,输出会是:
Disk /dev/sdb: 100 GiB, 107374182400 bytes, 209715200 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes注意这里没有分区表信息,说明这块盘还没有被分区。如果是一块已经有分区的磁盘,你会看到类似这样的内容:
Disk /dev/sda: 50 GiB, 53687091200 bytes, 104857600 sectors Disk model: VMware Virtual S Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes Disklabel type: gpt Disk identifier: 12345678-ABCD-EF00-1234-567890ABCDEF Device Start End Sectors Size Type /dev/sda1 2048 4095 2048 1M BIOS boot /dev/sda2 4096 4198399 4194304 2G Linux filesystem /dev/sda3 4198400 104857566 100665167 48G Linux filesystem这里有几个关键信息需要关注。Disklabel type告诉你分区表类型是 gpt 还是 dos(MBR)。Start和End是分区的起止扇区号,Sectors是分区占用的扇区数量。Type列显示分区类型,Linux filesystem 是最常见的类型。
注意:
fdisk -l不加设备名会列出所有磁盘的分区表,输出可能很长。建议养成指定设备名的习惯,避免看花眼。
2.3 确认磁盘是否已挂载
在操作分区之前,必须确认目标磁盘没有被挂载。如果磁盘正在使用中,你修改分区表后系统可能无法正确识别,甚至导致数据损坏。用mount命令或者findmnt检查:
mount | grep sdb findmnt /dev/sdb如果没有任何输出,说明这块盘没有被挂载,可以安全操作。如果有输出,你需要先卸载:
umount /dev/sdb1如果提示 "target is busy",说明有进程正在使用这个挂载点。用lsof或者fuser找到占用进程:
lsof /mnt/data fuser -m /mnt/data处理完占用进程后再卸载。这一步千万不能跳过,我见过有人强行修改正在使用的分区表,结果文件系统直接损坏,数据恢复花了好几个小时。
3. fdisk 交互模式下的完整操作链路
3.1 进入 fdisk 交互界面
确认磁盘安全后,就可以进入fdisk的交互模式了:
fdisk /dev/sdb你会看到这样的提示:
Welcome to fdisk (util-linux 2.37.2). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Device does not contain a recognized partition table. Created a new DOS disklabel with disk identifier 0x12345678. Command (m for help):注意那句 "Changes will remain in memory only, until you decide to write them"——这是fdisk最重要的安全机制。你所有的操作都先保存在内存里,只有执行w命令才会真正写入磁盘。这意味着你随时可以用q命令退出而不保存任何更改。这个设计给了你充分的试错空间,不用担心手滑。
输入m可以看到所有可用命令:
Help: DOS (MBR) a toggle a bootable flag b edit nested BSD disklabel c toggle the dos compatibility flag Generic d delete a partition F list free unpartitioned space l list known partition types n add a new partition p print the partition table t change a partition type v verify the partition table Misc m print this menu u change display/entry units x extra functionality (experts only) Save & Exit w write table to disk and exit q quit without saving changes Create a new label g create a new GPT disklabel G create a new empty GPT partition table o create a new empty DOS partition table s create a new empty Sun disklabel命令不多,常用的就那么几个:n新建分区、d删除分区、p打印分区表、t修改分区类型、w保存退出、q不保存退出。下面我按实际操作顺序逐一讲解。
3.2 创建新分区:n 命令的每一步选择
假设我们要在/dev/sdb上创建一个 50G 的主分区。在fdisk提示符下输入n:
Command (m for help): n Partition type p primary (0 primary, 0 extended, 4 free) e extended (container for logical partitions) Select (default p):这里让你选择主分区还是扩展分区。MBR 分区表最多支持 4 个主分区,如果你需要超过 4 个分区,就需要创建一个扩展分区,然后在扩展分区里创建逻辑分区。对于大多数场景,直接选p(主分区)就行,按回车使用默认值。
Partition number (1-4, default 1):分区编号,默认从 1 开始。如果你之前删过分区,这里可能会显示其他可用编号。直接回车即可。
First sector (2048-209715199, default 2048):起始扇区。默认值 2048 是经过对齐优化的,强烈建议直接回车使用默认值。为什么是 2048?因为现代磁盘的物理扇区通常是 4096 字节(8 个逻辑扇区),2048 是 8 的倍数,能确保分区起始位置与物理扇区对齐,避免读写性能下降。这个细节在机械硬盘时代不太重要,但在 SSD 上影响很明显。
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-209715199, default 209715199):结束扇区。这里你可以直接输入大小,比如+50G表示从起始位置往后 50G。也可以用+50M、+1T等单位。如果不指定,默认会占用剩余所有空间。
Created a new partition 1 of type 'Linux' and of size 50 GiB.分区创建成功。此时输入p可以查看当前分区表:
Disk /dev/sdb: 100 GiB, 107374182400 bytes, 209715200 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x12345678 Device Boot Start End Sectors Size Id Type /dev/sdb1 2048 104857599 104855552 50G 83 Linux注意Id列是 83,这是 Linux 文件系统的默认类型标识。Boot列是空的,说明这个分区没有设置启动标志。如果你需要从这个分区启动系统,需要用a命令切换启动标志。
3.3 修改分区类型:t 命令的实际用途
t命令用来修改分区类型。这个操作在什么场景下有用?举几个例子:你要把某个分区用作 swap,需要把类型改成 82;你要创建 LVM 物理卷,需要改成 8e;你要做 RAID,需要改成 fd。虽然文件系统的实际内容由mkfs决定,但分区类型标识能让系统和其他工具正确识别分区的用途。
操作方式:
Command (m for help): t Selected partition 1 Hex code or alias (type L to list all): 82 Changed type of partition 'Linux' to 'Linux swap / Solaris'.输入L可以列出所有支持的类型代码,列表很长,常用的就那几个:
| 代码 | 类型 | 用途 |
|---|---|---|
| 83 | Linux | 普通 Linux 文件系统 |
| 82 | Linux swap | 交换分区 |
| 8e | Linux LVM | LVM 物理卷 |
| fd | Linux raid autodetect | RAID 成员盘 |
| ef | EFI System | EFI 系统分区 |
提示:如果你用的是 GPT 分区表,类型代码的体系不一样,
t命令会列出 GPT 专用的类型名称,比如 "Linux filesystem"、"Linux swap"、"EFI System" 等。操作逻辑相同,只是选项不同。
3.4 删除分区:d 命令与数据不可逆性
删除分区用d命令:
Command (m for help): d Selected partition 1 Partition 1 has been deleted.如果磁盘上有多个分区,fdisk会提示你选择要删除哪个:
Command (m for help): d Partition number (1,2, default 2):删除分区这个操作本身只是修改分区表,并不会立即擦除磁盘上的数据。但分区表一旦写入,原来的分区结构就不存在了,文件系统无法再被正常挂载。数据恢复虽然理论上可行,但实际操作非常麻烦,需要专业工具逐扇区扫描。所以删除分区之前一定要确认数据已经备份或者不再需要。
我个人的习惯是:在生产环境中,删除分区之前先用dd把分区的前 512 字节备份出来:
dd if=/dev/sdb1 of=/root/sdb1_backup.bin bs=512 count=1这个备份包含了文件系统的超级块信息,万一误删了分区,可以用它来辅助恢复。当然,这只是应急手段,不能替代正规备份。
3.5 保存与退出:w 和 q 的区别
所有操作完成后,输入w写入磁盘并退出:
Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. Syncing disks.如果不想保存任何更改,输入q直接退出:
Command (m for help): qq命令不会对磁盘做任何修改,所有在内存中的操作都会被丢弃。这个设计在你不确定操作是否正确时非常有用——你可以随便试,看完p的输出确认无误后再决定是否w。
注意:在某些情况下,
w之后系统可能提示 "Re-reading the partition table failed",这是因为磁盘正在被使用。此时需要重启系统或者用partprobe命令强制内核重新读取分区表:partprobe /dev/sdb
4. MBR 与 GPT 的选择逻辑与转换实操
4.1 两种分区表的本质差异
MBR(Master Boot Record)和 GPT(GUID Partition Table)是两种不同的分区表格式,它们的差异远不止"支持容量大小"这么简单。
MBR 诞生于 1980 年代,设计上有很多历史局限。它的分区表存储在磁盘的第一个扇区(512 字节),其中 446 字节用于引导代码,64 字节用于分区表,每个分区表项占 16 字节,所以最多只能有 4 个主分区。为了突破这个限制,后来引入了扩展分区的概念——用一个主分区的位置来存放扩展分区,里面再划分逻辑分区。这种"套娃"式的设计增加了复杂性,也容易出问题。
GPT(GUID Partition Table)是 UEFI 标准的一部分,分区表信息存储在磁盘的多个位置(头部和尾部各有备份),每个分区用 GUID 标识,理论上支持无限个分区(实际限制通常是 128 个)。GPT 还自带 CRC32 校验,能检测分区表是否损坏。对于超过 2TB 的磁盘,GPT 是唯一选择。
| 对比项 | MBR | GPT |
|---|---|---|
| 最大磁盘容量 | 2TB | 9.4ZB |
| 最大主分区数 | 4 | 128(典型值) |
| 分区表备份 | 无 | 有(头部+尾部) |
| 校验机制 | 无 | CRC32 |
| 引导方式 | BIOS | UEFI(也兼容 BIOS) |
| 适用场景 | 老系统、小磁盘 | 新系统、大磁盘 |
4.2 在 fdisk 中切换分区表类型
在fdisk交互模式下,创建 GPT 分区表用g命令:
Command (m for help): g Created a new GPT disklabel (GUID: 12345678-ABCD-EF00-1234-567890ABCDEF).创建 MBR 分区表用o命令:
Command (m for help): o Created a new DOS disklabel with disk identifier 0x12345678.这两个操作都会清空现有分区表,所以执行前必须确认磁盘上没有重要数据。如果你只是想查看当前分区表类型,用p命令看Disklabel type那一行就行。
注意:从 MBR 切换到 GPT 或者反过来,都会导致原有分区信息丢失。如果磁盘上已经有数据,不要直接切换分区表类型,应该先备份数据,再重新分区。
4.3 大容量磁盘的分区策略
对于超过 2TB 的磁盘,必须使用 GPT 分区表。但即使磁盘小于 2TB,我也建议优先使用 GPT,原因有三:第一,GPT 有分区表备份,万一主分区表损坏可以从备份恢复;第二,GPT 没有主分区数量限制,后续扩展更灵活;第三,现代操作系统和主板普遍支持 UEFI 引导,GPT 是更符合趋势的选择。
创建 GPT 分区表的流程和 MBR 基本一致,只是在n命令创建分区时,fdisk不会问你"primary 还是 extended",因为 GPT 没有这个概念,所有分区都是平等的。分区类型的选择也变成了直接输入类型名称或 UUID。
如果你需要把一块已有数据的 MBR 磁盘转换成 GPT,不能直接在fdisk里操作,需要用gdisk或者sgdisk工具。gdisk的界面和fdisk很像,但它专门用于 GPT 分区表,支持无损转换(有一定风险,务必先备份)。
5. 分区之后的收尾工作:格式化与挂载
5.1 mkfs 格式化:选择正确的文件系统
分区创建完成后,还需要格式化才能使用。格式化的本质是在分区上建立文件系统结构,让操作系统能够读写文件。Linux 下常用的文件系统有 ext4、xfs、btrfs 等。
ext4 是最通用的选择,兼容性好,工具链成熟:
mkfs.ext4 /dev/sdb1xfs 在高并发和大文件场景下性能更好,是 RHEL/CentOS 7 之后的默认文件系统:
mkfs.xfs /dev/sdb1如果你要创建 swap 分区:
mkswap /dev/sdb1 swapon /dev/sdb1格式化命令执行前会提示确认,因为这会清除分区上的所有数据。如果你确定分区是空的或者数据不需要了,可以加-F参数跳过确认:
mkfs.ext4 -F /dev/sdb1提示:格式化时可以用
-L参数给文件系统打标签,方便后续挂载时用标签代替设备名:mkfs.ext4 -L data /dev/sdb1挂载时就可以写成
mount LABEL=data /mnt/data,这样即使设备名变了(比如加了新硬盘导致 sdb 变成 sdc),挂载配置也不会失效。
5.2 挂载与开机自动挂载
格式化完成后,创建挂载点并挂载:
mkdir -p /mnt/data mount /dev/sdb1 /mnt/data用df -h确认挂载成功:
df -h /mnt/data如果要开机自动挂载,需要编辑/etc/fstab文件。推荐使用 UUID 而不是设备名,因为设备名可能会变:
blkid /dev/sdb1输出类似:
/dev/sdb1: UUID="12345678-abcd-ef00-1234-567890abcdef" TYPE="ext4" LABEL="data"然后在/etc/fstab中添加一行:
UUID=12345678-abcd-ef00-1234-567890abcdef /mnt/data ext4 defaults 0 2各字段含义:UUID 是设备标识,/mnt/data是挂载点,ext4是文件系统类型,defaults是挂载选项,第一个0表示不备份,第二个2表示开机时检查文件系统(根分区是 1,其他分区是 2,不检查是 0)。
注意:修改
/etc/fstab后,先用mount -a测试一下,确认没有报错再重启。如果 fstab 写错了导致系统无法启动,需要进入救援模式修复,非常麻烦。
5.3 验证分区对齐与性能
分区对齐是容易被忽略但影响性能的细节。用parted可以检查分区是否对齐:
parted /dev/sdb align-check optimal 1如果输出 "1 aligned",说明分区 1 是对齐的。如果输出 "1 not aligned",说明起始扇区没有对齐到物理扇区边界,可能会影响读写性能。
对于 SSD,还可以用fdisk -l查看Sector size那一行。如果physical是 4096 而logical是 512,说明磁盘支持 4K 物理扇区,分区起始位置应该是 8 的倍数(即 4096 字节的倍数)。fdisk默认的 2048 起始扇区正好满足这个要求。
6. 那些年我踩过的 fdisk 坑
6.1 误操作系统盘:最危险的操作
我刚入行的时候,有一次在虚拟机上做实验,想给一块新加的磁盘分区,结果手快输入了fdisk /dev/sda,而sda是系统盘。当时没注意,直接n创建了一个新分区,然后w写入。结果系统重启后直接进入 grub rescue 模式,因为分区表被改了,引导程序找不到原来的分区。
这个教训让我养成了一个习惯:操作分区之前,先用lsblk确认目标磁盘,并且把系统盘的分区表备份出来。备份命令很简单:
sfdisk -d /dev/sda > /root/sda_partition_backup.txt万一误操作,可以用这个备份恢复:
sfdisk /dev/sda < /root/sda_partition_backup.txt6.2 分区表未更新导致挂载失败
有时候你在fdisk里创建了分区,w保存退出后,用lsblk却看不到新分区。这是因为内核还没有重新读取分区表。解决方法有两个:一是重启系统,二是用partprobe命令:
partprobe /dev/sdb如果partprobe也报错,提示设备忙,可以用partx命令:
partx -a /dev/sdb这个命令会强制内核重新扫描磁盘的分区表,通常能立即生效。
6.3 删除分区后忘记更新 fstab
如果你删除或修改了某个分区,但/etc/fstab里还有对应的挂载条目,系统启动时会因为找不到设备而进入紧急模式。这种情况在测试环境里很常见——你删了一个测试分区,但忘了清理 fstab。
避免这个问题的方法是:删除分区后立即检查 fstab:
grep sdb /etc/fstab如果有对应的条目,用#注释掉或者直接删除。然后运行mount -a确认没有报错。
6.4 SSD 上的分区对齐问题
早期我在 SSD 上分区时,没有关注对齐问题,直接用了fdisk的默认值。后来用parted检查发现分区没有对齐,导致写入性能下降了将近 30%。虽然fdisk现代版本的默认起始扇区 2048 已经是对齐的,但如果你手动指定了起始扇区,一定要确保它是 8 的倍数(对于 512 字节逻辑扇区、4096 字节物理扇区的磁盘)。
检查方法:
cat /sys/block/sdb/queue/physical_block_size cat /sys/block/sdb/queue/logical_block_size如果物理块大小是 4096,逻辑块大小是 512,那么起始扇区应该是 8 的倍数。fdisk的默认值 2048 满足这个条件。
6.5 在脚本中使用 fdisk 的注意事项
fdisk是交互式工具,不适合直接在脚本里用。如果你需要自动化分区,应该用sfdisk或者parted的命令行模式。比如用sfdisk创建分区:
echo "2048,104857599,L" | sfdisk /dev/sdb或者用parted:
parted -s /dev/sdb mklabel gpt parted -s /dev/sdb mkpart primary ext4 1MiB 50GiB这些命令可以直接写在脚本里,不需要人工交互。fdisk虽然也可以用echo管道输入命令序列,但可读性和可维护性都很差,不推荐在生产脚本中使用。
7. 从 fdisk 延伸到日常磁盘管理习惯
fdisk只是磁盘管理的一个环节。在实际运维中,你还需要掌握df、du、lsblk、blkid、mount、umount等命令的配合使用。我个人的习惯是:每次动磁盘之前,先跑一遍lsblk和df -h,把当前状态截图或者记录到笔记里;操作完成后,再用同样的命令确认结果符合预期。
另外,对于生产服务器,我强烈建议使用 LVM(逻辑卷管理)而不是直接分区。LVM 可以在不重启的情况下动态调整分区大小,灵活性远超传统分区。fdisk创建的分区可以作为 LVM 的物理卷(PV),然后用pvcreate、vgcreate、lvcreate一步步构建逻辑卷。这套组合拳在需要频繁调整存储的場景下非常实用。
最后分享一个我常用的磁盘信息速查命令组合:
lsblk -f这个命令会列出所有磁盘和分区,同时显示文件系统类型、UUID、挂载点,一屏就能看完所有关键信息。比单独跑lsblk、blkid、df三个命令高效得多。