当前位置:首页 » 《关于电脑》 » 正文

Linux 文件系统 fsck 磁盘修复

2 人参与  2024年04月17日 15:58  分类 : 《关于电脑》  评论

点击全文阅读


Linux文件系统

一切皆文件

  Linux 文件系统是一种管理存储设备上所存储的文件的一种内生性软件。Linux 支持多种类型的文件系统,以便在硬盘中存储应用程序、数据文件和配置文件等。
  文件系统类型:Linux 支持多种文件系统,例如 ext4、xfs、btrfs 等。每种文件系统都在存储设备上实现了虚拟目录结构,具有特定的功能和性能。
  Linux 文件系统会为每个文件分配两个数据结构:

索引节点(index node)和目录项(directory entry),它们主要用来记录文件的元信息和目录层次结构。索引节点,也就是 inode,用来记录文件的元信息,比如 inode 编号、文件大小、访问权限、创建时间、修改时间、数据在磁盘的位置等等。索引节点是文件的唯一标识,它们之间一一对应,也同样都会被存储在硬盘中,所以索引节点同样占用磁盘空间。目录项,也就是 dentry,用来记录文件的名字、索引节点指针以及与其他目录项的层级关联关系。多个目录项关联起来,就会形成目录结构,但它与索引节点不同的是,目录项是由内核维护的一个数据结构(目录是一个文件,持久化存储在磁盘),不存放于磁盘,而是缓存在内存。

  如果查询目录频繁从磁盘读,效率会很低,所以内核会把已经读过的目录用目录项这个数据结构缓存在内存,下次再次读到相同的目录时,只需从内存读就可以,大大提高了文件系统的效率。
  文件系统把多个扇区组成了一个逻辑块,每次读写的最小单位就是逻辑块(数据块),Linux 中的逻辑块大小为 4KB,也就是一次性读写 8 个扇区(每个扇区512B),这将大大提高了磁盘的读写的效率。

虚拟文件系统(VFS)

  文件系统的种类众多,而操作系统希望对用户提供一个统一的接口,于是在用户层与文件系统层引入了中间层,这个中间层就称为虚拟文件系统(Virtual File System,VFS)。
  VFS 定义了一组所有文件系统都支持的数据结构和标准接口,这样程序员不需要了解文件系统的工作原理,只需要了解 VFS 提供的统一接口即可。
在这里插入图片描述
Linux支持的文件系统按照存储位置的不同分为三类:

磁盘的文件系统,它是直接把数据存储在磁盘中,比如 Ext 2/3/4、XFS 等都是这类文件系统。内存的文件系统,这类文件系统的数据不是存储在硬盘的,而是占用内存空间,我们经常用到的 /proc 和 /sys 文件系统都属于这一类,读写这类文件,实际上是读写内核中相关的数据数据。网络的文件系统,用来访问其他计算机主机数据的文件系统,比如 NFS、SMB 等等。

文件系统首先要先挂载到某个目录才可以正常使用,比如 Linux 系统在启动时,会把文件系统挂载到根目录。

文件使用

在这里插入图片描述

fd = open(name, flag); # 打开文件 文件的路径名和文件名 返回文件描述符...write(fd,...);         # 写数据 使用文件描述符来操作文件...close(fd);             # 关闭文件  避免资源泄露

流程:
  打开了一个文件后,操作系统会跟踪进程打开的所有文件,所谓的跟踪呢,就是操作系统为每个进程维护一个打开文件表,文件表里的每一项代表「文件描述符」,所以说文件描述符是打开文件的标识。
在这里插入图片描述
操作系统在每个进程中打开文件表中维护着打开文件的状态和信息:

文件指针:系统跟踪上次读写位置作为当前文件位置指针,这种指针对打开文件的某个进程来说是唯一的;文件打开计数器:文件关闭时,操作系统必须重用其打开文件表条目,否则表内空间不够用。因为多个进程可能打开同一个文件,所以系统在删除打开文件条目之前,必须等待最后一个进程关闭文件,该计数器跟踪打开和关闭的数量,当该计数为 0 时,系统关闭文件,删除该条目;文件磁盘位置:绝大多数文件操作都要求系统修改文件数据,该信息保存在内存中,以免每个操作都从磁盘中读取;访问权限:每个进程打开文件都需要有一个访问模式(创建、只读、读写、添加等),该信息保存在进程的打开文件表中,以便操作系统能允许或拒绝之后的 I/O 请求;

