第13章:磁盘管理入门

第十三章:磁盘管理入门

13.1 磁盘分区概念:为什么要分区?

想象一下:你买了一个巨大的仓库(硬盘),但是不分隔间就直接往里塞东西…找东西的时候怎么办?把整个仓库翻个底朝天?

分区就是把一个大硬盘分成多个"隔间",每个隔间可以放不同的东西,有不同的"规则"!

为什么要分区?

graph TD
    A["一块大硬盘"] --> B["不分区的硬盘"]
    A --> C["分区的硬盘"]
    
    B --> D["所有数据混在一起"]
    D --> E["系统文件和应用混在一起"]
    E --> F["重装系统?数据全丢!"]
    
    C --> G["系统区:/"]
    C --> H["家目录区:/home"]
    C --> I["数据区:/data"]
    C --> J["交换区:swap"]
    
    G --> K["重装系统只格式化 /"]
    H --> K
    K --> L["/home 和 /data 不受影响!"]

分区的好处

好处说明
数据安全系统坏了,只丢系统区
重装方便重装系统不动用户数据
性能优化不同分区用不同文件系统
隔离日志日志爆了,不影响其他分区
多系统启动一块硬盘装多个系统

打个比方:分区就像给你的房子分房间——厨房、卧室、卫生间各司其职。厨房发大水了,不会把你卧室淹了!


13.2 MBR 分区表:传统分区方式(最大 2TB)

MBR = Master Boot Record,主引导记录。这是早期的分区方式,1983年诞生,统治了 PC 领域几十年!

MBR 的限制

1
2
3
4
5
# MBR 的硬伤:
# 1. 单个分区最大 2TiB(按 512 字节扇区、32 位扇区号计算)
#    超过 2TiB 的空间没法寻址——这正是大硬盘必须改用 GPT 的根本原因
# 2. 最多只能有 4 个主分区!
#    想分更多?必须用"扩展分区"套"逻辑分区"!

MBR 就像老式邮政编码,只能编码有限的地址!

13.2.1 主分区:最多 4 个

主分区是"正式的分区",可以安装操作系统!

1
2
3
4
5
# 主分区特点:
# - 最多 4 个(这是 MBR 的硬限制!)
# - 可以安装操作系统
# - 可以设置为启动分区
# - 可以格式化

13.2.2 扩展分区

扩展分区是 MBR 的"变通方案"——当你想分超过4个区时!

1
2
3
4
# 扩展分区特点:
# - 最多 1 个(所以主分区+扩展分区 ≤ 4)
# - 不能直接使用,只是"容器"
# - 里面可以划分多个"逻辑分区"

13.2.3 逻辑分区

逻辑分区是从扩展分区里"划分"出来的分区!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# MBR 分区布局示例:
# /dev/sda
# ├── /dev/sda1  (主分区)  50GB   # 安装 Windows
# ├── /dev/sda2  (主分区) 100GB   # 安装 Linux
# ├── /dev/sda3  (扩展分区) 剩余空间
# │   ├── /dev/sda5  (逻辑分区)  200GB  # /home
# │   ├── /dev/sda6  (逻辑分区)   50GB  # swap
# └── (扩展分区本身不能使用)

# 注意:扩展分区自己占用一个编号(这里是 sda3),但它只是"容器"、不能直接存数据;
# 逻辑分区从 5 号开始编号,因为 1~4 号要留给主分区和扩展分区。

小技巧:主分区是"独立房间",逻辑分区是"合租房里的隔间"!


13.3 GPT 分区表:现代分区方式(UEFI,无限制)

GPT = GUID Partition Table,GUID 分区表。这是现代硬盘的"标配"!

GPT 的优势

1
2
3
4
5
6
# GPT 的优势:
# 1. 最大支持 9.4ZB(是的,ZB!约等于无限)
# 2. 分区数量上限很高:Windows 限定 128 个;Linux 内核默认每块盘 256 个(sda1~sda256)
# 3. 自带备份(分区表在硬盘头尾各存一份)
# 4. CRC 校验(数据损坏能检测出来)
# 5. 64位磁盘序列号(唯一标识)

GPT 就像现代邮政编码系统,能编码几乎无限的地址!

