Skip to content

Linux 文件管理系统

文件系统是一种组织和管理数据的方法,它提供文件与目录的命名空间,以及一套统一的接口,让用户无需关心数据在底层存储设备上的具体位置与存取方式。它的底层可以是磁盘,也可以是其他动态生成的数据,如网络或内存。

常见文件系统

  1. 磁盘文件系统

    • Ext4:现代 Linux 默认文件系统(其前代 Ext2/Ext3 基本用于兼容场景)。
    • XFS:高性能、支持大文件,企业常用。
    • ZFS:集成了传统文件系统与卷管理,支持数据完整性校验、快照、克隆、压缩等功能。
    • NTFS: Windows 主流文件系统,也可用在移动存储设备上,在 Linux 中可使用 ntfs-3g 访问。
    • FAT16 / FAT32 / exFAT:常见于移动存储设备(如 U 盘、SD 卡),跨平台兼容性好。

    • ISO9660 / UDF:只读光盘文件系统,也用于系统镜像。

    • SquashFS:只读压缩文件系统,支持多种压缩算法,常用于嵌入式系统作为根文件系统,或者用于软件打包、文件备份归档。
  2. 网络文件系统

    • NFS:网络文件系统,用于局域网环境的分布式文件共享。
  3. 虚拟文件系统

    • /proc:提供进程和内核状态信息接口

    • /sys(sysfs):提供设备和内核对象接口

    • tmpfs:临时文件系统,用于快速存储和临时挂载

    • cgroupfs:一般挂载在 /sys/fs/cgroup,是资源控制组接口

  4. 其他

    • swap:交换空间,可将不活跃的内存页换出到磁盘(不是严格意义上的文件系统)。
    • OverlayFS:分层文件系统,容器常用。

Linux 识别硬盘设备和分区

Linux 启动时,内核会通过硬盘驱动识别存储设备(如 SATA、SCSI、NVMe 等),并读取分区表以了解分区布局。用户可通过 lsblk 命令或者 fdisk -l 了解系统磁盘分区信息。

现代硬盘分区主要使用 GPT(GUID Partition Table),可支持大量主分区(数百上千个),提供 CRC 校验,与 UEFI 启动兼容。历史上,旧的 BIOS 系统则使用 MBR(Master Boot Record)分区,最多只支持 4 个主分区,超出需要使用扩展分区,仅在老旧硬件或兼容性场景使用。

分区目的包括:

  1. 方便管理:将系统文件、用户数据、日志文件分开。
  2. 提高系统效率:合理分区可减少碎片,提高 I/O。
  3. 磁盘配额:限制用户或组的磁盘使用量。
  4. 备份和恢复:便于单独备份系统或数据。
  5. 安全性:不同分区可以设置不同的挂载选项以及 ACL 访问控制权限。

文件系统与磁盘状态查看工具

Linux 提供了多种命令用于查看磁盘、分区和文件系统的状态,从空间占用到文件系统元数据都可以监控和分析。