读写文件的过程:

当用户进程从文件读取 1 个字节大小的数据时,文件系统则需要获取字节所在的数据块,再返回数据块对应的用户进程所需的数据部分。当用户进程把 1 个字节大小的数据写进文件时,文件系统则找到需要写入数据的数据块的位置,然后修改数据块中对应的部分,最后再把数据块写回磁盘。
文件系统的基本操作单位是数据块。

文件存储

连续存储

文件头里需要指定「起始块的位置」和「长度」,有了这两个信息就可以很好的表示文件存放方式是一块连续的磁盘空间。此处说的文件头,就类似于 Linux 的 inode。
在这里插入图片描述
连续空间存放的方式虽然读写效率高,但是有**「磁盘空间碎片」和「文件长度不易扩展」的缺陷。**

请添加图片描述

非连续存储

隐式链表:的方式存放的话,实现的方式是文件头要包含「第一块」和「最后一块」的位置,并且每个数据块里面留出一个指针空间,用来存放下一个数据块的位置。
缺点
1.无法直接访问数据块,只能通过指针顺序访问文件,以及数据块指针消耗了一定的存储空间。
2.隐式链接分配的稳定性较差,系统在运行过程中由于软件或者硬件错误导致链表中的指针丢失或损坏,会导致文件数据的丢失。
请添加图片描述
显示链表:把用于链接文件各数据块的指针,显式地存放在内存的一张链接表中,该表在整个磁盘仅设置一张,每个表项中存放链接指针,指向下一个数据块号。显著地提高了检索速度,而且大大减少了访问磁盘的次数。
缺点:
1.整个表都存放在内存中的关系,因此不适用于大磁盘。

在这里插入图片描述

文件索引

三种文件索引基本方式:
顺序分配:
请添加图片描述
链表分配:
请添加图片描述
索引分配:
请添加图片描述
对照:
请添加图片描述
集合三种基础索引方式的优点于一身:
请添加图片描述

目录存储

目录文件的块里面保存的是目录里面一项一项的文件信息。
在目录文件的块中,最简单的保存格式就是列表,就是将该目录下的每个文件的文件信息(如文件名、文件 inode、文件类型等)列在表里。列表中每一项就代表该目录下的文件的文件名和对应的 inode,通过这个 inode,就可以找到真正的文件。
请添加图片描述
为提高效率,保存目录的格式改成哈希表,对文件名进行哈希计算,把哈希值保存起来,如果我们要查找一个目录下面的文件名,可以通过名称取哈希。如果哈希能够匹配上,就说明这个文件的信息在相应的块里面。
Linux 系统的 ext 文件系统就是采用了哈希表,来保存目录的内容,这种方法的优点是查找非常迅速,插入和删除也较简单,不过需要一些预备措施来避免哈希冲突。

硬链接和软链接

硬链接是多个目录项中的「索引节点」指向一个文件,也就是指向同一个 inode,但是 inode 是不可能跨越文件系统的,每个文件系统都有各自的 inode 数据结构和列表,所以硬链接是不可用于跨文件系统的。由于多个目录项都是指向一个 inode,那么只有删除文件的所有硬链接以及源文件时,系统才会彻底删除该文件请添加图片描述
软链接相当于重新创建一个文件,这个文件有独立的 inode,但是这个文件的内容是另外一个文件的路径,所以访问软链接的时候,实际上相当于访问到了另外一个文件,所以软链接是可以跨文件系统的,甚至目标文件被删除了,链接文件还是在的,只不过指向的文件找不到了而已。
请添加图片描述

文件系统结构

用户在创建一个新文件时,Linux 内核会通过 inode 的位图找到空闲可用的 inode,并进行分配。要存储数据时,会通过块的位图找到空闲的块,并分配。 计算一个块4K可以表示4 * 1024 * 8=2^15个空闲块。这些块总大小为( 4 * 1024(一个数据块)) * 2^15 = 2^27 = 128M。(太小了,很多文件都比这个大)。
在 Linux 文件系统,把这个结构称为一个块组,那么有 N 多的块组,就能够表示 N 大的文件。