GPT vs MBR

特性MBRGPT
最大硬盘2TB9.4ZB
最大分区数4(3 主 + 1 扩展)+扩展内的逻辑分区128(Windows)/ 256(Linux 内核默认)
启动方式BIOSUEFI
分区表备份无硬盘头尾各一份
数据校验无CRC 校验

现代电脑(2010年后)基本都支持 UEFI + GPT!如果你的电脑还在用 MBR,是时候升级了!


13.4 fdisk 分区工具

fdisk 是 Linux 最经典的分区工具。

1
2
3
4
5
6
7
# 老教材常说"fdisk 只支持 MBR",这句话已经过时了:
# util-linux 2.38(2022 年)之后,fdisk 已经能处理 GPT——
# 进入交互界面后按 g 可新建 GPT 分区表,按 o 可新建 MBR(DOS)分区表。
#
# 怎么确认你手上的 fdisk 支不支持 GPT?看版本号:
fdisk --version
# fdisk from util-linux 2.39.3    ← 2.38 及以上都支持

不过在真正的运维场景里,GPT 的首选工具仍然是 gdisk 或 parted:gdisk 对 GPT 的支持最完整(能修复分区表、能改分区类型 GUID),parted 更适合被脚本调用。fdisk 的优势是操作直观、提示清晰,适合快速在 MBR 磁盘上切几个分区。

13.4.1 fdisk -l:列出分区

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 列出所有磁盘的分区
sudo fdisk -l

# 输出示例:
# Disk /dev/sda: 500 GB, 500107862016 bytes, 976773168 sectors
# Units = sectors of 1 * 512 = 512 bytes
# Sector size (logical/physical): 512 bytes / 4096 bytes
# I/O size (minimum/optimal): 4096 bytes / 4096 bytes
# Disk label type: dos
# Disk identifier: 0x00012345
#
# Device      Boot   Start      End         Blocks     Id   System
# /dev/sda1  *      2048      1024000     512000     83   Linux
# /dev/sda2         1024001   500000000   250000000  83   Linux

13.4.2 fdisk /dev/sdb:交互式分区

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# 开始分区(交互式)
sudo fdisk /dev/sdb

# fdisk 交互命令:
# Command action
#    a   toggle a bootable flag
#    b   edit bsd disklabel
#    c   toggle the dos compatibility flag
#    d   delete a partition         # 删除分区
#    l   list known partition types # 列出分区类型
#    m   print this menu            # 显示帮助
#    n   add a new partition         # 新建分区
#    o   create a new empty DOS partition table
#    p   print the partition table   # 显示分区表
#    q   quit without saving changes # 不保存退出
#    s   create a new empty Sun disklabel
#    t   change a partition's system id
#    u   change display/entry units
#    v   verify the partition table
#    w   write table to disk and exit # 保存退出

13.4.3 n:新建分区

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# fdisk 交互示例:创建一个 10GB 的分区

Command (m for help): n
Partition type:
   p   primary (3 primary, 0 extended, 1 free)
   e   extended
Select (default p): p
Partition number (1-4, default 3): 3
First sector (2048-500000000, default 2048): <直接回车使用默认值>
Last sector, +sectors or +size{K,M,G} (2048-500000000, default 500000000): +10G

Command (m for help): p
# Device      Boot   Start      End         Blocks     Id   System
# /dev/sdb3          2048    20971520    10485248   83   Linux

💡 小技巧:起始扇区直接按回车使用默认值即可,通常不需要手动指定。结束位置可以用 +10G 这样的格式指定大小,比计算扇区数方便多了!

13.4.4 p:主分区

1
2
3
4
5
6
7
8
9
# 新建主分区
Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1): 1
# 输入分区大小
Last sector...: +50G

💡 提示:如果已经有分区,fdisk会显示当前分区数量,分区编号需要选择未被使用的。

13.4.5 e:扩展分区

1
2
3
4
5
6
7
8
9
# 新建扩展分区
Command (m for help): n
Partition type:
   p   primary (2 primary, 0 extended, 2 free)
   e   extended
Select (default p): e
Partition number (1-4, default 3): 3
# 指定大小为剩余全部空间
Last sector...: +200G