常见工具

  1. df 命令可用于查看挂载文件系统的使用情况。常见参数有:

    • -h:习惯单位(K/M/G)。

    • -a:显示所有文件系统,包括虚拟文件系统。

    • -T:显示文件系统类型,如 ext4、xfs、tmpfs 等。

  2. du 命令可查看目录所占用的空间。常见参数有:

    • -h:习惯单位。
    • --max-depth=1:只展开一层子目录,默认全展开。
    • -s:只统计总占用。
  3. lsblk 查看块设备和及其文件系统信息(包括未挂载)。可查看块设备名、大小、挂载点等信息。添加 -f 参数还可查看文件系统类型、UUID 等信息。
  4. findmnt 查看已挂载的文件系统及挂载点(包括虚拟文件系统)。可查看挂载点、源设备、文件系统类型、挂载选项。
  5. `fdisk -l 查看所有磁盘和分区的低级信息(包括未挂载)。可查看分区表类型、分区起止扇区、大小、分区类型、UUID 等信息。需要 root 权限。

查看 EXT 文件系统详细信息

Linux 提供了一些工具用于查看 ext2/ext3/ext4 文件系统的详细信息:

  1. dumpe2fs

    dumpe2fs [-h] <device>
    
    • 查看指定分区或设备上的 ext 文件系统详细信息。

    • -h 选项只显示 超级块(superblock)信息

  2. tune2fs

    tune2fs -l <device>
    
    • 输出信息与 dumpe2fs 类似,但格式更易读,常用于查看系统或分区状态。

注:这些工具仅适用于 ext2/ext3/ext4 文件系统,其他文件系统(如 XFS、Btrfs)需要使用相应工具,如 xfs_infobtrfs filesystem show

Linux 设备文件

Linux 系统中,一切都是文件,设备也不例外。设备文件是内核访问设备的接口,而 /dev 是设备文件所在目录,Linux 通过它与设备硬件进行交互。当内核检测到硬件时,会触发 udev(用户空间设备管理器)创建对应的 /dev 设备文件。

设备文件的设备文件名是方便用户记忆的标签(如 /dev/sda)。而每个设备文件具有自己的主设备号(major number)次设备号(minor number),主设备号告诉内核应该用哪个驱动程序管理设备,而次设备号用于区分同一类设备下的具体实例,内核通过这两个设备号唯一标识一个内核管理的设备实例。

通过 ls -l /dev 可查看设备文件的信息:

crw-rw-rw-  1 root root    195,     0 Aug 19 15:45 nvidia0
crw-------  1 root root    241,     0 Aug 19 15:45 nvme0
brw-rw----  1 root disk    259,     0 Aug 30 06:01 nvme0n1
brw-rw----  1 root disk    259,     1 Aug 30 06:01 nvme0n1p1
brw-rw----  1 root disk      8,     0 Aug 30 06:01 sda
brw-rw----  1 root disk      8,     1 Aug 30 06:01 sda1

如上输出中:

  • 第一个字符如果是 b 表示是块设备,而 c 表示是字符设备。
    • 块设备:按块访问,用户可挂载文件系统;
    • 字符设备:按字节访问,不经过文件系统缓存,直接和驱动交互(nvme0 是 NVMe 控制器本身,不挂载文件系统,所以是字符设备)。
  • 第 5,6 列的数字即是主设备号和次设备号。
  • 最后一列是设备文件名,一般来说,设备文件名的开头代表了设备类型或接口,如:
    • nvidia 开头的表示 Nvidia GPU;
    • nvme 开头的表示 NVMe 接口的 SSD,其后的 XnYpZ 中,X 表示控制器号,而 Y 表示命名空间号,而 Z 表示分区号;
    • sd 开头的代表 SATA/SCSI/SAS 硬盘(如传统机械、SATA SSD、U盘),每个设备一个设备名(sdasdb,…),其后再接数字表示分区。

分区唯一标识符 UUID

Linux 内核在启动或热插拔事件时,会 扫描所有总线(PCI/SCSI/SATA/NVMe 等)上的设备。内核会根据扫描顺序分配 设备号(major/minor)设备节点名(如 /dev/sda/dev/nvme0n1)。扫描顺序受总线拓扑、设备存在与否、驱动加载顺序等影响。

如果更换了硬盘顺序,或者拔掉了某些设备,可能导致设备名和次设备号发生改变。因此,为了稳定挂载文件系统,Linux 会给每个格式化后的分区分配一个 UUID。UUID 是一个 128 bit 的数字,由系统自动生成和管理。使用 UUID,在分区顺序改变或内核升级后,仍然保证分区正确加载。

查看分区 UUID 的方法:

ls -l /dev/disk/by-uuid  # 或
blkid

给磁盘分区

在挂载和管理磁盘之前,通常需要 先对磁盘进行分区。Linux 提供了 fdisk 工具,用于列出分区、创建和修改分区表。首先,在创建分区之前,可以使用前文提到的如 fdisk -llsblk 等工具查看当前系统中的磁盘和分区信息。

要给指定的磁盘(如 /dev/sda)分区,使用如下的命令进入交互式界面,在交互式界面输入 m 可以获取帮助:

fdisk /dev/sda

创建分区过程:在交互式界面依次输入如下字母,进行分区创建

  1. 创建分区表
    • g:创建 GPT 分区表(输入 o 则是创建 MBR 分区表,不推荐使用)。
  2. 创建新分区:若要在该盘上创建多个分区,则重复执行该步骤
    • n:创建新分区;
    • p:设置新分区为主分区(输入e 则是扩展分区,仅 MBR 使用);
    • 输入分区号;
    • 输入分区起始扇区(直接回车则紧接着上一个分区);
    • 输入结束扇区(可以直接使用 +size 的格式,如 +20G,直接回车表示使用全部剩余空间)。
  3. 保存或退出
    • w:写入分区表,并保存退出;
    • q:直接退出,不保存。

创建文件系统

创建磁盘文件系统

完成分区后,磁盘只是被划分了逻辑区域,还没有文件系统。在分区完成后,需要 为分区创建文件系统,才能挂载使用。Linux 提供了两个常用工具:

  1. mkfs

    mkfs [-t type] <device>
    
    • -t type 指定文件系统类型,如 ext4xfsvfat
  2. mke2fs(专用于 ext 系列文件系统)

    mke2fs [-t type] [-b block-size] [-i bytes-per-inode] <device>
    
    • -t type:指定文件系统
    • -b block-size:指定 block 大小
    • -i bytes-per-inode:指定多少字节分配一个 inode
  • 若无特殊需要,用 mkfs 就够了。

  • 格式化操作会清除分区上所有数据,请谨慎操作

  • 格式化完成后,分区便拥有了 UUID,请使用 blkidlsblk -f 查看。

创建 swap 文件系统

在 Linux 中,用作虚拟内存的磁盘空间称为 swap。Swap 可以在物理内存不足时临时存储数据,保证系统继续运行。可以通过 swap 分区swap 文件 两种方式创建。

  1. swap 分区

    1. 分区:使用 fdisk 创建一个分区(类型随意,大小根据系统内存和需求设置)

    2. 格式化为 swap:

      mkswap /dev/sdXn
      
  2. swap 文件

    1. 创建文件:使用 fallocate 或者 dd 命令

      # 创建 4GB 文件
      sudo fallocate -l 4G /swapfile # 或
      sudo dd if=/dev/zero of=/swapfile bs=1M count=4096
      
    2. 设置权限为 600

      sudo chmod 600 /swapfile
      
    3. 格式化为 swap 文件:

      sudo mkswap /swapfile
      

swap 的启用

格式化 swap 分区/ swap 文件后,可用 swapon /dev/sdXnswapon /swapfile 命令启动 swap。若要设置开机自动,需要在 /etc/fstab 中添加:(fstab 文件具体配置请看下文)

# 分区
/dev/sdXn none swap sw 0 0  # 也可先查看 UUID 后,使用 UUID 来配置
# 文件
/swapfile none swap sw 0 0

可用 free -h 或者 swapon --show 命令查看 swap 的使用情况。

Linux 文件系统挂载

挂载命令 mount

mount 命令用于挂载文件系统,也可以列出当前系统已挂载的文件系统信息。

命令格式:

mount [-t filesystem_type] [-L label] [-U uuid] [-o opt1[,opt2,...]] device mountpoint

参数说明:

  • -t 指定文件系统类型,不指定系统自动检测

  • -L 通过卷标名进行挂载

  • -U:通过 UUID 挂载(推荐)

  • -o :指定额外挂载选项,用逗号分隔,默认选项为:rw,async,nodev,auto,suid,exec,nouser

    • rw/ro:读写/只读权限;

    • async/sync:异步/同步写入;

    • dev/nodev:是否允许访问设备文件;

    • auto/noauto:是否允许以 mount -a 的方式自动挂载;

    • suid/nosuid:是否拥有 SetUID 和 SetGID 权限;

    • exec/noexec:是否允许可执行文件;

    • user/nouser:是否允许让普通用户使用 mount 挂载;

    • remount:重新挂载,对已经挂载的文件系统,修改显式指定的选项。

例1:挂载磁盘 /dev/sdb1

mkdir /mnt/disk1   # 建立挂载点
mount /dev/sdb1 /mnt/disk1  # 挂载分区

例 2:挂载 FAT32 的 U 盘 /dev/sdb1

插入 U 盘后,Linux 会将其识别为一个块设备。可通过 fdisk -llsblk 等命令找到其文件名,如 /dev/sdb1

# 建立挂载点
mkdir /mnt/usb 
# 挂载 U 盘,如果不确定 U 盘的文件系统是什么,可省略 -t vfat,由系统自动检测
mount -t vfat -o iocharset=utf8 /dev/sdb1 /mnt/usb
# 进入挂载点访问 U 盘数据
cd /mnt/usb/

注:对于 NTFS、exFAT 等非 Linux 原生文件系统,需要额外驱动(ntfs-3gexfat-fuse

开机自动挂载硬件设备

Linux 通过 /etc/fstab 文件配置开机自动挂载的文件系统。系统启动时会根据配置挂载分区。systemd 会自动读取该文件并挂载对应分区,运行 mount -a 也可手动挂载 /etc/fstab 中定义的所有分区。

文件中每一行表示一个挂载,格式为:

<file system> <mount point>   <type>  <options>       <dump>  <pass>

其各字段含义:

  1. file system:要挂载的设备,可以是:
    • 设备文件名:/dev/sda1
    • UUID:UUID=xxxx-xxxx (推荐)
    • 标签:LABEL=mydisk
    • 网络路径:server:/path
  2. mount point:挂载点目录,目录必须事先存在,否则挂载失败。
  3. type:文件系统类型,如 ext4xfstmpfs 等,或使用 auto 自动识别。
  4. options:挂载参数,见 mount 命令的挂载参数。
  5. dump:是否被 dump 备份(0 不备份,1 备份,2 不定期备份)
  6. pass:启动时 fsck 的检查顺序(0 不检测,其他是优先级,越小越高,)

dump 是一个传统的 UNIX 备份工具,可以按照文件系统级别进行备份。现代 Linux 系统中几乎没人再用,取而代之是 rsynctarborg 等更通用的工具,这个字段现在几乎是“摆设”,直接写 0 就行。

卸载文件系统

umount 命令用于卸载已经挂载的硬件设备。只有在卸载后,设备才能安全移除或重新挂载。用法:

umount 挂载点/设备名

如果文件系统正在被使用,umount 会失败。可以用 lsoffuser -m <挂载点> 来查找占用进程。如果要强制卸载,可给 umount-f 参数,但可能导致数据丢失,需谨慎操作。

fuser -m <挂载点> 输出列出是占用的进程,如:

/:       1942rce 5331rce  7442rce 59846rce 65221rce 66638rce 95797rce 208201rce 242421rce 300136c 300370cm 391330rce

前面的数字(如 19425331)代表进程的 PID,而后缀字母代表进程如何使用该文件:

  • c:cwd(当前目录)在这个挂载点里
  • e:进程运行的可执行文件在这个挂载点里
  • f:打开的文件在这个目录里
  • r:根目录在这个文件里
  • m:内存映射的文件在这个挂载点里

检测和修复文件系统

fsck(file system check)是 Linux 文件系统一致性检查工具。它会扫描磁盘分区的元数据和数据块,确保没有逻辑错误,例如:

  • inode 表和块位图不一致
  • 空闲块计数错误
  • 文件指向丢失的数据块
  • 目录项损坏

系统启动时,systemd 会自动调用 fsck/etc/fstab<pass> 字段规定的优先级依次检查文件系统的完整性,修复可能的错误:

  • 0:不检查,常见于 swap、tmpfs、nfs 分区等非本地磁盘分区;
  • 1:优先检查,通常只给根分区 / 设为 1;
  • 2:次级检查,用于其他需要检查的分区,如 /home/data 等。

这样可以保证在启动过程中,根分区最先被检查并修复,其他分区随后检查。

管理员也可手动运行:fsck /dev/sda1 来进行检查。但是请注意:

  1. 必须在分区未挂载时执行,否则可能会导致数据损坏。
  2. 如果只是想检查报告问题而不自动修复,可以加 -n 参数

LVM 逻辑卷管理机制

LVM(Logical Volume Manager)允许对磁盘进行 灵活管理:可以跨多个物理磁盘扩展卷组,动态调整逻辑卷大小,便于分区管理和快照操作。建立 LVM 的流程如下:

  1. 物理磁盘分为分区
  2. 将分区创建为物理卷(PV)
  3. 将物理卷整合为卷组(VG)
  4. 在卷组内创建逻辑卷(LV)

物理卷 PV

  • 创建:使用 pvcreate device 命令将磁盘/分区建立为物理卷。
  • 删除:若要删除物理卷,则使用 pvremove device 命令删除。删除前必须先从 VG 中移除。
  • 查看:使用 pvscan 命令查看系统中物理卷。pvdisplay 可查看更详细信息。

卷组 VG

  • 创建:使用 vgcreate [-s PE_size] vg_name pv_name1 [pv_name2] 命令建立卷组(PE_size 设置物理扩展大小,默认 4MB)。
  • 扩展:vgextend vg_name pv_name
  • 减少:vgreduce vg_name pv_name
  • 删除:vgremove vg_name 删除卷组。删除前需先删除其中所有 LV。
  • 查看:vgscan vgs vgdisplay 查看信息。

逻辑卷 LV

  • 创建:使用 lvcreate [-L vg_size] [-n lv_name] vg_name 建立逻辑卷。

    • 建立逻辑卷后,还需格式化和挂载才能使用。逻辑卷的设备文件名是 /dev/vg_name/lv_name
  • 增大lvresize -L new_size -r lv_name 修改逻辑卷大小,并同时调整文件系统大小。

  • 缩小:缩小逻辑卷较为复杂:

    • 卸载对应分区:umount mountpoint
    • 检查文件系统完整性:e2fsck -f /dev/vg_name/lv_name
    • 缩小文件系统:resize2fs /dev/vg_name/lv_name new_size
    • 缩小逻辑卷:lvresize -L new_size /dev/vg_name/lv_name
    • 重新挂载
  • 删除:lvremove /dev/vg_name/lv_name。删除前需先卸载。
  • 查看:lvscan lvdisplay 查看信息。

删除 LVM

若要删除 LVM,需按卸载分区,然后删除 LV,VG,PV 的顺序:

  • umount 卸载分区
  • lvremove 删除逻辑卷
  • vgremove 删除卷组
  • pvremove 删除物理卷卷标

RAID 磁盘阵列

RAID 介绍

RAID(Redundant Array of Independent/Inexpensive Disks)是一种通过多块磁盘组合提高 性能和/或冗余 的技术。常见类型:

RAID 0(带区卷 / Striping)

  • 数据分条写入多块磁盘,循环存储
  • 提高读写性能
  • 不提供冗余,任何一块磁盘故障都会丢失数据

RAID 1(镜像卷 / Mirroring)

  • 两块磁盘存储相同数据
  • 提供冗余,提高可靠性
  • 存储效率 50%

RAID 5(带奇偶校验的条带卷 / Striping with Parity)

  • 至少需要 3 块磁盘
  • 数据和校验信息分布存储
  • 可容忍一块磁盘故障,读性能高,写性能略低

还有 RAID 6(可容忍两块磁盘故障)、RAID 10(镜像+条带组合)等高级模式。

建立 RAID

  1. 建立分区:fdisk 创建每块磁盘的分区,建议设置相同大小
  2. 创建 RAID 阵列

    mdadm --create --verbose /dev/md0 --level=5 --raid-devices=3 /dev/sd[b-d]1
    
    • --level:RAID 类型
    • --raid-devices:参与 RAID 的设备数量
    • /dev/md0:创建后的 RAID 设备名称
  3. 格式化并挂载 RAID:

    mkfs -t ext4 /dev/md0
    mount /dev/md0 /mnt/raid
    
  4. 保存 mdadm 配置:确保开机自动组建 RAID

    mdadm --detail --scan >> /etc/mdadm/mdadm.conf
    
  5. 设置开机自动挂载:

    /dev/md0 /mnt/raid ext4 defaults 0 0