下图给出了 Linux Ext2 整个文件系统的结构和块组的内容,文件系统都由大量块组组成,在硬盘上相继排布:
请添加图片描述

超级块,包含的是文件系统的重要信息,比如 inode 总个数、块总个数、每个块组的 inode 个数、每个块组的块个数等等。块组描述符,包含文件系统中各个块组的状态,比如块组中空闲块和 inode 的数目等,每个块组都包含了文件系统中「所有块组的组描述符信息」。数据位图和 inode 位图, 用于表示对应的数据块或 inode 是空闲的,还是被使用中。inode 列表,包含了块组中所有的 inode,inode 用于保存文件系统中与各个文件和目录相关的所有元数据。数据块,包含文件的有用数据。

文件系统介绍

ext文件系统

  Linux 操作系统中引入的最早的文件系统叫作扩展文件系统(extended filesystem,简记为 ext)。它为 Linux 提供了一个基本的类 Unix 文件系统:使用虚拟目录来操作硬件设备,在物理设备上按定长的块来存储数据。
  ext 文件系统采用名为索引节点的系统来存放虚拟目录中所存储文件的信息。索引节点系统在每个物理设备中创建一个单独的表(称为索引节点表)来存储这些文件的信息。存储在虚拟目录中的每一个文件在索引节点表中都有一个条目。ext 文件系统名称中的 extended 部分来自其跟踪的每个文件的额外数据,包括:

文件名文件大小文件的属主文件的属组文件的访问权限

  Linux 通过唯一的数值(称作索引节点号)来引用索引节点表中的每个索引节点,这个值是创建文件时由文件系统分配的。文件系统通过索引节点号而不是文件全名及路径来标识文件。 ext 文件系统常见的问题是在文件写入到物理设备时,存储数据用的块很容易分散在整个设备中(称作碎片化,fragmentation)。 数据块的碎片化会降低文件系统的性能,因为需要更长的时间在存储设备中查找特定文件的所有块。
参考:https://brinnatt.com/primary/%E7%AC%AC-4-%E7%AB%A0-linux-ext-%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F/

ext2文件系统

  为了解决ext文件系统对文件大小2GB的限制, 升级ext2。ext2文件系统扩展了索引节点表的格式来保存系统上每个文件的更多信息。添加了文件信息有:创建时间值、修改时间值、最后访问时间值, 帮助系统管理员追踪文件的访问情况。最大允许文件大小增加到2TB(后期版本改到32TB),以容纳数据库服务器中常见的大文件。
   相较于ext文件系统,保存文件时,ext2 文件系统通过按组分配磁盘块来减轻碎片化。通过将数据块分组,文件系统在读取文件时不需要为了数据块查找整个物理设备。
  文件系统每次存储或更新文件,它都要用新信息来更新索引节点表。问题在于这种操作并非总是一气呵成的,会对系统造成致命的问题。
  系统在人为误操作,非正常断电重启等各种非规范操作的情况下,容易造成文件系统损坏和崩溃,严重时会造成硬件损坏。为避免出现文件系统崩坏,甚至是硬件损坏这种不可逆损坏,敬告尽可能规范操作。
参考文章:https://blog.csdn.net/sinat_37817094/article/details/125716792

ext3文件系统(日志文件系统)

文件系统设计原理:Linux文件系统的设计原理是基于文件系统的一致性和可靠性。文件系统需要确保数据的完整性、可靠性和可用性,以便在需要时进行访问和修改。fsck命令的工作原理:fsck命令会对文件系统进行检查和修复。它会检查文件系统的数据结构、文件节点、目录结构等,以确保文件系统的一致性和正常性。

ext4 文件系统(日志文件系统)

扩展 ext3 文件系统功能的结果是 ext4 文件系统(你可能也猜出来了)。ext4 文件系统在 2008 年受到 Linux 内核官方支持,现在已是大多数流行的 Linux 发行版采用的默认文件系统。
除了支持数据压缩和加密,ext4 文件系统还支持一个称作区段(extent)的特性。区段在存储设备上按块分配空间,但在索引节点表中只保存起始块的位置。由于无需列出所有用来存储文件中数据的数据块,它可以在索引节点表中节省一些空间。
ext4 还引入了块预分配技术(block preallocation)。如果你想在存储设备上给一个你知道要变大的文件预留空间,ext4 文件系统可以为文件分配所有需要用到的块,而不仅仅是那些现在已经用到的块。ext4 文件系统用 0 填满预留的数据块,不会将它们分配给其他文件。