⚠️ 注意:扩展分区本身不能使用,需要在其中创建逻辑分区!

13.4.6 l:逻辑分区

1
2
3
4
5
6
7
# 在扩展分区内创建逻辑分区
Command (m for help): n
# 如果已有扩展分区,fdisk会自动提示创建逻辑分区
Select (default p): l
# 逻辑分区自动分配编号(从5开始,1-4保留给主分区/扩展分区)
# 输入分区大小
Last sector...: +100G

💡 逻辑分区编号规则:

  • 1-4:保留给主分区和扩展分区
  • 5+:逻辑分区(从5开始)
  • 例如:/dev/sda5, /dev/sda6, /dev/sda7…

13.4.7 w:保存退出

1
2
3
4
5
# 保存并退出
Command (m for help): w
# The partition table has been altered!
# Calling ioctl() to re-read partition table.
# Syncing disks.

重要:修改完分区后,需要重新读取分区表!使用 partprobe 或重启系统!


13.5 gdisk 分区工具:GPT 分区

gdisk = GPT disk,专门用于 GPT 分区的工具!用法和 fdisk 几乎一样!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 安装 gdisk(Ubuntu)
sudo apt install gdisk

# 列出 GPT 分区
sudo gdisk -l /dev/sda

# 开始分区
sudo gdisk /dev/sdb

# gdisk 交互命令(和 fdisk 类似):
# Command: n (new partition)
# Command: p (print partition table)
# Command: d (delete partition)
# Command: w (write and quit)
# Command: q (quit without saving)

gdisk 支持 GPT,但没有 MBR 那套主/逻辑分区的概念——所有分区地位平等。GPT 分区表本身为 128 个条目预留了空间,所以常见上限是 128 个(Linux 内核默认每块盘最多 256 个)。


13.6 parted 分区工具:交互式分区

parted 是一个"全能选手",同时支持 MBR 和 GPT!

13.6.1 parted /dev/sdb

1
2
3
4
5
# 启动 parted(交互式)
sudo parted /dev/sdb

# parted 提示符:
# (parted)

13.6.2 mklabel gpt

1
2
3
4
5
6
7
8
9
# 创建分区表
(parted) mklabel gpt
# Warning: The existing disk label on /dev/sdb will be destroyed and all data on this disk will be lost.
# Do you want to continue?
# Yes/No? Yes

# 分区表类型:
# msdos   # MBR
# gpt     # GPT

13.6.3 mkpart

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 创建分区
(parted) mkpart
# Partition name?  []? data
# File system type?  [ext2]? ext4
# Start? 1MB
# End? 100GB

# 查看分区
(parted) print
# Model: VMware Virtual Disk (scsi)
# Disk /dev/sdb: 500GB
# Sector size (logical/physical): 512B/512B
# Partition Table: gpt
#
# Number  Start   End     Size    File system  Name   Flags
#  1      1049kB 100GB   100GB   ext4        data
1
2
3
4
5
6
7
# parted 常用命令:
# (parted) help              # 显示帮助
# (parted) print             # 显示分区表
# (parted) mklabel gpt      # 创建分区表
# (parted) mkpart           # 创建分区
# (parted) rm 1             # 删除分区 1
# (parted) quit             # 退出

13.7 mkfs 格式化

mkfs = make filesystem,格式化!创建文件系统!

1
2
3
4
# mkfs 只是"前端",实际调用具体工具:
# mkfs.ext4  → 格式化 ext4
# mkfs.xfs   → 格式化 XFS
# mkfs.vfat  → 格式化 FAT32(U 盘)

13.7.1 mkfs.ext4 /dev/sdb1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 格式化为 ext4
sudo mkfs.ext4 /dev/sdb1

# 输出:
# mke2fs 1.45.6 (20-Mar-2020)
# Discarding device blocks: done
# Creating filesystem with 262144 4k blocks and 65536 inodes
# Filesystem UUID: a1b2c3d4-e5f6-7890-abcd-ef1234567890
# Superblock backups stored on blocks:
#     32768, 98304, 163840, 229376, 294912
# Allocating group tables: done
# Writing inode tables: done
# Creating journal (4096 blocks): done
# Writing superblocks and filesystem accounting information: done

