@(Linux)[文件系统管理]
1. 文件系统
1.1 各个操作系统上的文件系统
Linux文件系统
- ext2
- ext3
ext4
xfs
btrfs
- reiserfs
- jfs
- swap(交换分区)
- iso9660(光盘)
Windows
- fat32
- ntfs
Unix
- FFS
- UFS
- JFS2
网络文件系统
- NFS
- CIFS
集群文件系统
- GFS2
- OCFS2
分布式文件系统
- ceph
- moosefs
- mogilefs
- GlusterFS
- Lustre
1.2 文件系统划分
根据其是否支持"journal"功能
- 日志型文件系统: ext3, ext4, xfs, ...
- 非日志型文件系统: ext2, vfat, ...
文件系统的组成部分
内核中的比用户控件的效率高
- 内核中的模块:ext4, xfs, vfat
- 用户空间的管理工具:mkfs.ext4, mkfs.xfs, mkfs.vfat
Linux的虚拟文件系统
- VFS
1.3 几种文件系统介绍
第一种文件系统:ext4
近年来 ext2/3 暴露出了一些扩展性问题,于是便催生了 ext4 。在 2008 年发布的 Linux2.6.19 内核中集成了 ext4 的 dev 版本。 2.6.28 内核发布时,ext4 结束了开发版,开始接受用户的使用。
-
功能
- 向后和向前兼容性
- ext4 与 ext3 是向前兼容的,这样就可以将 ext3 文件系统挂载为 ext4 文件系统。
- 为了充分利用 ext4 的优势,必须实现文件系统的迁移,以转换和利用新的 ext4 格式。
- 提高时间戳分辨率和扩展范围
- 基于秒的时间戳已经不够用,ext4设计时间戳时考虑到未来的发展,它将时间戳的单位提升到纳秒。
- ext4 给时间范围添加了两个位,从而让时间寿命再延长 500 年。
- 向后和向前兼容性
-
伸缩性
- 突破文件系统的限制
- ext4 支持的最大文件系统为 1 EB(1000 PB)。
- ext4 支持最大 16 TB 的文件(假设由 4KB 的块组成),这个容量是 ext3 的 8 倍。
- 区段
- ext4 使用区段取代 ext3 的机制,从而改善了空间的分配,并且支持更加高效的存储结构。
- 区段 是一种表示一组相邻块的方式。使用区段减少了元数据,因为区段维护关于一组相邻块的存储位置的信息(从而减少了总体元数据存储),而不是一个块的存储位置的信息。
- ext4 的区段采用分层的方法高效地表示小文件,并且使用区段树高效地表示大文件。
- 突破文件系统的限制
-
性能
- 文件级预分配
- 尽管区段能够将相邻块划分为片段,但另一种更强大的方法是按照所需的大小预分配比较大的相邻块(XFS 以前就是采用这种方法)。
- ext4 通过一个新的系统调用来实现这个目的,这个调用将按照特定的大小预分配并初始化文件。然后,您就可以写入必要的数据,并为数据提供不错的读性能。
- 延迟块分配
- 这种优化的关键是延迟物理块的分配,直到需要在磁盘上写这些物理块时才对其进行分配并写到相邻的块。
- 这类似于持久化预分配,惟一的区别是文件系统会自动执行这项任务。不过如果预先知道文件的大小时,持久化预分配是更好的选择。
- 多个块分配
- 相邻块相关的优化,即针对 ext4 的块分配器。
- ext4 使用块分配器修复了这个问题,它能够在磁盘上一次分配多个块。与前面其他优化一样,这个优化在磁盘上收集相关的数据,以实现相邻读优化。
- 文件级预分配
-
可靠性
- 执行文件系统日志校验和
- 和 ext3 一样,ext4 也是一个日志文件系统。日志记录 就是通过日记(磁盘上相邻区域的专门循环记录)记录文件系统的变更的过程。
- 但是即使进行日志记录,如果日志出现错误仍然会导致文件系统损坏。为了解决这个问题,ext4 对日志执行校验和,确保有效变更能够在底层文件系统上正确完成。
- ext4 支持根据用户需求采用多种模式的日志记录。例如,ext4 支持 Writeback 模式,它仅记录元数据;或 Ordered 模式,它记录元数据,但写为元数据的数据是从日志中写入的;或 Journal 模式(最可靠的模式),它同时记录元数据和数据。注意,虽然 Journal 模式是确保文件系统一致的最佳选择,但它也是最慢的,因为所有数据都要经过日志。
- 在线磁盘碎片整理
- 尽管 ext4 添加一些特性来减少文件系统的碎片(比如将相邻块分配为区段),但随着系统使用时间的增加,碎片是难以完全避免的。因此出现了在线碎片整理工具,它们可以对文件系统和单个文件执行碎片整理,从而改善性能。在线碎片整理程序是一个简单的工具,它将文件复制到引用相邻区段的新 ext4 inode。
- 在线碎片整理还可以减少检查文件系统所需的时间(fsck)。ext4 将未使用的块组标记到 inode 表中,并让 fsck 进程忽略它们以加快检查速度。当操作系统因内部损坏(随着文件系统变大,这是不可避免的)而检查文件系统时,ext4 的设计方式将能够提高总体可靠性。
- 执行文件系统日志校验和
Note: 点击这里,查看参考文章
第二种文件系统:btrfs
文件系统似乎是内核中比较稳定的部分,多年来,人们一直使用 ext2/3,ext 文件系统以其卓越的稳定性成为了事实上的 Linux 标准文件系统。似乎 ext 就将成为 Linux 文件系统的代名词。然而当您阅读很多有关 ext4 的文章时,会发现都不约而同地提到了 btrfs,并认为 ext4 将是一个过渡的文件系统。
-
扩展性相关的特性
- B-Tree
- btrfs 文件系统中所有的 metadata 都由 BTree 管理。
- 使用 BTree 的主要好处在于查找,插入和删除操作都很高效。可以说 BTree 是 btrfs 的核心。
- btrfs 文件系统中所有的 metadata 都由 BTree 管理。
- 基于 Extent 的文件存储
- 现代很多文件系统都采用了 extent 替代 block 来管理磁盘。
- Extent 就是一些连续的 block,一个 extent 由起始的 block 加上长度进行定义。Extent 能有效地减少元数据开销。
- 动态 inode 分配
- 在 ext2 中 inode 区是被预先固定分配的,且大小固定,比如一个 100G 的分区中,inode table 区中只能存放 131072 个 inode,这就意味着不可能创建超过 131072 个文件,因为每一个文件都必须有一个唯一的 inode 。
- 为了解决这个问题,必须动态分配 inode 。每一个 inode 只是 BTree 中的一个节点,用户可以无限制地任意插入新的 inode,其物理存储位置是动态分配的。所以 btrfs 没有对文件个数的限制。
- 针对 SSD 的优化支持
- SSD 采用 flash memory 技术,内部没有磁盘磁头等机械装置,读写速率大幅度提升。 flash memory 有一些不同于 HDD 的特性。 flash 在写数据之前必须先执行擦除操作;其次,flash 对擦除操作的次数有一定的限制,在目前的技术水平下,对同一个数据单元最多能进行约 100 万次擦除操作,因此,为了延长 flash 的寿命,应该将写操作平均到整个 flash 上。
- 虽然 SSD 在硬件层面做了很多努力,但毕竟还是有限。 btrfs 用户可以使用 mount 参数打开对 SSD 的特殊优化处理。btrfs 用户可以使用 mount 参数打开对 SSD 的特殊优化处理。
- B-Tree
-
数据一致性相关的特性
- COW 事务
- 所谓 COW,即每次写磁盘数据时,先将更新数据写入一个新的 block,当新数据写入成功之后,再更新相关的数据结构指向新 block 。
- COW 只能保证单一数据更新的原子性。但文件系统中很多操作需要更新多个不同的元数据,比如创建文件需要修改以下这些元数据。任何一个步骤出错,文件便不能创建成功,因此可以定义为一个事务。
- Checksum
- 由于硬件原因,从磁盘上读出的数据会出错。比如 block A 中存放的数据为 0x55,但读取出来的数据变是 0x54,因为读取操作并未报错,所以这种错误不能被上层软件所察觉。
- 解决这个问题的方法是保存数据的校验和,在读取数据后检查校验和。如果不符合,便知道数据出现了错误。
- Btrfs 采用单独的 checksum Tree 来管理数据块的校验和,把 checksum 和 checksum 所保护的数据块分离开,从而提供了更严格的保护。
- COW 事务
-
多设备管理相关的特性
- 多设备管理
- Btrfs 支持动态添加设备。用户在系统中增加新的磁盘之后,可以使用 btrfs 的命令将该设备添加到文件系统中。
- 为了灵活利用设备空间,Btrfs 将磁盘空间划分为多个 chunk 。每个 chunk 可以使用不同的磁盘空间分配策略。
- Subvolume
- Subvolume 是很优雅的一个概念。即把文件系统的一部分配置为一个完整的子文件系统,称之为 subvolume 。
- 这种模型有很多优点,比如可以充分利用 disk 的带宽,可以简化磁盘空间的管理等。
- Subvolume 可以作为根目录挂载到任意 mount 点。 subvolume 是非常有趣的一个特性,有很多应用。
- 快照和克隆
- 快照是对文件系统某一时刻的完全备份。建立快照之后,对文件系统的修改不会影响快照中的内容。这是非常有用的一种技术。
- 快照一般是只读的,当系统支持可写快照,那么这种可写快照便被称为克隆。克隆技术也有很多应用。比如在一个系统中安装好基本的软件,然后为不同的用户做不同的克隆,每个用户使用自己的克隆而不会影响其他用户的磁盘空间。非常类似于虚拟机。
- 软件 RAID
- Btrfs 很好的支持了软件 RAID,RAID 种类包括 RAID0,RAID1 和 RAID10。
- Btrfs 缺省情况下对 metadata 进行 RAID1 保护。
- 多设备管理
-
其他特性
- Delay allocation
- Inline file
- 目录索引 Directory index
- 预分配
Note: 点击这里,查看参考文章
1.4 扩展查看
# 查看系统支持的文件系统
`cat /proc/filesystems`
# 查看操作系统中安装的模块
`lsmod`
2. 文件系统剖析
我们知道不同的操作系统所使用的文件系统是不一样的。举例来说,Windows 98 以前所使用的是文件系统是 FAT,Windows 2000 以后的版本有所谓的 NTFS 文件系统。至于 Linux 的正规文件系统则为 Ext2(Linux second extended file system,Ext2fs)。之后又出现了改进版的 Ext3 和 Ext4 ,总体上变化不大。
2.1 文件系统的对比
2.1.1 Linux的 Ext2
文件系统
假设一个文件的属性和权限信息是存放在 3 号的 inode 上,而文件的实际数据是存放在 1、4、6、11 这四个 block 中,那么当操作系统要访问该文件时,就能据此来排列磁盘的阅读顺序,可以扫描一次就将 4 个 block 内容读出来。这种访问方式称为索引式文件系统(indexed allocation)。而且 ext 在每两个文件之间都留有相当巨大的空闲空间。当文件被修改、体积增加时,它们通常有足够的空间来扩展。因此在一定程度上保证了 block 的访问范围不会跨度很大,减小了磁头的移动距离。
2.1.2 Windows的 FAT32
的文件系统
在往 FAT 文件系统中存入一个文件时,系统会尽量存放在靠近磁盘开始的地方。当你存入第二个文件时,它会紧挨着第一个文件。当进行频繁的删除修改后,block 就会分散的特别厉害。FAT 文件系统没有 inode 的存在,所以不能一下子将文件的所有 block 在一开始就读取出来。每个 block 号码都记录在前一个 block 当中,形成一个 block 链。当我们需要读取文件的时候,就必须一个一个地将 block 读出,例如上图的读出顺序为 1、6、3、12 。这就会导致磁头无法在磁盘转一圈就获得所有数据,有时候需要来回转好几圈才能读取到这个文件,导致文件读取性能极差。这就是 Windows 经常需要碎片整理的原因——使离散的数据汇合在一起
2.1.3 Windows系统为什么需要磁盘碎片整理?
相信我们看了上面的内容,一定理解了这个原因是怎么导致的。及时Windows之后开发了NTFS 文件系统。NTFS 文件系统虽然智能了一点,在文件周围分配了一些“缓冲”的空间,但经过一段时间的使用后, NTFS 文件系统还是会形成碎片。由于 ext 是索引式文件系统,所以基本上不太需要经常进行磁盘碎片整理。
2.1.4 知识扩展
以下是我花了几张图,来加深你对于文件系统的理解。
3. 创建文件系统
3.1 mkfs
命令
命令格式:
mkfs [options] [-t type] [fs-options] device [size]
参数选项:
-
-V
详细显示模式 -
-t
给定档案系统的型式,Linux 的预设值为 ext2 -
-c
在制做档案系统前,检查该partition 是否有坏轨 -
-l bad_blocks_file
将有坏轨的block资料加到 bad_blocks_file 里面 -
block
给定 block 的大小 -
-L
建立lable
Note:
- 在使用
mkfs
的时候,在命令行中输入mkfs之后输入.
按tab
键来查看支持的分区类型。 -
device
预备检查的硬盘 partition,例如:/dev/sda1
,必选。 -
mkfs
本身并不执行建立文件系统的工作,而是去调用相关的程序来执行。例如,若在-t
参数中指定ext2,则mkfs会调用mke2fs
来建立文件系统。使用时如省略指定【块数】参数,mkfs会自动设置适当的块数。
3.2 mke2fs
命令
ext系列文件系统专用管理工具
命令格式:
mke2fs -O journal_dev [ -b block-size ] [ -L volume-label ] [ -n ] [ -q ] [ -v ] external-journal [ fs-size ]
参数选项:
必要参数
-
<设备名称>
与设备对应文件,例如/dev/hd1 -
-b<块大小>
指定块大小 -
-c
在创建文件系统之前检查指定的设备 -
-g<块组数量>
指定一个块组中块的数量
选择参数
-t {ext2|ext3|ext4}
-b {1024|2048|4096}
-
-N #
为数据空间创建个多少个inode -
-m #
为管理人员预留的空间占据的百分比 -
-O FEATURE[,...]
启用指定特性 -
-O ^FEATURE
关闭指定特性 -
-E<扩展参数>
为要创建的文件系统指定一些参数 -
-f<不连续区段大小>
不知道连续区段的大小 -
-F
强制执行,即使指定设备没有被挂载或者不是块设备 -
-l<文件>
从指定文件中读取坏的块列表 -
-i<字节>
指定每个inode的字节数 -
-j
创建使用ext3卷号的文件系统 -
-J<扩展参数>
为使用ext3卷号的文件系统指定一些参数 -
-L
设置创建的文件系统的标签 -
-q
执行时不显示任何信息 -
-V
显示版本信息
3.3 mkswap
命令
添加扩展的swap分区
命令格式:
mkswap [options] device [size]
参数选项:
-
-c
建立交换区前,先检查是否有损坏的区块。 -
-p<页大小>
使用指定的页大小 -
-L<标签>
指定一个标签,伺候的sawpon
可以使用这个标签
实战演示:
[root@linux ~]# dd if=/dev/zero of=/extra-swap bs=1024 count=1024 #创建交换分区文件
[root@linux ~]# mkswap /extra-swap 1024 #格式化交换分区
[root@linux ~]# swapon /extra-swap #加载交换分区
Note:
- 调整其分区的ID为82
- [交换区大小] 指定交换区的大小,单位为1024字节
3.4 blkid
命令
块设备属性信息查看
命令格式:
blkid [OPTION]... [DEVICE]
参数选项:
-
-o<标签>
指定输出格式 (full、value、list\device\udev) -
-s<标签>
显示指定标签信息 (LABEL、UUID、TYPE) -
-U UUID
根据指定的UUID来查找对应的设备 -
-L LABEL
根据指定的LABEL来查找对应的设备
实战演示:
[root@localhost ~]# blkid -s UUID /dev/sda5 #显示指定设备 UUID
/dev/sda5: UUID="cad7349a-601d-4df4-a46b-90e1ffc29b1b"
[root@localhost ~]# blkid -s UUID #显示所有设备 UUID
/dev/sda5: UUID="cad7349a-601d-4df4-a46b-90e1ffc29b1b"
/dev/sda1: UUID="d7899bc2-b08e-48cd-b904-54956c085951"
[root@localhost ~]# blkid -s LABEL /dev/sda5 #显示指定设备 LABEL
/dev/sda5: LABEL="Disk E"
[root@localhost ~]# blkid -s LABEL #显示所有设备 LABEL
/dev/sda1: LABEL="M-fM-^VM-0M-eM-^JM- M-eM-^MM-7"
/dev/sda5: LABEL="Disk E"
[root@localhost ~]# blkid -s TYPE #显示所有设备文件系统
/dev/sda5: TYPE="swap"
/dev/sda1: TYPE="ext4"
[root@localhost ~]# blkid -o device #显示所有设备
/dev/sda5
/dev/sda1
[root@localhost ~]# blkid -o list #以列表方式查看详细信息
device fs_type label mount point UUID
---------------------------------------------------------------------------------
/dev/sda5 swap cad7349a-601d-4df4-a46b-90e1ffc29b1b
/dev/sda1 ext4 / d7899bc2-b08e-48cd-b904-54956c085951
3.5 e2label
命令
管理ext系列文件系统的LABEL
e2label命令用来设置第二扩展文件系统的卷标。
命令格式:
e2label device [ new-label ]
3.5 tune2fs
命令
重新设定ext系列文件系统可调整参数的值
命令格式:
tune2fs [OPTION]... [DEVICE]
参数选项:
-
-l
查看指定文件系统超级块信息 -
-c max-mount-counts
设置强制自检的挂载次数,如果开启,每挂载一次mount conut就会加1,超过次数就会强制自检 -
-i interval-between-checks[d|m|w]
设置强制自检的时间间隔[d天m月w周] -
-m #
保留块的百分比 -
-j
将ext2文件系统转换为ext3类型的文件系统 -
-L 'LABEL'
类似e2label的功能,可以修改文件系统的标签 -
-r reserved-blocks-count
调整系统保留空间 -
-o [^]mount-option[,...]
设置或清除默认挂载的文件系统选项 -
-O
文件系统属性启用或禁用 -
-U UUID
修改UUID号
实战演示:
# tune2fs -c 30 /dev/hda1 #设置强制检查前文件系统可以挂载的次数
# tune2fs -c -l /dev/hda1 #关闭强制检查挂载次数限制。
# tune2fs -i 10 /dev/hda1 #10天后检查
# tune2fs -i 1d /dev/hda1 #1天后检查
# tune2fs -i 3w /dev/hda1 #3周后检查
# tune2fs -i 6m /dev/hda1 #半年后检查
# tune2fs -i 0 /dev/hda1 #禁用时间检查
# tune2fs -j /dev/hda1 #添加日志功能,将ext2转换成ext3文件系统
# tune2fs -r 40000 /dev/hda1 #调整/dev/hda1分区的保留空间为40000个磁盘块
# tune2fs -o acl,user_xattr /dev/hda1 #设置/dev/hda1挂载选项,启用Posix Access Control Lists和用户指定的扩展属性
3.6 dumpe2fs
命令
dumpe2fs命令用于打印“ext”文件系统的超级块和块组信息。
命令格式:
dumpe2fs [-bfhixV] [-o superblock=] [-o blocksize=] device
参数选项:
-
-b
打印文件系统中预留的块信息 -
-ob<超级块>
指定检查文件系统时使用的超级块 -
-OB<块大小>
检查文件系统时使用的指定的块大小 -
-h
仅显示超级块信息 -
-i
从指定的文件系统映像文件中读取文件系统信息 -
-x
以16进制格式打印信息块成员
实战演示:
[root@localhost ~]$ sudo dumpe2fs /dev/sda8 #查看sda8磁盘信息
dumpe2fs 1.41.12 (17-May-2010)
Filesystem volume name:
Last mounted on: /
Filesystem UUID: a0794ac7-6cda-4a45-aa45-a97bd32f8c82
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
3.7 fsck
命令
文件系统检测
命令格式:
fsck [ -sACVRTNP ] [ -t fstype ] [filesys ... ] [--] [ fs-specific-options ] [[ ]]
参数选项:
-
-t FS_TYPE
检查那个文件格式的文件系统,类似fsck.FS_TYPE
。 -
-a
不提问,自动修复文件系统(请小心使用此选项)。注意 e2fsck(8) 支持 -a 仅仅是为了向前兼容。这个选项被映射到e2fsck
的-p
选项,那比较安全一点,不像大多数文件系统检查器支持的 -a 那样。 -
-r
交互式地修复文件系统错误(询问确认)。注意: 如果多个 fsck 在并行执行,这不是一个好想法。还要注意e2fsck
的默认行为;它也只为了向前兼容才保留这个选项。 -
-R
当使用 -A 标志来检查所有文件系统时,跳过root文件系统 (它可能已经被挂载为可读写)。 -
-A
搜索/etc/fstab
文件,一次检查所有在文件中有定义的文件系统。这个选项典型地用在 /etc/rc 系统初始化文件中,而不使用多条命令来分别检查各独立的分区。
Note:
- 只输入
fsck
命令,版本号 - FS_TYPE一定要与分区上已经文件类型相同
实战演示:
[root@localhost ~]# e2fsck -a -y /dev/sda1 #检查 /dev/sda1 是否有问题,如发现问题便自动修复
3.8 e2fsck
命令
ext系列文件专用的检测修复工具
命令格式:
e2fsck [ -pacnyrdfkvtDFV ] [ -b superblock ] [ -B blocksize ] [ -l|-L bad_blocks_file ] [ -C fd ] [ -j external-journal ] [ -E extended_options ] device
参数选项:
-
-a
检查 partition,如发现问题会自动修复 -
-b
设定 superblock 位置 -
-B size
指定 size 作为区块大小 -
-c
检查 partition 是否有坏轨 -
-C file
将检查结果储存到 file -
-d
输出 e2fsck debug 结果 -
-f
e2fsck 预设只会对错误的档案系统检查,加上 -f 是强制检查 -
-F
在检查前将硬盘的 buffer cache 清空,避免发生错误 -
-l list
记录了坏轨区块加入 list 中 -
-d
打印 e2fsck 的 debug 结果 -
-f
强制检查 -
-n
以 (read-only) 开启档案系统 -
-p
关闭互动模式,如有问题自动修复,等同 -a -
-v
显示详细报告 -
-y
启用使用者互动模式
实战演示:
[root@localhost ~]# e2fsck -a -y /dev/sda1 #检查 /dev/sda1 是否有问题,如发现问题便自动修复