既然要详细的了解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
-
yum install e2fsprogs-devel
- yum install e2fsprogs-libs
首先安装依赖程序
-
wget https://ncu.dl.sourceforge.net/project/extundelete/extundelete/0.2.4/extundelete-0.2.4.tar.bz2
下载Extundelete
-
tar -jxvf extundelete-0.2.4.tar.bz2
解压缩包
-
cd extundelete-0.2.4
进入安装程序目录
-
./configure --prefix=/usr/local/extundelete && make && make install
编译安装
开始恢复文件
-
/usr/local/extundelete/bin/extundelete --restore-file 需要恢复的文件名 /dev/vda1
其中, /usr/local/extundelete/bin/extundelete
是恢复程序的执行路径, --restore-file
的意思是恢复单个文件,后面加上要恢复的文件名, /dev/vda1
是被误删文件的所在位置。