13.7.2 mkfs.xfs /dev/sdb1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 格式化为 XFS
sudo mkfs.xfs /dev/sdb1

# 输出(xfsprogs 6.x 的典型输出,字段按列对齐):
# meta-data=/dev/sdb1              isize=512    agcount=4, agsize=655360 blks
#          =                       sectsz=512   attr=2, projid32bit=1
#          =                       crc=1        finobt=1, sparse=1, rmapbt=1
#          =                       reflink=1    bigtime=1 inobtcount=1 nrext64=1
# data     =                       bsize=4096   blocks=2621440, imaxpct=25
#          =                       sunit=0      swidth=0 blks
# naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
# log      =internal log           bsize=4096   blocks=16384, version=2
#          =                       sectsz=512   sunit=0 blks, lazy-count=1
# realtime =none                   extsz=4096   blocks=0, rtextents=0

注意这里出现的都是真实存在的字段(rmapbt、reflink、bigtime、inobtcount 等)。像 unreclaim=1、nodinodeq=on、nobrowse 这种"看起来很专业"的词,在任何版本的 mkfs.xfs 里都不存在——那是凭空编出来的输出。

13.7.3 mkfs.btrfs /dev/sdb1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# 格式化为 Btrfs
sudo mkfs.btrfs /dev/sdb1

# 输出(btrfs-progs 6.x 的典型输出):
# btrfs-progs v6.6.3
# See https://btrfs.readthedocs.io for more information.
#
# Label:              (null)
# UUID:               8f3c1e60-1a2b-4c3d-9e8f-0123456789ab
# Node size:          16384
# Sector size:        4096
# Filesystem size:    100.00GiB
# Block group profiles:
#   Data:             single            8.00MiB
#   Metadata:         DUP             256.00MiB
#   System:           DUP               8.00MiB
# SSD detected:       no
# Devices:
#    ID        SIZE      PATH
#     1     100.00GiB  /dev/sdb1

顺便指出一个"假字段":上面旧版本里的 UBIQUITY: - 在 mkfs.btrfs 的任何真实输出里都不存在,是编造出来的。学习命令输出时,字段名对不上就是提醒信号——不要照着背,最好自己跑一遍对照。

13.7.4 -L 指定卷标

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 指定卷标(就像给硬盘起名字)
sudo mkfs.ext4 -L "MyData" /dev/sdb1

# 查看卷标
sudo e2label /dev/sdb1
# MyData

# 查看所有磁盘的 UUID 和卷标
sudo blkid
# /dev/sdb1: LABEL="MyData" UUID="a1b2c3d4-e5f6-7890-abcd-ef1234567890" TYPE="ext4"

13.8 mount 挂载

mount 是"挂载"命令,把分区/硬盘连接到目录!

为什么需要挂载?因为 Linux 所有文件都在一个树形结构里。新硬盘不挂载,就无法访问!

13.8.1 mount /dev/sdb1 /mnt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 基本挂载
sudo mount /dev/sdb1 /mnt

# 查看挂载
df -h /mnt
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/sdb1       99G   60M   94G   1% /mnt

# 查看所有挂载
mount

13.8.2 mount -o ro:只读挂载

1
2
3
4
5
# 只读挂载(不能写入)
sudo mount -o ro /dev/sdb1 /mnt

# 重新挂载为读写:已经在挂载中的文件系统,必须用 remount
sudo mount -o remount,rw /mnt

⚠️ 这里有个高频错误:设备已经被挂载时,mount -o rw /dev/sdb1 /mnt 不会"改成读写",它会直接报错(already mounted or mount point busy)。想改现有挂载的选项,一律走 remount,并且只需要给挂载点:

1
2
3
sudo mount -o remount,rw /mnt            # 改回读写
sudo mount -o remount,ro /mnt            # 改成只读(救援时常用)
sudo mount -o remount,noexec /mnt        # 追加/修改选项

系统救援时最经典的一句就是 mount -o remount,rw / ——根文件系统默认可能是只读的,改任何配置文件之前得先把它挂成可写。

13.8.3 mount -t ext4:指定类型

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 指定文件系统类型(通常不需要,mount 会自动检测)
sudo mount -t ext4 /dev/sdb1 /mnt

