我最早接触 Linux 磁盘管理时,印象最深的一件事是:在服务器上敲了一下午命令,以为自己在"管理磁盘",结果第二天系统重启,之前挂载好的数据盘不见了。后来才明白,我只是临时挂载了一下,并没有把挂载关系写进系统配置。这类问题几乎每个刚接触 Linux 运维的人都会遇到,而磁盘管理恰恰是 Linux 系统里绕不开的基本功。
这篇内容是"Linux 磁盘管理"系列的第一篇,目标是把磁盘从"硬件设备"到"可用文件系统"这一整条链路讲透。我们会从设备命名、分区表、文件系统、挂载操作这几个核心环节入手,配合实际的命令演示和踩坑记录,帮助你建立一套完整的磁盘管理知识框架。内容适用于刚入门 Linux 的开发者、准备转行运维的新人,以及那些用过 Linux 但始终对磁盘管理"知其然不知其所以然"的朋友。
磁盘管理与日常开发最大的不同在于:它的每一步操作都直接作用于真实的数据载体,一旦出错,后果可能是毁灭性的。所以这篇文章里除了讲"怎么做",我还会重点讲"为什么这么做"以及"做错了会怎样"。
1. 先搞清楚 Linux 是怎么给硬盘"起名字"的
在动手管理磁盘之前,最基础也最容易忽视的一件事,是理解 Linux 系统中的设备命名规则。很多新手在 /dev/ 目录下看到一堆 sda、sdb、nvme0n1 之类的文件,完全分不清谁是谁,更不敢动。其实这套命名规则非常直观,搞懂之后,后续所有分区、格式化、挂载操作都会变得顺理成章。
1.1 /dev 目录下的设备文件是怎么来的
Linux 的设计哲学是"一切皆文件",硬件设备也不例外。当你往服务器上插一块硬盘,系统内核检测到新硬件后,会在 /dev/ 目录下创建对应的设备文件。应用层程序不直接跟硬件打交道,而是通过读写这些设备文件来间接操作硬件。
查看当前系统识别到的所有磁盘设备,最常用的命令是:
bash复制lsblk
这个命令的输出非常直观,它会以树状结构展示磁盘和分区的关系:
bash复制NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 40G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 39.5G 0 part /
lsblk 全称是 list block devices,专门用来列出块设备信息。从上面的输出可以很清楚看到:系统有一块名为 sda 的磁盘,容量 40G,下面分了两个分区 sda1 和 sda2,分别挂载在 /boot 和根目录。
除了 lsblk,下面这几个命令也值得记一下:
bash复制# 查看内核环缓冲区中的设备识别日志
dmesg | grep sd
# 查看已识别的 SCSI/SATA 设备详细信息
cat /proc/scsi/scsi
# 查看块设备主次设备号等信息
lsblk -f
提示:
lsblk -f会额外显示文件系统类型和 UUID,这个在后续挂载操作中非常有用,建议平时多养成用lsblk -f查看磁盘信息的习惯。
1.2 sd 开头和 nvme 开头的设备名有什么区别
服务器和台式机上最常见的磁盘设备命名有两类,一类是 sd 开头,一类是 nvme 开头。
sd 开头的设备名对应的是 SCSI 子系统管理的磁盘,包括传统的 SATA 硬盘、SAS 硬盘、USB 移动硬盘,以及虚拟化平台里的虚拟磁盘。命名规则是从 sda 开始,按字母顺序往后排:sda 是第一块,sdb 是第二块,sdc 是第三块,以此类推。同一块磁盘上的分区则通过数字后缀区分,sda1 是 sda 的第一分区,sda2 是第二分区。
nvme 开头的设备名对应的是 NVMe 固态硬盘,这类硬盘直连 PCIe 总线,速度和延迟表现远好于 SATA 接口的 SSD。命名规则与 sd 系列不同,格式是 nvme0n1,其中 0 代表控制器编号,n1 代表 Namespace 编号。NVMe 盘的分区同样用数字后缀表示,比如 nvme0n1p1 就是第一分区。
这里有一个实用判断技巧:
bash复制# 查看磁盘类型和传输方式
lsblk -d -o NAME,ROTA,TRAN
NAME ROTA TRAN
sda 1 sata
nvme0n1 0 nvme
ROTA 列如果为 1,表示是机械盘(旋转盘),为 0 表示 SSD 等固态存储;TRAN 列显示传输类型,是 sata、nvme 还是 usb,一看便知。
1.3 为什么不能依赖 sda 这种名字来定位硬盘
这里必须提醒一个非常容易踩坑的点:sda 这个名字并不保证永远指向同一块物理硬盘。具体来说,在以下场景中设备名可能会发生变化:
- 新增或移除硬盘后,原有的设备名顺序可能重新排列。
- 服务器重启后,内核识别硬盘的顺序与上次不同。
- 在虚拟化平台中调整了磁盘的接入顺序。
我自己就踩过这个坑。有次在测试服务器上插了第二块数据盘,结果重启之后原先配置好的服务全部启动失败。排查半天发现,原来系统把两块盘的识别顺序调换了,原来的 sdb 变成了 sda,而挂载配置里写的是 /dev/sdb1,自然就找不到了。
所以专业运维在写挂载配置时,一般不会直接用设备名,而是用 UUID 或 PARTUUID 来定位分区。UUID 是文件系统在格式化时生成的全局唯一标识符,只要不重新格式化,基本不会变化。查 UUID 的方式很简单:
bash复制blkid
或者:
bash复制lsblk -f
后面写 /etc/fstab 自动挂载配置时,我会详细演示用 UUID 替代设备名的完整做法,这里先记下这个思路。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 分区表选 MBR 还是 GPT,不只是容量问题
/dev/sda 是一块完整的硬盘,但硬盘不能直接用来存文件。使用前需要先做分区规划,也就是在硬盘上划分出一个或多个独立的区域,每个区域后续可以独立格式化、独立挂载。分区信息要记录在硬盘开头的特定区域里,这部分区域就是分区表。
2.1 MBR 与 GPT 的核心差异对照
目前主流的分区表格式只有两种:MBR 和 GPT。我在实际工作中发现,很多刚接触 Linux 的朋友对这两者的理解停留在"MBR 老、GPT 新"这种最浅层的程度,但真要回答"为什么要用 GPT",却说不出本质原因。
用一张表格直观对比:
| 对比项 | MBR | GPT |
|---|---|---|
| 全称 | Master Boot Record | GUID Partition Table |
| 最大分区容量 | 约 2TB(实际 2.2TB) | 理论可达 9.4ZB(实际受系统限制) |
| 最大分区数量 | 4 个主分区 | 默认 128 个分区(可扩展更多) |
| 备份机制 | 无备份,分区表损坏即灾难 | 分区表在磁盘首尾各有备份,自动校验恢复 |
| 数据校验 | 无 | 使用 CRC32 校验分区表完整性 |
| 引导方式 | BIOS + MBR | UEFI + GPT |
| 适用场景 | 老旧机器、老旧系统兼容需求 | 现代服务器、大容量存储、新装机 |
从表里可以看到,GPT 在容量、分区数量、可靠性上全面占优。除非你的机器是十几年前的旧设备,且 BIOS 和操作系统对 GPT 支持不完善,否则新装的系统一律建议选 GPT。
2.2 为什么 2TB 是 MBR 迈不过去的门槛
很多人只知道 MBR 无法管理超过 2TB 的磁盘,但不理解背后原因。这里用最朴素的话解释清楚。
MBR 的分区表项里用 32 位二进制数来记录分区的起始扇区和总扇区数。每个扇区的大小通常是 512 字节,而 2 的 32 次方乘以 512 字节大约等于 2.2TB,这就是 MBR 单分区容量上限的直接原因。如果磁盘容量本身大于 2.2TB,即使只划分一个小分区,MBR 格式也难以正确处理超出部分的地址。
GPT 则完全不同,它用 64 位二进制数来记录逻辑块地址,同样按 512 字节扇区计算,理论容量上限能达到 9.4ZB。这个数字大到什么程度?目前全球所有数据中心加起来的存储总量,离这个上限也差着好几个数量级。所以 GPT 在容量层面的提升,不是简单翻倍,而是彻底消除了容量制约。
2.3 检查整块磁盘的分区表格式
动手分区之前,先检查一下目标磁盘当前的分区表类型:
bash复制# 方法一
parted /dev/sdb print
# 方法二
fdisk -l /dev/sdb
# 方法三
blkid /dev/sdb
比如执行 parted /dev/sdb print,开头几行就会直接显示 Partition Table: gpt 或 Partition Table: msdos,前者就是 GPT,后者就是 MBR。
注意:
fdisk -l是最常见的查看方式,但输出中不会直接写 "MBR" 或 "GPT" 这两个词,而是用Disklabel type: dos表示 MBR,Disklabel type: gpt表示 GPT。dos就是 MBR,因为 MBR 最初是在 DOS 系统中引入的分区方案。不认识这个对应关系的人,看到dos很容易误解成是 DOS 系统相关的东西。
3. 动手分区:fdisk 和 parted 的使用逻辑与操作演示
确定分区表格式之后,真正开始分区。Linux 下的分区工具有很多,实际用得最多的就是 fdisk 和 parted。新版的 fdisk 其实也支持 GPT 格式,所以在大多数场景下,仅用 fdisk 就能完成任务。但如果涉及超大容量磁盘或者需要脚本化非交互式分区,parted 会更合适。
明确一点:下面的演示基于 /dev/sdb 这块空白数据盘。操作前请务必确认你操作的盘上没有任何需要保留的数据。任何分区操作都可能造成不可逆的数据丢失。
3.1 用 fdisk 完成 GPT 分区全流程
常见的 Linux 发行版默认都安装了 fdisk。使用下列命令进入交互式操作界面:
bash复制fdisk /dev/sdb
输入 m 可以查看帮助,但更常用的几个操作是:
g:创建新的 GPT 分区表n:新建分区p:打印当前分区表d:删除分区w:写入并退出
实际执行过程大致如下:
bash复制$ fdisk /dev/sdb
Command (m for help): g
Created a new GPT disklabel (GUID: XXX).
Command (m for help): n
Partition number (1-128, default 1): 1
First sector (2048-209715166, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-209715166, default 209715166): +50G
Created a new partition 1 of type 'Linux filesystem' and of size 50 GiB.
Command (m for help): p
Command (m for help): w
这里有三处值得展开讲的细节。
第一处,输入 g 之后,fdisk 会生成新的 GPT 分区表,这个过程会清空磁盘上原有的分区信息。如果你操作的不是一块全新空盘,请一定先确认上面的数据不需要保留。
第二处,分区起始扇区直接回车用了默认值 2048。现代分区工具默认从 2048 扇区开始,而不是最开头的扇区,这是为了给分区表本身、引导程序以及潜在的元数据区域留出空间。扇区对齐到 2048 的整数倍,也能让分区在 SSD 等现代存储设备上获得更好的性能表现。不建议为了省那几兆空间手动改小起始扇区。
第三处,分区的终止位置我用了 +50G 这种写法,含义是从起始扇区开始,向后分配 50GiB 的空间。fdisk 支持 K、M、G、T、P 这些后缀,直接写数字会按扇区数来算。你如果希望把整个剩余空间都分给这个区,直接回车默认值即可。
3.2 用 parted 创建分区表并完成分区
fdisk 的流程虽然直观,但遇到需要非交互式分区或者磁盘容量特别大的场景,parted 会更顺手。parted 的命令参数设计更接近自然语言,下面演示一个典型的完整流程:
bash复制# 在 /dev/sdc 上创建 GPT 分区表
parted /dev/sdc mklabel gpt
# 创建第一个分区,起始位置 0%,结束位置 50%
parted /dev/sdc mkpart primary 0% 50%
# 创建第二个分区,起始位置 50%,结束位置 100%
parted /dev/sdc mkpart primary 50% 100%
# 查看结果
parted /dev/sdc print
用百分比来定义分区边界是 parted 的典型用法,省去了手工计算扇区的麻烦。例如在 4TB 磁盘上,要分两个等大的区,直接 0% 50% 和 50% 100% 就可以,无需关心起始扇区编号是多少。
parted 的 mkpart 在 GPT 分区表下会接受 primary 这个参数吗?实际测试中,GPT 格式下分区没有主分区和逻辑分区之分,所以这里写不写 primary 影响不大,写上是习惯性动作,工具会忽略或兼容处理。
3.3 分区结果验证与常见报错分析
分区完成后,用下面的命令验证分区是否创建成功:
bash复制lsblk /dev/sdb
预期会看到类似下面的输出:
bash复制NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb 8:16 0 80G 0 disk
└─sdb1 8:17 0 50G 0 part
需要注意的是,分区表创建成功后,内核未必立刻识别到新分区。尤其是对一块正在使用的磁盘重新分区后,直接执行格式化可能会提示找不到设备。此时执行 partprobe /dev/sdb 让内核重新读取分区表即可:
bash复制partprobe /dev/sdb
提示:
partprobe是分区操作中最容易被忽略的一步,但恰恰是它决定了你新创建的分区能否马上被系统识别。虚拟化平台上尤其容易出现分区已创建但设备节点迟迟不出现的情况。
4. 格式化与文件系统选型:ext4、XFS 还是其他
分区完成后,分区本身只是磁盘上一块划好了边界的区域,操作系统还不能直接往里写文件。下一步是在分区上创建文件系统,也就是俗称的"格式化"。
文件系统决定了数据在磁盘上的组织方式,包括文件如何存储、元数据如何管理、空间不足时如何处理等等。选哪个文件系统,直接影响后续的性能表现和可维护性。
4.1 主流 Linux 文件系统的适用场景对比
| 文件系统 | 最大单文件 | 最大文件系统 | 日志机制 | 适合场景 |
|---|---|---|---|---|
| ext4 | 16TB | 1EB(实际受限于工具) | 支持,可关闭 | 通用场景,兼容性极好 |
| XFS | 8EB | 8EB | 支持,不可关闭 | 大文件、高并发写入、大数据 |
| Btrfs | 16EB | 16EB | 支持(CoW) | 快照、压缩、子卷等高级功能 |
| ZFS | 16EB | 256ZB | 支持(CoW) | 数据完整性要求极高的存储场景 |
结合使用场景做个简单排序:
- 如果你是日常折腾虚拟机、双系统,或者在普通服务器上做基础数据盘,ext4 是最稳妥、最不会出错的选择。
- 如果你的应用涉及海量小文件写入、大文件持续读写(比如文件服务器、数据库数据目录),XFS 的表现通常优于 ext4,而且 RHEL/CentOS 系发行版已经默认使用 XFS。
- 如果你追求快照、回滚、压缩等高级功能,且不介意文件系统本身更大的复杂度,可以考虑 Btrfs 或 ZFS。但这两者在生产环境中的运维门槛明显更高。
4.2 mkfs 系列命令的实操与调优
创建文件系统的命令是 mkfs 系列。格式化刚才创建的 /dev/sdb1 分区为 ext4:
bash复制mkfs.ext4 /dev/sdb1
如果要用 XFS:
bash复制mkfs.xfs /dev/sdb1
格式化过程会输出大量信息,最后提示文件系统创建成功。如果想在格式化的同时顺手设置卷标,便于后续识别:
bash复制mkfs.ext4 -L data_disk /dev/sdb1
卷标就相当于给这个文件系统起的名字,使用 blkid 或者 lsblk -f 可以查看。但这里要特别提醒:卷标并不是唯一、绝对的标识,同一台机器上卷标重复是可能发生的,所以生产环境方案中,我依然更推荐通过 UUID 来定位分区。
格式化时还有一个比较实际的问题:是否预留太多空间给 root 用户。ext4 文件系统默认会预留 5% 的空间,目的是防止文件系统被写满后 root 无法登录做维护。但对于动辄数 TB 的数据盘来说,5% 意味着浪费几十上百 GB,非常不划算。可以在格式化时手动调低预留比例:
bash复制# 磁盘按块计算,-m 0 表示不预留空间,但生产环境建议至少留 1%
mkfs.ext4 -m 1 /dev/sdb1
这一点很多教程不会提,但当你管理几十 TB 的存储服务器时,这个细节能省下不小的空间。
4.3 查看文件系统类型与 UUID
格式化的动作本身很快,完成后用这几个命令确认结果是常规动作:
bash复制# 查看块设备文件系统类型和 UUID
lsblk -f /dev/sdb1
# 更详细的文件系统信息
blkid /dev/sdb1
# 查看 ext4/xfs 详细参数
dumpe2fs -h /dev/sdb1 # ext4 专用
xfs_info /dev/sdb1 # XFS 专用
看一个真实的 lsblk -f 输出示例:
bash复制NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
sdb1 ext4 1.0 data_disk abcdef01-2345-6789-abcd-ef0123456789
UUID 一列就是后续挂载操作的"身份证号"。下一步进行挂载时,优先使用这个 UUID。
5. 挂载与永久挂载:mount 命令和 /etc/fstab 的完整逻辑
文件系统创建好之后,磁盘分区其实还是一个独立的存储单元。Linux 的目录树结构要求所有可用的存储必须挂载到某个目录下,用户才能通过目录路径正常访问其中的文件。这个"把文件系统关联到指定目录"的动作就叫挂载(mount)。
5.1 mount 命令的基本用法与挂载点目录规范
挂载操作很简单:
bash复制# 创建挂载点目录
mkdir -p /data
# 挂载分区到 /data
mount /dev/sdb1 /data
挂载之后验证一下:
bash复制df -h /data
输出会显示 /dev/sdb1 已经挂载在 /data,容量和已用空间都一目了然。
挂载点目录的命名和规划,是一个容易忽略但影响深远的细节。生产服务器上,我建议按用途来规划目录,例如:
/data:通用业务数据/data/mysql:数据库专用数据目录/data/backup:备份文件目录/home:如果用户多且用户数据量大,可以单独分一个大区挂载到这里
挂载点目录本身最好是空目录。如果往一个已有数据的目录上挂载新分区,挂载后原目录下的内容会被"遮蔽",等卸载挂载后才能重新看到原内容。这不是数据丢失,只是被临时隐藏了,但对不了解这个机制的新手来说,很容易误以为数据搞丢了。
5.2 /etc/fstab 的字段解析与实际配置
刚才用 mount 命令完成的挂载是临时挂载,只要系统重启就会消失,这正是这篇文章开头我提到的那次事故的原因。要实现"开机自动挂载",必须把挂载关系写入 /etc/fstab 文件。
用编辑器打开 /etc/fstab,文件内容的格式是六列,每列用空白分隔:
bash复制# <device> <mount-point> <filesystem-type> <options> <dump> <pass>
一个实际的生产配置示例:
bash复制UUID=abcdef01-2345-6789-abcd-ef0123456789 /data ext4 defaults 0 2
逐列解释:
- 第一列,设备来源,推荐写 UUID,而不是
/dev/sdb1。前面提到过,设备名可能变化,UUID 不会变。 - 第二列,挂载点目录,比如
/data。 - 第三列,文件系统类型,填写
ext4、xfs等,与格式化时选择的类型一致。 - 第四列,挂载选项。
defaults是常用默认值,实际对应rw, suid, dev, exec, auto, nouser, async等一组参数。 - 第五列,dump 备份标记。
0表示不备份,通常填 0。 - 第六列,开机自检顺序。根目录
/填 1,其他普通文件系统填 2,不需要自检的填 0。
拿到 UUID 的方式是:
bash复制blkid /dev/sdb1
把输出的 UUID 复制到配置文件里。修改完 /etc/fstab 之后,不要急着重启,先用下面的命令测试配置是否有误:
bash复制mount -a
这条命令会依据 /etc/fstab 重新挂载所有未挂载的文件系统。如果配置有误,会直接报错。确认无报错后,再用 df -h 查看是否挂载成功。
5.3 修改 fstab 引发的开机故障应急方案
/etc/fstab 配置错误是 Linux 服务器无法开机的常见原因之一。一旦写错了 UUID 或挂载选项,系统启动时可能会卡在 emergency mode,也就是紧急模式,要求管理员输密码进行交互式修复。
遇到这种情况不必慌张,修复思路是:
- 在紧急模式中输入 root 密码登录。
- 执行
cat /etc/fstab检查配置文件,确认哪一行有问题。 - 用
mount -o remount,rw /将根文件系统重新挂载为可读写模式(因为紧急模式下根文件系统通常是只读的)。 - 编辑
/etc/fstab注释或修正出错的行。 - 执行
reboot重启验证。
我个人每次修改完 /etc/fstab 后,都会养成立刻执行 mount -a 验证的习惯。经验告诉我,一条错误的 fstab 配置,可以让你在半夜被电话叫醒,然后花半小时处理一次本可以在一分钟之内避免的故障。
注意:紧急模式下的操作系统环境非常精简,有些常用命令可能不在 PATH 中。如果提示命令找不到,可以直接用绝对路径执行,例如
/usr/sbin/mount -o remount,rw /。
5.4 swap 分区(交换分区)的挂载逻辑
在 Linux 磁盘管理的话题下,不得不提 swap。Swap 是磁盘上划出的一块空间,在物理内存不足时作为内存的扩展使用。虽然现在的服务器内存容量普遍很大,但在某些特定场景下,swap 依然是系统稳定性的保障。
创建 swap 的完整流程如下:
bash复制# 1. 创建分区(可以用 fdisk 或 parted 完成)
# 2. 把分区标记为 swap 类型
fdisk /dev/sdb # 输入 t 修改分区类型,选择 Linux swap
# 3. 格式化 swap 文件系统
mkswap /dev/sdb2
# 4. 查看 swap 的 UUID
blkid /dev/sdb2
# 5. 启用 swap
swapon /dev/sdb2
# 6. 永久启用,在 /etc/fstab 中添加
UUID=<swap的UUID> swap swap defaults 0 0
验证 swap 是否生效:
bash复制free -h
输出中的 Swap 一行会显示总容量和已用容量。
6. 容量查看与日常排查:从 df 到 iostat
磁盘管理的另一大主题是日常监控与问题排查。故障往往不是瞬间发生的,而是有着明显的预警信号。能够读懂这些信号,是区分"会用 Linux"和"能管好 Linux"的分水岭。
6.1 df 与 du:容量视角的两个层次
查看文件系统整体容量使用情况,df 是首选:
bash复制df -h
-h 参数表示 human-readable,也就是以 G、M 这种方便阅读的单位显示。实际输出类似:
bash复制Filesystem Size Used Avail Use% Mounted on
/dev/sda2 40G 12G 27G 31% /
/dev/sdb1 50G 4.0G 43G 9% /data
这里的 Avail 列是当前用户实际可用的空间,不是 Size - Used。因为 ext4 文件系统默认预留了 5% 给 root,所以非 root 用户看到的可用空间会偏小一些。这就是前面格式化时建议调低预留比例的原因之一。
要看具体某个目录占了多少空间,需要用到 du:
bash复制# 查看当前目录下各子目录占用空间
du -sh *
# 查看指定目录占用空间
du -sh /data
du 在扫描大目录时可能比较慢,这是正常的。为了加快速度,可以限制扫描深度:
bash复制du -h --max-depth=1 /data
6.2 定位"磁盘满了但找不到大文件"的经典问题
实际运维中经常遇到一种情况:df -h 显示磁盘空间满了,但是 du 加起来的总和远小于磁盘总容量。这种矛盾怎么排查?
最常见的原因有两个:
第一个原因是已删除但仍被进程占用的文件。某些进程打开了一个大文件,然后这个文件被删除了,但进程没有释放文件句柄。此时该文件占用的磁盘空间既不会出现在 du 中,也无法正常回收。排查方式:
bash复制# 查找被删除但仍被占用的文件
lsof | grep deleted
找到对应的进程号后,重启或重启相关服务即可释放空间。
第二个原因是文件系统元数据(inode)被耗尽。磁盘空间可能还有剩余,但 inode 数量已经用完,无法再创建任何新文件。排查方式:
bash复制df -i
如果 IUse% 达到 100%,说明 inode 耗尽。这种情况常见于大量小文件堆积(比如缓存目录、邮件队列),需要清理无用小文件或调整 inode 数量。
6.3 iostat 与性能瓶颈的初步判断
磁盘性能问题在运维排查中也经常碰到。系统响应变慢,有可能是磁盘 I/O 达到了瓶颈。iostat 是 sysstat 软件包中的一个工具,专门用来查看设备 I/O 统计信息:
bash复制# CentOS/RHEL 安装
yum install -y sysstat
# Ubuntu/Debian 安装
apt install -y sysstat
# 每隔 2 秒刷新一次,共显示 3 次
iostat -x 2 3
重点关注几个指标:
%util:设备忙绿程度,接近 100% 说明磁盘已经接近饱和。await:平均 I/O 响应时间,机械盘通常在 10ms 上下,SSD 应低于 1ms。如果响应时间明显增加,需要考虑磁盘自身是否异常或负载是否过高。svctm:平均服务时间,如果远小于await,说明 I/O 请求在排队等待,队列本身是瓶颈。
iostat 只提供整体统计,要定位具体是哪个进程在大量读写磁盘,可以用 iotop:
bash复制iotop
这个工具和 top 命令类似,但专门展示各进程的 I/O 使用情况。定位到高 I/O 的进程后,再结合应用日志分析原因。
7. 扩展预告与常见错误速查
这篇文章作为系列第一篇,覆盖了 Linux 磁盘管理中从磁盘识别、分区、格式化、挂载到日常查询排查的完整基础链路。后续的文章会在此基础上展开对这些环节更深入的内容。
我在这篇文章的篇幅内,把几个最重要的基础操作和排错思路讲清楚了。系列后续内容包括:LVM 逻辑卷管理的完整实现、RAID 阵列的构建与故障替换、磁盘配额管理、系统盘数据盘分离的实践方案。这些都是围绕"磁盘管理"这个主题逐步深入的自然方向。
7.1 磁盘管理操作速查表
| 操作场景 | 相关命令 |
|---|---|
| 查看磁盘分区概览 | lsblk / lsblk -f |
| 查看文件系统容量 | df -h |
| 查看目录占用 | du -sh |
| 创建/修改分区表 | fdisk /dev/sdb 或 parted /dev/sdb |
| 内核重读分区表 | partprobe /dev/sdb |
| 格式化 ext4 | mkfs.ext4 /dev/sdb1 |
| 格式化 XFS | mkfs.xfs /dev/sdb1 |
| 查看 UUID | blkid |
| 临时挂载 | mount /dev/sdb1 /data |
| 永久挂载配置 | 编辑 /etc/fstab,执行 mount -a 测试 |
| 查看磁盘 I/O 性能 | iostat -x |
| 查找删除未释放文件 | lsof | grep deleted |
7.2 高频常见错误与解决方案对照
| 错误现象 | 可能原因 | 解决办法 |
|---|---|---|
mount: /dev/sdb1 is write-protected, mounting read-only |
文件系统有异常或存在写保护 | 检查磁盘是否只读挂载,重启或修复文件系统 |
wrong fs type, bad option, bad superblock on /dev/sdb1 |
文件系统类型填错,或分区上根本没有文件系统 | 检查 /etc/fstab 第三列,用 blkid 确认真实类型 |
/dev/sdb1: No such file or directory |
分区不存在或未重读分区表 | 执行 partprobe,检查分区是否创建成功 |
No space left on device |
磁盘空间或 inode 不足 | df -h 与 df -i 双查,清理无用文件 |
fsck.ext4: Unable to resolve 'UUID=...' |
/etc/fstab 中的 UUID 不存在 |
用 blkid 确认正确 UUID 并修正配置 |
7.3 几条实在的运维体会
文章最后,分享几条这些年实际管服务器攒下的经验。这些不是从任何一本教科书上抄来的,而是经历了真实故障之后总结出来的:
第一,任何分区、格式化、fstab 修改操作之前,先执行 lsblk、blkid、df -h 把当前状态记录下来。大多数灾难性误操作,都源于对当前环境状态不够清楚。
第二,操作生产服务器时,先把 mount -o remount,ro 这类只读保护性操作想明白再动手。修改 fstab 之后别急着重启,mount -a 能提前拦住大部分错误。
第三,新盘上线前,把 UUID、挂载点、用途、格式化时间记到一个简单文档里。服务器数量一多,"这块盘是干什么的"这个问题会成为维护中最大的隐性成本。
第四,遇到任何与"空间"相关的告警,先分清楚是空间不足还是 inode 不足,两者的处理手段截然不同。只盯着 df -h 看而忽略 df -i,会在排查路上浪费很多时间。
磁盘管理是一个需要动手验证的领域,光看不练很难真正掌握。强烈建议用虚拟机新建一块虚拟磁盘,按照这篇文章的流程完整走一遍:分区、格式化、挂载、写 fstab、重启验证。等这一步熟练之后,再尝试玩坏一块测试盘然后修复它,你会发现自己对 Linux 磁盘管理的理解会产生质的变化。下一篇系列内容里,我们详细聊聊 LVM 的逻辑——它能让磁盘管理从"静态固定"变成"动态伸缩",这是生产环境中更常见、更实用的能力。
