1. 先搞清楚你的磁盘长什么样设备命名与识别在动手分区之前我强烈建议你先花两分钟把磁盘的“身份信息”摸清楚。很多朋友上来就fdisk /dev/sda结果分完才发现操作错了盘轻则数据丢失重则系统起不来。这种事我见过不止一次。Linux 下的磁盘设备文件名是有规律的RHEL/CentOS、Debian/Ubuntu 这些主流发行版基本沿用同一套命名逻辑。传统的 SCSI 和 SATA 硬盘通常叫/dev/sda、/dev/sdb这样依次排下去如果是云服务器虚拟化出来的盘可能是/dev/vda、/dev/vdbNVMe 固态盘则长这样/dev/nvme0n1其中nvme0是控制器编号n1是命名空间编号。分区就是在这些设备名后面直接追加数字比如/dev/sda1、/dev/nvme0n1p1NVMe 的分区号前有个p别漏了。1.1 用 lsblk 一眼看清磁盘拓扑我最常用的命令其实是lsblk不是fdisk -l。原因很简单lsblk以树形结构展示磁盘和分区的从属关系输出非常直观而且它默认不读取所有分区的元数据速度很快。$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 80G 0 disk ├─sda1 8:1 0 1G 0 part /boot ├─sda2 8:2 0 50G 0 part / └─sda3 8:3 0 29G 0 part [SWAP] sdb 8:16 0 500G 0 disk看到没sda是系统盘分了三个区/boot、根分区和 swapsdb是一块 500G 的全新数据盘目前没有任何分区也没有挂载点这就是我们接下来要处理的目标。如果某个分区已经被挂载MOUNTPOINTS列会显示对应的目录如果显示为空说明这块盘还没挂载需要你主动配置。提示在某些带 RAID 卡的物理机上磁盘可能显示为/dev/sda但容量和实际不符或者出现/dev/mapper/xxx这种设备映射路径。这是硬件 RAID 或 LVM 的产物不属于本文讨论的裸盘分区范畴。1.2 用 fdisk -l 确认磁盘状态与大小lsblk看结构fdisk -l看细节。两条命令配合使用基本不会误判$ sudo fdisk -l /dev/sdb Disk /dev/sdb: 500 GiB, 536870912000 bytes, 1048576000 sectors Disk model: Virtual Disk Units: sectors of 1 * 512 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes这里有两个信息值得注意。一个是扇区大小。现在主流的 4K 先进格式硬盘物理扇区是 4096 字节但逻辑扇区通常还是暴露为 512 字节为了实现兼容。分区工具默认都会按逻辑扇区对齐一般不需要手动干预。另一个是整块磁盘的总扇区数。1048576000 sectors这个数字乘以 512 字节就是磁盘总容量。分区的时候起始扇区建议留出 2048 个扇区即 1 MiB的对齐空间这能让分区边界和底层物理扇区对齐避免读写性能下降。现代分区工具默认就是这么做的你不需要自己算但理解一下没坏处。1.3 物理盘、分区、文件系统三者到底什么关系很多新手把“磁盘”“分区”“文件系统”混为一谈这里我用一句话说透磁盘是一块完整的存储介质分区是把这块介质划成若干逻辑区域文件系统是在某个分区之上建立的目录和文件组织结构。打个比方磁盘就像一块地皮分区就是在这块地皮上画出的几块宅基地文件系统则是每块宅基地上盖好的房子和铺设的道路——你最终用的是房子里的空间而房子必须建造在指定的宅基地上。所以完整的操作链路是识别磁盘 → 创建分区 → 格式化文件系统 → 挂载到目录 → 写入/etc/fstab实现永久挂载。任何一步跳过了系统就不会按你预期工作。接下来我们一步步来。2. 分区前的关键决策MBR 还是 GPT确定要操作哪块盘之后先别急着敲fdisk。你面临第一个关键选择这块盘用 MBR 还是 GPT 分区表这个选择做错了后面可能要返工甚至数据全毁。2.1 两种分区表格式的本质区别MBRMaster Boot Record主引导记录是上世纪 80 年代设计的方案。它把分区表存放在磁盘的第一个扇区里总共只有 64 字节的空间每条分区记录占 16 字节所以最多只能记录 4 个主分区。解决多分区需求的办法是“扩展分区 逻辑分区”但这条链路在维护上稍显繁琐。MBR 还有一个硬伤分区表项用 32 位来记录起始扇区按 512 字节扇区计算单块磁盘最大只能寻址到 2 TiB。这意味着超过 2T 的盘用 MBR 根本没法把全部容量都用上。GPTGUID Partition Table全局唯一标识分区表是 UEFI 时代的新标准。它不再局限于第一个扇区而是在磁盘头部和尾部各放一份分区表互为备份还带有 CRC 校验能识别分区表损坏。GPT 最多支持 128 个分区Windows 默认上限单盘容量上限高到 9.4 ZB在实际使用中可以认为没有容量限制。2.2 什么场景选什么我的建议很直接我个人的选择标准如下新装的服务器、新买的数据盘统一用 GPT。不管这块盘现在是 500G 还是 5TGPT 都没有容量焦虑而且以后如果要把分区数据迁移到更大的盘上分区表不用重做。老机器、老系统比如 2010 年以前的 BIOS 固件环境或需要和 Windows XP 这类老系统共用移动硬盘的场景才考虑 MBR。系统盘如果要用 UEFI 引导那必须是 GPT如果是传统 BIOS 引导用 MBR 或 GPT 都可以但建议跟厂商固件设置保持一致。注意MBR 和 GPT 互相转换是不可逆的破坏性操作。在已经分好区、存了数据的盘上直接转换分区表数据会全部丢失。如果你确实需要转换必须先把数据备份出来重新分区再把数据导回去。别指望有“无损转换”这种好事。2.3 分区规划别等到装完系统才想分区这件事最怕“事后诸葛亮”。以一块 500G 的存储盘为例我通常这样规划分区用途建议大小文件系统挂载点业务数据主分区400Gxfs 或 ext4/data日志分区80Gxfs/var/log/备份或临时文件剩余全部ext4/backup当然这只是一个参考。具体规划取决于你的业务场景如果是数据库服务器可能不需要分开存放日志如果是对象存储节点可能一整块大分区更省心。但有两个原则我认为放之四海而皆准根分区和数据分区要分开否则系统崩溃重装时业务数据会跟着遭殃。日志目录独立分区至少在大容量存储场景下这样可以防止日志暴涨把根分区填满拖垮整个系统。3. 实操分区从 fdisk 到 parted两种工具走一遍分区工具的选择也有一点讲究。小容量磁盘用fdisk完全够用而且交互式操作比较友好大容量磁盘或需要精确定位分区的场景parted更合适。下面我把两种工具都走一遍。3.1 用 fdisk 创建分区一步步来以 500G 的/dev/sdb为例我打算分成两个区400G 给/data剩下约 100G 给/backup。$ sudo 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. Command (m for help): n Partition type p primary (0 primary, 0 extended, 4 free) e extended (container for logical partitions) Select (default p): p Partition number (1-4, default 1): 1 First sector (2048-1048575999, default 2048): Last sector, /-sectors or /-size{K,M,G,T,P} (2048-1048575999, default 1048575999): 400G Created a new partition 1 of type Linux filesystem and of size 400 GiB. Command (m for help): n Partition type p primary (0 primary, 1 extended, 3 free) e extended (container for logical partitions) Select (default p): p Partition number (2-4, default 2): 2 First sector (838862848-1048575999, default 838862848): Last sector, /-sectors or /-size{K,M,G,T,P} (838862848-1048575999, default 1048575999): Created a new partition 2 of type Linux filesystem and of size 100 GiB. Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. Syncing disks.这里有一个细节要特别注意第一次输入起始扇区时我直接回车用了默认值 2048目的是让分区对齐。如果手动指定起始扇区务必保证它能被 2048 整除否则分区边界会错位导致读写性能明显下降。第二次分区的起始扇区默认是838862848也就是 400G 之后的下一个扇区这个值是 fdisk 自动计算好的直接回车即可。终止扇区回车使用默认值代表把剩余空间全部分给第二个分区。最后输入wfdisk 才会真正把分区表写入磁盘。在此之前所有修改都只存在内存里输入q可以直接放弃。这个设计给了你反悔的机会。3.2 用 parted 应对大容量和脚本化场景fdisk对 MBR 支持很友好但在 GPT 和 2T 以上大容量盘的管理上parted更直接。特别是脚本化操作时parted可以直接通过命令行参数完成不用进交互模式。使用parted将整块 3T 盘分成一个 GPT 分区# 定义分区表类型为 GPT注意这会清空磁盘现有分区表 $ sudo parted /dev/sdc mklabel gpt # 创建主分区从 1MiB 开始使用 100% 剩余空间 $ sudo parted /dev/sdc mkpart primary 1MiB 100% # 查看分区结果 $ sudo parted /dev/sdc print Model: Virtual Disk (virtio) Disk /dev/sdc: 3000GB Sector size (logical/physical): 512B/512B Partition Table: gpt Disk Flags: Number Start End Size File system Name Flags 1 1049kB 3000GB 3000GB primary这三行命令比 fdisk 的交互式操作适合脚本化得多。有一点要提醒mklabel gpt这步会彻底清空磁盘上的所有现有分区和数据执行前务必确认盘符正确建议先用lsblk和parted /dev/sdc print检查。3.3 分区完成之后别忘了 partprobe分区表写入磁盘后内核不一定马上感知到变化。特别是在线操作、磁盘还在使用时你需要手动让内核重新读取分区表$ sudo partprobe /dev/sdbpartprobe是parted软件包提供的工具作用就是通知内核重新读取指定磁盘的分区表。执行完之后再用lsblk确认新的分区已经出现$ lsblk /dev/sdb NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sdb 8:16 0 500G 0 disk ├─sdb1 8:17 0 400G 0 part └─sdb2 8:18 0 100G 0 part如果执行完partprobe后分区仍然没有出现别慌有几种可能一是某些老旧内核确实支持不了在线重读需要重启二是磁盘上有 LVM 缓存之类的元数据没有刷新运行sudo partprobe时加上-s参数可以查看详情三是磁盘正被某进程占用这种情况重启系统最省事。4. 格式化与临时挂载mkfs 和 mount 的正确用法分区只是把“地皮”画好了接下来要在这块地面上铺设“道路和房屋”——也就是创建文件系统。然后再把文件系统挂到目录树里系统才能往里写数据。4.1 文件系统选型ext4、xfs还是 btrfs这是分区之后第二个关键决策。不同文件系统各有性格没有“绝对最好”只有“适不适合你的场景”。ext4是当前兼容性最好的通用文件系统。Red Hat 系和 Debian 系默认都用它做系统盘。它支持在线扩容成熟稳定工具箱tune2fs、resize2fs完备遇到问题网上资料也最多。xfs是 Red Hat 系RHEL/CentOS 8的默认文件系统。它在大文件、大分区、高并发写入场景下表现非常出色创建和挂载速度也快。RHEL 官方甚至明确说“从 RHEL 8 开始只支持 xfs 作为根文件系统”。但 xfs 的短板是不能缩容换句话说是支持在线扩容但缩小分区不行。btrfs的优势是快照、压缩、子卷这些高级功能适合需要做文件级备份或瘦身存储的场景。但它的稳定性在大规模生产环境还有争议日常使用也需要更仔细地维护。我个人的建议很实际不确定选什么就选 ext4存储量较大、对写入性能有要求就选 xfs需要快照功能再考虑 btrfs。4.2 格式化操作mkfs 命令详解以/dev/sdb1为例格式化为 xfs$ sudo mkfs.xfs /dev/sdb1 meta-data/dev/sdb1 isize512 agcount4, agsize26214400 blks sectsz512 attr2, projid32bit1 crc1 finobt1, sparse1, rmapbt0 reflink1 bigtime1 inobtcount1 nrext641 data bsize4096 blocks104857600, imaxpct25 sunit0 swidth0 blk naming version 2 bsize4096 ascii-ci0, ftype1 log internal log bsize4096 blocks25600, version2 sectsz512 sunit0 blks, lazy-count1 realtime none extsz4096 blocks0, rtextents0看到reflink1就说明你这个内核版本支持 xfs 的 reflink 特性可以配合cp --reflink做快速复制后面讲数据管理时会用到。如果你选 ext4$ sudo mkfs.ext4 /dev/sdb2 mke2fs 1.46.5 (30-Dec-2021) Creating filesystem with 26214400 4k blocks and 6553600 inodes Filesystem UUID: 3f8a4c9e-7a12-4b56-a123-4a65789abcde Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, ...注意看Creating filesystem with 26214400 4k blocks and 6553600 inodes这行。ext4 默认会按分区大小划出一个固定比例的 inode 数量每 16KB 空间一个 inode也就是 4K 块大小下每 4 个块一个 inode。如果这个分区要存大量小文件比如几百万个几 KB 的图片默认的 inode 数可能不够用。遇到这种情况手动指定-i参数提高 inode 密度$ sudo mkfs.ext4 -i 8192 /dev/sdb2表示每 8192 字节分配一个 inode这样同样的分区大小能容纳的理论文件数量翻了一倍。代价是每个 inode 占用的空间也变多实际可用容量会略微减少。文件数量巨多的冷数据存储分区这个取舍是值的。4.3 mount 挂载与 umount 卸载文件系统创建好之后先挂载起来测试一下确认没问题再写永久配置。# 创建挂载点目录 $ sudo mkdir -p /data /backup # 挂载文件系统 $ sudo mount /dev/sdb1 /data $ sudo mount /dev/sdb2 /backup # 查看挂载结果 $ df -h /data /backup Filesystem Size Used Avail Use% Mounted on /dev/sdb1 400G 1.2G 399G 1% /data /dev/sdb2 100G 60M 100G 1% /backup注意df -h输出里/data显示使用了 1.2G这不是数据写入了而是 xfs 文件系统自身创建时预留了部分元数据空间和日志空间全新文件系统也会显示一些小占用属正常现象。挂载时还可以带上-o参数指定挂载选项$ sudo mount -o noatime,nodiratime /dev/sdb1 /datanoatime的意思是读写文件时不更新访问时间戳。这个选项对大多数业务场景都是安全的除了个别需要精确追踪文件访问时间的审计系统可以明显减少写盘次数延长 SSD 寿命提升文件访问性能。nodiratime对目录同理。卸载用umount注意两个常见坑umount /data如果提示target is busy说明有进程正在这个挂载点下读写文件。用lsof /data找到占用进程或者fuser -km /data强制结束占用再卸载。当前工作目录如果在挂载点里面也会导致卸载失败。先用cd切到别处再卸载。5. 永久挂载/etc/fstab 一次配好不折腾临时挂载一重启就没了这是新手最容易踩的坑。要让系统开机自动挂载必须把挂载信息写进/etc/fstab文件。5.1 fstab 六大字段逐项拆解/etc/fstab每行代表一个挂载条目总共六个字段以空格或 Tab 分隔# device dir type options dump pass UUID3f8a4c9e-… /data xfs defaults,noatime 0 2各字段含义如下字段示例作用deviceUUIDxxx、/dev/sdb1指定要挂载的设备。建议用 UUID原因见下节dir/data挂载点目录必须提前创建好typexfs、ext4文件系统类型要与格式化时一致optionsdefaults,noatime挂载选项defaults包含 rw、suid、dev、exec、auto、nouser、async 等常用默认选项dump0 或 1是否用 dump 备份文件系统现代系统填 0 即可pass0、1、2开机时是否检查文件系统。根分区填 1其他分区填 2不需要检查填 0以我的两块盘为例/etc/fstab追加两行UUID3f8a4c9e-7a12-4b56-a123-4a65789abcde /data xfs defaults,noatime 0 2 UUID6c9e2f3a-8b34-4c56-b456-8c90def12345 /backup ext4 defaults,noatime 0 25.2 为什么坚持用 UUID 而不是 /dev/sdb1很多新手直接写/dev/sdb1 /data xfs defaults 0 0测试也没问题。但麻烦在下次重启——设备名不是一成不变的。如果你在系统里加了一块新硬盘或者某些硬盘的识别顺序发生变化/dev/sda可能变成/dev/sdb原来的sdb1可能变成sdc1。一旦设备名错位系统开机时就会找不到挂载设备直接进入紧急模式。而 UUID文件系统唯一标识符是格式化时随机生成并写入文件系统的只要你不重新格式化这个值就不会变。不管设备名怎么漂移系统都能通过 UUID 精确找到对应的文件系统。获取每个分区的 UUID 很简单$ sudo blkid /dev/sdb1: UUID3f8a4c9e-7a12-4b56-a123-4a65789abcde TYPExfs PARTUUID... /dev/sdb2: UUID6c9e2f3a-8b34-4c56-b456-8c90def12345 TYPEext4 PARTUUID...blkid输出的 UUID 就是我们要填到 fstab 里的值。别忘了看清楚每一行对应哪块盘这个真见过有人把两个分区 UUID 抄反了然后系统直接起不来。5.3 fstab 写错会导致系统无法开机修改/etc/fstab是一件有风险的事。如果 fstab 中某个字段写错了系统重启时会尝试挂载不存在的设备或错误的文件系统随后掉进 emergency 模式需要手动输入密码修复。所以我的习惯是修改 fstab 之后先用mount -a验证一遍$ sudo mount -amount -a会按照 fstab 的配置尝试挂载所有条目。如果没有任何错误输出说明语法和配置基本没问题只要报错就立刻修正不要带着错误配置去重启。如果你已经写错了并且重启后进不了系统在 GRUB 引导界面选择内核时按e编辑启动参数在linux那一行末尾加上systemd.unitemergency.target然后按Ctrlx启动进入紧急模式后用编辑命令修复 fstab。这个操作不复杂但对新手来说现场处理压力很大所以还是建议大家提前验证、常态化验证。6. 生产环境避坑实录扩容、swap 与数据安全最后这一部分我想把自己踩过的一些坑和总结出来的经验写透。这些都是平时文档里不太会写、但真到生产环境一定会碰上的问题。6.1 在线扩容xfs 和 ext4 的扩容姿势不一样磁盘空间不够扩容是常态操作。如果当初分区时没有用 LVM那么扩容路径只能是新增大容量硬盘 → 新建分区并挂载 → 迁移数据 → 解除旧盘挂载。这个过程是有业务中断时间的。如果你当初用的是 LVM即使分区没有预留空间也可以先加一块物理盘加入卷组再把逻辑卷扩大文件系统在线扩容。以 ext4 为例扩容逻辑卷后$ sudo lvextend -L 100G /dev/vg_data/lv_data $ sudo resize2fs /dev/vg_data/lv_dataresize2fs在线扩容 ext4 分区是安全的可以做到业务不中断。xfs 则用xfs_growfs$ sudo lvextend -L 100G /dev/vg_data/lv_data $ sudo xfs_growfs /data注意 xfs 的扩容是挂载状态下也可以执行而且它不需要指定设备参数直接给挂载点即可。这里有一个反面教训xfs 不能缩容ext4 可以缩容但要先卸载文件系统。所以如果你的文件系统选型是 xfs又要做存储资源池化调配分区大小必须规划得只增不减。我见过有人以为 xfs 能像 ext4 一样缩容直接把逻辑卷缩了结果 xfs 文件系统直接损坏数据尽毁。这种事真不是段子。6.2 swap 分区还是 swap 文件以前装 Linuxswap 必须是一个独立分区。但现在主流发行版都支持 swap 文件的方式特别是磁盘分区调整越来越不灵活的情况下swap 文件更灵活——随时可以扩大缩小不用动分区表。创建 8G swap 文件的完整流程# 创建文件并指定大小fallocate 比 dd 快非常多 $ sudo fallocate -l 8G /swapfile # 修改权限swap 文件不能是普通用户可读的 $ sudo chmod 600 /swapfile # 格式化为 swap $ sudo mkswap /swapfile # 启用 swap $ sudo swapon /swapfile # 写入 fstab实现开机自动启用 $ echo /swapfile none swap sw 0 0 | sudo tee -a /etc/fstab # 查看 swap 使用情况 $ free -h第一次创建 swap 文件时我不太建议用fallocate因为某些文件系统上它分配的空间可能不是连续的swapon有时会失败或性能异常。用下面的命令更稳妥$ sudo dd if/dev/zero of/swapfile bs1M count8192这个命令会实打实地把 8192 个 1M 的零字节写入文件确保物理块是真实连续分配的虽然速度慢一些但求稳。swap 文件的另一大优势是完全不需要分区以后扩缩容敲几条命令就行不用碰分区表。如果你还在用 swap 分区我只能说你保守得有点过时了。6.3 分区操作前的最后检查清单任何对磁盘分区表的修改都是高危操作。我自己的习惯是操作前过一遍这个检查清单[ ] 确认盘符lsblk对照容量和厂商型号绝不靠猜[ ] 确认无进程占用lsof /dev/sdb、fuser -v /dev/sdb[ ] 确认数据已备份涉及数据盘操作重要数据必须异地备份或至少做文件系统快照[ ] 记录原始状态把blkid输出、df -h输出保存到一个文本文件方便事后核对[ ] 分区表变更前用parted /dev/sdb print再确认一次另外在云服务器上操作时建议先做一份云盘快照。这个操作成本通常很低但能在你误操作、误格式化、误删分区的场景下直接回滚。别问我为什么强调这个——每个做过运维的人都有过“手滑之后只能靠快照救命”的时刻。关于分区与挂载核心链路其实就这几步识别磁盘 → 规划分区表 → 创建分区 → 格式化 → 挂载 → 写入 fstab。每步都有对应的验证手段按顺序走、多看输出基本不会出大问题。我最想强调的还是那两件事操作前确认盘符修改 fstab 后立即验证。这两条做到位磁盘管理的大部分事故都可以避免。最后再分享一个我个人的小习惯所有新挂载的数据盘我都会在挂载点下创建一个lostfound之外的说明文件比如/data/README.txt写上这个盘的用途、挂载时间、UUID、负责人。半年后系统里挂了一堆盘你翻这个文件就能快速搞清楚每块盘是干嘛的比翻监控记录高效得多。这点小事关键时刻能省下不少排查功夫。
阅读完成 · 觉得有帮助?