# 常用挂载选项:
# ro            # 只读
# rw            # 读写
# noexec        # 禁止执行程序
# nosuid        # 忽略 suid 位
# nodev         # 不解释字符/块设备
# noatime       # 不更新访问时间
# relatime      # 相对 atime 更新
# defaults      # 默认选项(rw, suid, dev, exec, auto, nouser, async)

# 组合使用
sudo mount -o noexec,nosuid,nodev /dev/sdb1 /mnt

13.9 umount 卸载

umount 是"卸载"命令,解除挂载关系!

13.9.1 umount /mnt

1
2
3
4
5
# 通过挂载点卸载
sudo umount /mnt

# 通过设备卸载
sudo umount /dev/sdb1

13.9.2 umount /dev/sdb1

1
2
3
4
5
# 通过设备名卸载
sudo umount /dev/sdb1

# 如果设备正在使用,会报错:
# umount: /mnt: target is busy.

13.9.3 umount -l:懒卸载(不是"强制")

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# -l = lazy,懒卸载
# 立即断开文件系统,但延迟清理(等所有进程释放后)
sudo umount -l /mnt

# -f = force,强制卸载(主要用于NFS等网络文件系统)
# 本地文件系统强制卸载可能导致数据损坏!
sudo umount -f /mnt

# 查看谁在使用这个挂载点
sudo lsof +D /mnt
# 或
sudo fuser -v /mnt

# 终止占用进程后重试
sudo fuser -k /mnt
sudo umount /mnt

小技巧:卸载前先切换到其他目录!

1
2
cd ~
sudo umount /mnt

⚠️ 警告:强制卸载可能导致数据损坏!尽量先关闭占用文件,而不是强制卸载。


13.10 /etc/fstab 自动挂载配置

/etc/fstab 定义了开机时自动挂载的文件系统!

13.10.1 格式:设备 挂载点 类型 选项 转储 检查

1
2
3
4
5
6
# /etc/fstab 格式:
# <file system>   <mount point>   <type>   <options>       <dump>  <pass>
# 设备             挂载点           类型      选项            转储    检查

# 示例:
UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890  /data  ext4  defaults  0  2
字段说明
file system设备名、UUID 或 LABEL
mount point挂载点(交换分区用 none)
type文件系统类型
options挂载选项(defaults, nofail 等)
dump是否备份(0=否, 1=是)
passfsck 检查顺序(0=不检查, 1=先检查根, 2=后检查)

13.10.2 UUID 方式挂载

1
2
3
4
5
6
7
8
9
# 查看 UUID
sudo blkid

# /dev/sda1: UUID="xxxx-xxxx" TYPE="vfat"
# /dev/sda2: UUID="a1b2c3d4-..." TYPE="ext4"

# 使用 UUID 挂载(推荐!)
# /etc/fstab 配置:
UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890  /data  ext4  defaults  0  2

为什么用 UUID?因为设备名(/dev/sda)可能会变!UUID 是固定的!

13.10.3 LABEL 方式挂载

1
2
3
# 使用卷标挂载
# /etc/fstab 配置:
LABEL=MyData  /data  ext4  defaults  0  2

常用 fstab 配置示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# /etc/fstab

# 根分区
UUID=root-uuid  /               ext4    errors=remount-ro  0  1

# 交换分区
UUID=swap-uuid  none            swap    sw                0  0

# 数据分区
UUID=data-uuid  /data          ext4    defaults          0  2

# Windows NTFS 分区
UUID=windows-uuid  /mnt/windows ntfs-3g defaults,uid=1000,gid=1000  0  0

# NFS 网络挂载
192.168.1.100:/nfs/share  /nfs  nfs  defaults  0  0

# CIFS/SMB 共享
//192.168.1.100/share  /smb  cifs  username=user,password=pass  0  0

🚨 上面最后一行是个反面教材,不要照抄:把 password=pass 明文写在 /etc/fstab 里,等于把凭据摆在全局可读的位置。正确做法是单独建一个 600 权限的凭据文件:

1
2
3
4
5
6
7
8
9
# 1. 建凭据文件(只有 root 能读)
sudo install -m 600 /dev/null /etc/cifs-cred
sudo tee /etc/cifs-cred >/dev/null <<'EOF'
username=user
password=你的密码
EOF