Reiser 文件系统(日志文件系统)

2001 年,Hans Reiser 为 Linux 创建了第一个称为 ReiserFS 的日志文件系统。ReiserFS 文件系统只支持回写日志模式——只把索引节点表数据写到日志文件。ReiserFS 文件系统也因此成为 Linux 上最快的日志文件系统之一。
有两个有意思的特性被引入了 ReiserFS 文件系统:一个是你可以在线调整已有文件系统的大小;另一个是被称作尾部压缩(tailpacking)的技术,该技术能将一个文件的数据填进另一个文件的数据块中的空白空间。如果你必须为已有文件系统扩容来容纳更多的数据,在线调整文件系统大小功能非常好用。

JFS 文件系统(日志文件系统)

作为可能依然在用的最老的日志文件系统之一,JFS(Journaled File System)是 IBM 在 1990 年为其 Unix 衍生版 AIX 开发的。然而直到第 2 版,它才被移植到 Linux 环境中。
IBM 官方称 JFS 文件系统的第 2 版为 JFS2,但大多数 Linux 系统提到它时都只用 JFS。
JFS 文件系统采用的是有序日志方法,即只在日志中保存索引节点表数据,直到真正的文件数据被写进存储设备时才删除它。这个方法在 ReiserFS 的速度和数据模式日志方法的完整性之间的采取的一种折中。
JFS 文件系统采用基于区段的文件分配,即为每个写入存储设备的文件分配一组块。这样可以减少存储设备上的碎片。
除了用在 IBM Linux 上外,JFS 文件系统并没有流行起来,但你有可能在同 Linux 打交道的日子中碰到它。

XFS 文件系统(日志文件系统)

XFS 日志文件系统是另一种最初用于商业 Unix 系统而如今走进 Linux 世界的文件系统。美国硅图公司(SGI)最初在 1994 年为其商业化的 IRIX Unix 系统开发了 XFS。2002 年,它被发布到了适用于 Linux 环境的版本。
XFS 文件系统采用回写模式的日志,在提供了高性能的同时也引入了一定的风险,因为实际数据并未存进日志文件。XFS 文件系统还允许在线调整文件系统的大小,这点类似于 ReiserFS 文件系统,除了 XFS 文件系统只能扩大不能缩小。

ZFS 文件系统(写时复制文件系统)

COW 文件系统 ZFS 是由 Sun 公司于 2005 年研发的,用于 OpenSolaris 操作系统,从 2008 年起开始向 Linux 移植,最终在 2012 年投入 Linux 产品的使用。
ZFS 是一个稳定的文件系统,与 Resier4、Btrfs 和 ext4 势均力敌。它最大的弱项就是没有使用 GPL 许可。自 2013 年发起的 OpenZFS 项目有可能改变这种局面。但是,在获得 GPL 许可之前,ZFS 有可能终无法成为 Linux 默认的文件系统。

Btrfs 文件系统(写时复制文件系统)

Btrfs 文件系统是 COW 的新人,也被称为 B 树文件系统。它是由 Oracle 公司于 2007 年开始研发的。Btrfs 在 Reiser4 的诸多特性的基础上改进了可靠性。另一些开发人员最终也加入了开发过程,帮助 Btrfs 快速成为了最流行的文件系统。究其原因,则要归于它的稳定性、易用性以及能够动态调整已挂载文件系统的大小。OpenSUSE Linux 发行版将 Btrfs 作为其默认文件系统。除此之外,该文件系统也出现在了其他 Linux 发行版中(如 RHEL),Fedora 在 2020 年将 Btrfs 作为其默认文件系统。

