• inode节点和文件系统


    既然要详细的了解inode节点,我们有必要深入的探索一下文件系统的概念。

    硬盘的物理构成和逻辑构成

    在物理层面上,硬盘主要由磁盘片(组),机械手臂,读取头和主轴马达构成.其中,磁盘片(组)用于存储数据,读取头用于读写数据,主轴马达负责转动磁盘片(组),机械手臂负责移动读取头.
    在逻辑层面上,硬盘主要由扇区构成.
    在补充篇中我们提及过,扇区是硬盘存储的最小单位,大小为512bytes,将多个扇区组合成一个闭合圆构成一个磁柱,磁柱是硬盘分割的最小单位.
    其中,在硬盘中,第一个扇区最为特殊,它分为两个部分,
    一部分大小为446bytes,这一部分作为主要开机区(MBR),存放系统开机的核心程序.
    另一部分大小只有64bytes,用于存放分区表数据,每条分区数据为8bytes,所以最多只能有4个分区(主+扩展),当然还有逻辑分区,我们可以将一个扩展分区分割成多个逻辑分区.

    格式化

    我们都知道一块硬盘必须要分区才能使用,而在分区后,我们还需要对分区进行格式化,硬盘都必须经过格式化才能使用.
    格式化的作用就是将一个空白的分区,分割成一个个小的区域,并对这些区域进行编号,没有这个过程,计算机就不知道从何处读写.
    在传统的磁盘和文件系统中,一个分区往往只能被格式化成一个文件系统,但是由于新技术的利用,我们可以将同一分区格式化为多个文件系统(LVM--Logical Volume Manage),也可以将多个分区合成一个文件系统,比如在系统架构中常提到的RAID(磁盘阵列).
    我们也知道,每一个操作系统支持的文件系统也并不相同,比如windows支持的NTFS和linuxEXT4就是两种不同的文件系统.
    我们接下来提及的文件系统就指EXT2/3/4。

    文件系统

    在之前的学习中,我们了解到linux存储的文件不仅仅只是文件的内容,还要存储文件的权限和文件属性等.文件系统通常会将文件的权限及属性和实际存储的内容分开存储.
    将权限和文件属性存放在inode节点中,而实际的数据则存放在数据块(data bolck)中.
    而除此之外,还会有一个superblock用来记录文件系统的整体信息,包含inode节点的数量,block的数量等.

    因此,文件系统会在初始化的时候,就规划好inode节点和block.而一旦初始化完毕后,除非再次格式化(还可以使用命令变更文件系统大小),否则inode和block就不会再变动.
    但是当我们的文件系统非常庞大的时候,将inode节点和block一块管理,是很麻烦的,所以linux的EXT2系统在格式化的时候,会将整个分区再次分割成多个
    block group(区块组),每个block group都拥有自己的inode/block/superblock系统.这样就可以减轻管理负担.

    此处有一点需要注意,在文件系统最前面还有一个启动扇区,用于安装开机管理程序.


    接下来,我们就针对BlockGroup中的数据进行学习.首先我们需要了解一下数据块的概念.

    数据块

    从名称上来看,很容易理解,数据块==存储数据的块.在我们使用的ext2(现在使用到一般是ext4)系统中,支持的数据块大小有1k,2k,4k.
    需要注意的是,在格式化的时候,数据块的大小就已经固定了,同时每个数据块都有编号,用于inode记录.
    而数据块大小的不同差别也会很大,比如1k的数据块支持的最大单一文件大小只有16gb,文件系统的总量最多只能为2t.而2k的数据块分别为256gb和8t,4kb分别为2tb和16tb.
    在linux中,原则上数据块的大小和数量在格式化后就不能再改变了,同时每个数据块只能放置一个文件的数据,当文件很大时可以占用多个数据块,但是当文件的大小小于数据块的时候,数据块中剩余的空间不会再被使用.

    inode节点

    首先,在linux中,inode节点在初始化之后,其数量和大小也是固定的,每个inode节点大小均为128bytes ~ 256bytes,

    同时每一个档案都会且仅会占用一个inode,因此文件系统能够建立文件的数量和inode的数量息息相关.

    在linux中,系统读取文件的时候,会先找到inode节点,然后根据inode节点所记录的权限等属性判断用户是否符合要求,然后决定是否读取block中的数据.

    inode节点负责记录文件的权限,属性,实际数据对应的block等属性,他记录的数据大致如下:

    该文件的存取模式(read/write/execute)

    该文件的拥有者和群组(owner/group)

    该文件的大小

    该文件建立/状态改变时间(ctime)

    最近一次读取时间(atime)

    最后修改时间(mtime)

    定义文件的标志(SETUID等)

    文件的真正指向

    直接指向block区域

    间接指向block区域

    双间接指向blokc区域

    三间接指向block区域

    前面几个属性我们可以通过描述理解其作用,但是最后面四个属性又是干什么的呢?

    看到上面inode节点包含的属性,我们可以发现inode节点需要记录的属性非常多,但是inode节点却只有128bytes的大小.而inode节点记录一个数据块需要使用4bytes.

    也就是说,假设每个数据块大小为4k.那么一个inode节点最多只能记录4kb*(128/4)=128kb的数据,而且因为inode节点还需要记录其他属性,所以其值远远小于128.

    那么,linux就不能存放大于128kb的数据了吗?当然不是.

    为了能够记录更大的文件,inode节点将记录block的区域分为了12个直接区域,1个间接区域,一个双间接区域,一个三间接区域.

    直接区域,每一个都可以指向一个存放文件内容的区域.

    间接区域,该区域指向一个block,这个block不直接存放文件内容,而是指向其他的数据块,这个被间接指向的数据块才是真正存放数据内容的地方.

    双间接区域,类似于间接区域,但是双间接区域,将第二次指向的数据块再次指向新的数据块,使用这个新的数据块来存放真正的数据,

    三间接区域:顾名思义,该区域的数据经过三次数据块作为中转,才会到达真正的数据存放位置.

    因此,如果每个数据块的大小为1k的话,那么一个inode节点理论上最大存储文件大小为:

    直接区域:12*1k  间接区域 1*(1024/4) 一条block记录占用4bytes,前文已提过. 双间接区域:1*(1024/4)^2 三间接区域:1*(1024^3)

    12+(1024/4)+(1024/4)^2+(1024/4)^3=16gb.这个值也和我们之前所说的我ext2文件系统单个文件最大大小一致.

      

    superblock
    superblock也就是超级块,是记录整个文件系统相关信息的地方,他记录的主要信息有.
    magic签名
    每个数据块的大小
    每个inode节点的大小
    数据块的总量
    inode节点的总量
    未使用的数据块数量
    未使用的inode数量
    文件系统最近挂载时间
    文件系统最近写入时间
    文件系统最近一次检索磁盘时间
    blockGroup的总量
    文件系统是否挂载(valid变量),0表示未挂载,1表示已挂载.
    SuperBlock存储了文件系统的基本信息,如果SuperBlock死掉,那么文件系统也就挂掉了.
    在之前说到BlockGroup的时候,提到过,每一个BlockGroup都会维护自己的inode节点和block以及superBlock区域.
    实际上,并不是左右的BlockGroup都拥有superBlock,因为除了第一个BlockGroup的SuperBlock,其余的SuperBlock都是第一个的备份.
    文件系统描述(FileSystem Description)
    FileSystem Description描述了每个BlockGroup的起始块,以及SuperBlock,bitMap,inodeMap,dataBlock存放在那些数据块中.

    区块对照表(BlockMap)
    我们通过区块对招标,可以查看每个数据块的使用情况,比如当我们需要新建一个文件的时候,我们就需要根据区块对照表查找出未被使用的数据块.
    Inode节点对照表(InodeMap)
    类似于区块对照表,Inode节点对照表用于记录Inode节点的使用情况.

    查看文件的inode号

    1. ls -i 文件名

    2. stat 文件名

    查看文件的inode内容

    英文 别称 中文翻译 何时修改  查看命令
    Access Atime 访问时间 读取、写入 ls  -lu
    Modify Mtime 修改时间 写入、修改 ls  -l
    Change/Create Ctime 改变时间/创建时间 修改文件名、写入、修改、改权限、做链接 ls   -lc

    根据inode号删除指定文件

    在Linux中,有时候会遇到文件名乱码或者存在某些特殊中文的文件,这时候难易通过文件名将它删除。此时,可以尝试使用Tab键进行命令补全使用通配符来跳过 / 匹配特殊字符来使用常规方式将其删除。最佳的解决办法就是针对文件的inode来进行删除。

    对于linux中的任何一个文件都必然有其唯一的inode值,这时候就可以通过inode来删除异常文件名的文件。

    ●利用find命令来删除
             find ./* -inum inode号 -delete   //在当前目录下查找指定inode的文件,然后将其删除

    直接删除,不会询问你确认删除。

    ●利用find命令的-exec参数来调用rm命令
             find ./* -inum inode号 -exec rm -i {} ;
    find会调用rm命令,此时,==rm会询问是否确认删除==。
    如果对rm命令添加-f参数,则强制删除,rm命令不会询问确认删除。

    ●使用xargs配合find的结果进行删除
              find ./* -inum inode号 |xargs rm -f

    查看文件系统的 inode 与 block 的信息

    ●df -i 设备名 (文件系统已挂载时查询,查询 inode 总数与已用数量)

    ●dumpe2fs -h 设备名(文件系统无需挂载,只能查ext系列)

    ●tune2fs  -l   设备名 (文件系统无需挂载,只能查ext系列)

    更改指定文件系统的 inode 个数与 block 大小

    ●mkfs.ext4 -N inode 数 -b 块大小(单位字节)设备名

    示例:mkfs.ext4 -N 10000 -b 1024 /dev/sdb1

    // inode 数设定为 10000 个,block 大小为 1KB

    解决 inode 耗尽导致的磁盘故障

    ●删除不使用的文件

    ●将文件备份,重新格式化此文件系统,指定较多的 inode  个数

    链接

    ●硬链接(hard link)

    (1)方法:ln 源文件 目标文件

    (2)特点:硬链接指向 inode ,新生成的硬链接文件的 inode 号与源文件的 inode 号相同,不可针对目录进行硬链接,必须在同一文件系统内。删除一个文件名,不影响另外一个的访问。【删除源文件,硬链接不受影响】

    ●软连接(soft link)

    (1)方法:ln -s 源文件或目录 目标文件或目录

    (2)特点:软链接指向文件名,新生成的软链接文件的 inode 号与源文件的 inode 号不同,目录也可以生成软链接,软链接文件与源文件可以不在同一文件系统内,软链接文件的内容是源文件的路径,读取时系统会自动导向源文件,但当源文件移动或重命名时,软链接将报错。【移动或重命名源文件,硬链接不受影响,软链接失效】

    恢复误删除的文件

    恢复工具有Extundelete,Debugfs,恢复过程记录如下:

    安装Extundelete

    1. yum install e2fsprogs-devel

    2. yum install e2fsprogs-libs

    首先安装依赖程序

    1. wget https://ncu.dl.sourceforge.net/project/extundelete/extundelete/0.2.4/extundelete-0.2.4.tar.bz2

    下载Extundelete

    1. tar -jxvf extundelete-0.2.4.tar.bz2

    解压缩包

    1. cd extundelete-0.2.4

    进入安装程序目录

    1. ./configure --prefix=/usr/local/extundelete && make && make install

    编译安装

    开始恢复文件

    1. /usr/local/extundelete/bin/extundelete --restore-file 需要恢复的文件名 /dev/vda1

      其中, /usr/local/extundelete/bin/extundelete 是恢复程序的执行路径, --restore-file 的意思是恢复单个文件,后面加上要恢复的文件名, /dev/vda1 是被误删文件的所在位置。

  • 相关阅读:
    Combine 框架,从0到1 —— 4.在 Combine 中使用计时器
    Combine 框架,从0到1 —— 4.在 Combine 中使用通知
    Combine 框架,从0到1 —— 3.使用 Subscriber 控制发布速度
    Combine 框架,从0到1 —— 2.通过 ConnectablePublisher 控制何时发布
    使用 Swift Package Manager 集成依赖库
    iOS 高效灵活地配置可复用视图组件的主题
    构建个人博客网站(基于Python Flask)
    Swift dynamic关键字
    Swift @objcMembers
    仅用递归函数操作逆序一个栈(Swift 4)
  • 原文地址:https://www.cnblogs.com/2567xl/p/11339632.html
Copyright © 2020-2023  润新知