# 2. fstab 里只引用这个文件
//192.168.1.100/share  /smb  cifs  credentials=/etc/cifs-cred,uid=1000,gid=1000,noauto,nofail  0  0

测试 fstab 配置:

1
2
sudo mount -a
# 如果没有报错,说明配置正确!

⚠️ 动 fstab 之前务必知道的两件事:

  1. 写错 fstab 可能导致系统起不来。系统每次开机都会读它,一行写坏就可能停在紧急模式。改完一定要先 sudo mount -a 验证,再考虑重启。
  2. 非关键分区(U 盘、NFS、云盘)记得加 nofail:不加的话,只要那块盘没插上或网络存储连不上,启动过程就会卡住甚至失败。加 nofail 表示"挂不上就算了,照常启动"。
  3. 想在图形界面里"点一下才挂载",加 noauto;配合 x-systemd.automount 还能做到"首次访问时自动挂载",这对网络存储特别友好。

13.11 UUID 和 LABEL:稳定的设备标识

设备名(/dev/sda)会变,但 UUID 和 LABEL 是稳定的!

13.11.1 blkid:查看 UUID

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 查看所有磁盘的 UUID 和类型
sudo blkid

# 输出:
# /dev/sda1: UUID="xxxx-xxxx" TYPE="vfat" PARTUUID="yyyy-yyyy"
# /dev/sda2: UUID="a1b2c3d4-e5f6-7890-abcd-ef1234567890" TYPE="ext4" PARTUUID="zzzz-zzzz"

# 查看特定设备
sudo blkid /dev/sdb1
# /dev/sdb1: UUID="a1b2c3d4-e5f6-7890-abcd-ef1234567890" TYPE="ext4"

13.11.2 e2label:设置卷标

1
2
3
4
5
6
7
8
9
# 设置 ext4 卷标
sudo e2label /dev/sdb1 "MyData"

# 查看卷标
sudo e2label /dev/sdb1
# MyData

# 设置 XFS 卷标
sudo xfs_admin -L "MyXFSData" /dev/sdb1

13.12 df 查看磁盘使用情况

df = disk free,磁盘剩余空间!

13.12.1 df -h:人性化显示

1
2
3
4
5
6
7
8
9
# -h = human-readable,人类可读
df -h

# 输出:
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/sda2       100G   40G   60G  40% /
# /dev/sda1       500M  100M  400M  20% /boot
# /dev/sdb1       200G   80G  120G  40% /data
# tmpfs           2.0G     0  2.0G   0% /dev/shm

13.12.2 df -T:显示文件系统类型

1
2
3
4
5
6
7
8
# -T = type,显示文件系统类型
df -hT

# 输出:
# Filesystem     Type      Size  Used Avail Use% Mounted on
# /dev/sda2     ext4      100G   40G   60G  40% /
# tmpfs          tmpfs     2.0G     0  2.0G   0% /dev/shm
# /dev/sdb1      xfs       200G   80G  120G  40% /data

13.12.3 df -i:显示 inode

1
2
3
4
5
6
7
# -i = inode,显示 inode 使用情况
df -i

# 输出:
# Filesystem      Inodes  IUsed  IFree IUse% Mounted on
# /dev/sda2     3932160  123456 3808704   4% /
# /dev/sdb1     1966080   78910 1887170   5% /data

如果 inode 满了,即使磁盘还有空间,也无法创建新文件!


13.13 du 查看目录大小

du = disk usage,磁盘使用情况!

13.13.1 du -sh 目录:总大小

1
2
3
4
5
6
# -s = summarize,总计
# -h = human-readable
du -sh /var/log

# 输出:
# 1.2G    /var/log

13.13.2 du -h –max-depth=1:子目录大小

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# --max-depth=1,只显示一级子目录
du -h --max-depth=1 /var

# 输出:
# 500M    /var/cache
# 1.2G    /var/log
# 50G     /var/www
# 200M    /var/lib
# ...

# 排序显示(最大的在前面)
du -h --max-depth=1 /var | sort -rh

常用 du 命令

1
2
3
4
5
6
7
8
# 查看当前目录各子目录大小
du -h --max-depth=1