FSCK

  计算机难免会由于某些系统因素或人为误操作(突然断电)出现系统异常,这种情况下非常容易造成文件系统的崩溃,严重时甚至会造成硬件损坏。
  fsck是一个用于检查和修复文件系统中错误的工具。它的工作原理是扫描文件系统并找出错误的数据结构和文件,然后尝试恢复这些错误。
  fsck只能修复软件层面的文件系统错误,无法修复硬件层面的损坏。如果文件系统已经受到了硬件层面的损坏,可能需要使用专业的数据恢复工具来恢复数据。
  在使用fsck工具时,文件系统不应该处于运行状态。

修复原理

检查超级块:fsck首先读取文件系统的超级块,以了解文件系统的大小、状态和其他信息。如果超级块损坏,fsck会尝试恢复它,否则它将使用备份超级块。检查inode表:fsck会检查inode表中每个inode的元数据(如文件大小、访问时间、修改时间、创建时间等),并确保它们与文件系统的实际内容匹配。检查块位图:fsck会检查块位图来确保每个块都被正确标记为已分配或未分配。如果块位图有误,fsck会尝试修复它。检查目录结构:fsck会检查每个目录,确保每个目录项都指向正确的inode,并且没有重复的或损坏的目录项。如果发现错误,fsck会尝试删除或修复它们。修复错误:如果fsck检测到错误,它会尝试自动修复它们。如果无法自动修复,它会向用户报告错误,并询问用户是否要手动修复它们。
参考文章:https://blog.csdn.net/younger_china/article/details/76348817

使用方法

语法:fsck.ext4[必要参数][选择参数][设备代号]
参数:

参数注释
-a非互交模式,自动修复
-c检查是否存在有损坏的区块。
-C反叙述器> fsck.ext3命令会把全部的执行过程,都交由其逆向叙述,便于监控程序
-d详细显示命令执行过程
-f强制进行检查
-F检查文件系统之前,先清理该保存设备块区内的数据
-l <损坏区块文件>把文件中所列出的损坏区块,加入标记
-L<损坏区块文件>清除所有损坏标志,重新标记
-n非交互模式,把欲检查的文件系统设成只读
-P<数字>设置fsck.ext2命令所能处理的inode大小为多少
-r交互模式
-R忽略目录
-s顺序检查
-S效果和指定“-s”参数类似
-t显示fsck.ext2命令的时序信息。
-v显示详细的处理过程
-y关闭互动模式
-b<分区第一个磁区地址>指定分区的第一个磁区的起始地址/Super Block
-B<区块大小>设置该分区每个区块的大小
-I设置欲检查的文件系统,其inode缓冲区的区块数目
-V显示版本信息

使用举例

1. fsck -r /dev/sdb1    #参用互动方式修复sdb1分区2. fsck -t ext4 -v /dev/sda1 #修复ext4系统3. fsck -s /dev/sdb  #检查/dev/sdb文件系统的完整性,并报告任何错误4. fsck -y /dev/sdb #当fsck检测到错误时,自动尝试修复它们5. fsck -s /   #检查系统根分区的完整性,并报告任何错误6. //在系统启动时强制运行fsck:创建一个名为forcefsck的文件在系统的根分区,然后重新启动系统。在下次启动期间,fsck将被自动运行7. //在救援模式下运行fsck:重新启动系统,按住shift键以显示grub菜单,选择高级选项,然后选择fsck/*    重新启动系统,并在启动时选择使用Live CD。   在Live CD中,找到文件管理器或终端。   使用lsblk命令查看硬盘分区情况,以确定需要修复的文件系统。   在终端中输入以下命令,根据需要选择自动修复或手动修复:   自动修复文件系统错误:fsck -y /dev/sdb,当fsck检测到错误时,自动尝试修复它们   手动修复文件系统错误:fsck -n /dev/sdb,检查文件系统的完整性,并报告任何错误,但不进行自动修复   如果fsck检测到错误,它会尝试自动修复它们。如果无法自动修复,它会向用户报告错误,并询问用户是否要手动修复它们*/8. fsck -AR -y  #自动检查并修复所有已安装的文件系统

参考文章:

https://www.cnblogs.com/forvs/p/16998934.htmlhttps://segmentfault.com/a/1190000023615225#item-2-6(基本全搬,全是干货)https://blog.csdn.net/Beginner_G/article/details/117911252

点击全文阅读


本文链接:http://zhangshiyu.com/post/96669.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1