# 查找最大的 10 个文件/目录
du -ah /home | sort -rh | head -10

# 排除某些目录
du -sh --exclude='*.log' /var/log

13.14 磁盘配额管理:quota

磁盘配额可以限制用户或组使用的磁盘空间!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 安装 quota
sudo apt install quota

# 1. 在 /etc/fstab 中启用配额
# /etc/fstab
UUID=xxxx  /data  ext4  defaults,usrquota,grpquota  0  2

# 2. 让新的挂载选项生效(不需要先 umount!)
sudo mount -o remount /data

# 3. 初始化配额数据库
sudo quotacheck -cum /data

# 4. 启用配额
sudo quotaon /data

# 5. 设置用户配额
sudo edquota username
# 编辑器里看到的是"以 KB 为单位"的纯数字,没有 M/G 这类单位:
# Disk quotas for user username (uid 1000):
#   Filesystem                   blocks    soft    hard    inodes    soft    hard
#   /dev/sdb1                  1048576 2097152 3145728         0       0       0
#                              ↑当前用量 ↑软限制  ↑硬限制(单位都是 KB)
#                               0KB     2GB     3GB

# 6. 查看配额
sudo quota username

# 7. 以人类可读的单位查看(-s = human readable,把 KB 换算成 M/G)
sudo quota -s username

⚠️ 这里有两个初学者最容易翻车的点:

  1. blocks、soft、hard 三列的单位是 KB(1024 字节),直接填数字,不写单位。写 100M 会被当成"100 个 KB",限额小得可怜。
  2. 第 2 步不要先 umount。老资料里常写"卸载再挂载",其实只需要 mount -o remount /data 让 usrquota,grpquota 生效;先 umount 反而会打断正在用这块盘的程序。
1
2
3
4
5
6
7
8
# 配额命令总结:
# quotacheck    # 扫描文件系统,创建配额数据库
# quotaon       # 启用配额
# quotaoff      # 禁用配额
# edquota       # 编辑用户配额
# edquota -g    # 编辑组配额
# quota         # 查看用户配额
# repquota      # 查看所有用户的配额状态

配额设置说明:

  • soft limit:软限制。到达后会开始计时,在宽限期(默认 7 天)内还能继续写入,系统会给出警告。
  • hard limit:硬限制。任何时候都不能超过,写入会直接失败(Disk quota exceeded)。
  • 宽限期(grace period):只在超过 soft limit 后开始倒计时。宽限期内把用量降回 soft limit 以下,计时会重置;硬扛到期后,soft limit 就会"变成"硬限制。
  • 别忘了改完配额还要 repquota -a 复核一下全盘的用户用量,光看 edquota 是看不到"谁已经超额"的。

本章小结

本章我们学习了 Linux 磁盘管理的基础知识!

核心知识点:

  1. 分区概念:分区把大硬盘分成多个"隔间",便于管理和备份。

  2. MBR vs GPT:

    • MBR:老式,最大 2TB,最多 4 个主分区
    • GPT:现代,支持 9.4ZB,常见上限 128 个分区(Windows)
  3. 分区工具:

    • fdisk:经典工具,老版本只支持 MBR,util-linux 2.38+ 已支持 GPT
    • gdisk:GPT 分区
    • parted:全能选手(MBR 和 GPT 都能用)
  4. 文件系统创建(mkfs):

    • mkfs.ext4:ext4 文件系统
    • mkfs.xfs:XFS 文件系统
    • mkfs.btrfs:Btrfs 文件系统
  5. 挂载(mount/umount):

    • 挂载点必须是已存在的目录
    • 卸载前确保没有程序在使用
  6. /etc/fstab 自动挂载:

    • 使用 UUID 比设备名更稳定
    • 修改后用 mount -a 测试
  7. UUID 和 LABEL:

    • blkid 查看 UUID
    • e2label 设置卷标
  8. 磁盘使用情况:

    • df:查看文件系统使用
    • du:查看目录大小
  9. 磁盘配额:限制用户/组的磁盘使用量。

下一章我们将学习 链接文件,深入理解硬链接和软链接!敬请期待!

最后修改 September 19, 2026: 更新 (3489033b1)