理解 Linux 中的 inodes
inodes 对于Linux是一个很重要的概念,它是 理解文件系统和磁盘存储的关键,理解了 inodes,常见的文件系统相关的问题就会迎刃而解,所以深入了解 inods 对于 Linux 从业者来说是非常有必要的
磁盘存储结构
安装操作系统或格式化磁盘分区的时候,操作系统会自动把磁盘分区分为两个区域 : Block存储区 和 inodes 存储区
Block存储区主要存储文件的内容
inodes存储区是由许多的inode组成的列表,每个 inode 中存储 文件元信息(文件大小,创建者,创建时间等)
以下是 磁盘分区中 Block存储区 和 inodes 存储区 图示:
inode 是什么
inode 是一种数据结构,用来存储文件以下的信息:
1、文件大小
2、文件类型(常规文件、目录、软连接等)
3、权限(读写执行权限)
4、属主(所属用户)
5、属组(所属用户组)
6、链接数(有多少个文件名指向这个inode)
7、文件创建时间
8、文件最近访问时间
9、文件最近修改时间
10、文件内容所在Block位置
可以通过以下命令查看文件的 inode 信息
[root@ecs-centos-7 ~]# stat t.txt
File: ‘t.txt’
Size: 70 Blocks: 8 IO Block: 4096 regular file
Device: fd01h/64769d Inode: 2498227 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-07-19 16:50:14.370189948 +0800
Modify: 2020-07-19 16:50:12.302176601 +0800
Change: 2020-07-19 16:50:12.302176601 +0800
Birth: -
inode 编号
每一个 inode 都有一个编号,系统根据 inode 编号可以快速的计算出 inode 信息在磁盘 inodes 存储区的偏移,然后从中获取 inode 信息,再根据 inode信息中记录的 Block 块位置,从Block存储区读出文件内容
inode 编号在一个文件系统中是唯一的,多个文件系统之间可能会出现相同的编号,前面的磁盘存储结构示意图中 /dev/vda1
和 /dev/vda2
在各自的文件系统中 inode 编号是唯一的
创建一个新文件的时候,文件名和对应的 inode 编号会存储在目录文件的Block块中(关于目录文件后面会讲到)
文件的 inode 信息中记录了文件 Block 块的位置,Block块中存储着文件的内容,可以使用 ls -i
命令查看文件的 inode 编号
[root@ecs-centos-7 ~]# ls -i t.txt
2498227 t.txt
inode 大小
下面的命令是查看每个 inode 节点的大小, 单位是字节
[root@ecs-centos-7 ~]# dumpe2fs -h /dev/vda1 | grep "Inode size"
dumpe2fs 1.42.9 (28-Dec-2013)
Inode size: 256
从例子中可以看出,每个 inode 节点大小为 256 字节。通过 df -i
命令可以查看每个文件系统中 inode 的使用情况
[root@ecs-centos-7 ~]# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
devtmpfs 482393 339 482054 1% /dev
tmpfs 484984 1 484983 1% /dev/shm
tmpfs 484984 433 484551 1% /run
tmpfs 484984 16 484968 1% /sys/fs/cgroup
/dev/vda1 2621440 157202 2464238 6% /
tmpfs 484984 1 484983 1% /run/user/0
字段解释:
Filesystem:文件系统
Inodes: 文件系统中 inodes 总数量
IUsed: inodes 已经使用了的数量
IFree: inodes 可供使用的数量
IUse%: 已经使用了的 inodes 百分比
Mounted on: 文件系统的挂载点
文件系统中的 inodes 数量在安装系统或格式化磁盘分区的时候已经分配好了,也就是说 inodes 数量是有限的,所以 inodes 数量有可能耗尽的,耗尽之后就会出现磁盘还有空间,但是无法创建新文件的情况
目录文件
Linux 中所有的一切都是文件,包括进程、线程、目录等。每个文件都有对应的 inode 编号
当打开目录时,实际上是打开一个目录文件,目录的存储结构是目录子项列表,每个目录子项由 文件名、文件名对应的 inode 编号 组成
上图中是列出了 tmp/ 目录中所有文件,其中第一列是 inode 编号
红框中的 .
表示当前目录,它是当前目录的一个硬链接,和当前目录拥有相同的inode编号。我们执行一个文件需要输入类似 ./test
的命令,命令中的 .
表示的就是当前目录
红框中的 ..
表示当前目录的父目录,它是父目录的一个硬链接,和父目录拥有相同的inode编号。还记得返回上一层目录的命令 cd ..
吗?这里的..
表示的就是当前目录的父目录
系统如何查看文件内容
tmp/ 目录中有 a.txt , b.txt, c.txt 三个文件, 其中 b.txt 是 a.txt 的硬链接,文件内容如下:
[root@ecs-centos-7 tmp]# cat a.txt
this is a.txt file
[root@ecs-centos-7 tmp]# cat c.txt
222
上面的图描述的是查看文件的流程,从图中可以看出 tmp/ 目录文件对应的 Block 块中存储的是该目录下文件名以及文件名对应的 inode 编号,而 a.txt、c.txt 文件对应的 Block 块中存储的是 a.txt 、c.txt 文件的内容
现以查看 a.txt 文件内容为例来说明在文件系统是如何查看文件内容的
1、根据 tmp/ 目录文件对应的 inode 编号(131098) 找到 tmp/ 目录文件对应 Block 数据块
2、从 tmp/ 目录文件对应的 Block 块中找出 a.txt 文件对应的 inode 编号(131101)
3、从 a.txt 文件对应的 inode 信息 中找到对应的 Block 块
4、读出 a.txt 文件对应的 Block 块中的数据(this is a.txt file)
通过 inode 查找文件
如果知道一个文件的 inode 编号,就可以使用以下的命令找到这个文件
[root@ecs-centos-7 ~]# find . -inum 2498227
./t.txt
通过 inode 删除文件
知道了 inode 编号, 用下面的命令可以删除链接到此 inode 的文件
[root@ecs-centos-7 ~]# ls -i ta.txt
2498227 ta.txt
[root@ecs-centos-7 ~]# find -inum 2498227
./ta.txt
[root@ecs-centos-7 ~]# find -inum 2498227 -delete
[root@ecs-centos-7 ~]# find -inum 2498227
[root@ecs-centos-7 ~]#
上面的例子中, ta.txt 的 inode 编号是 2498227 ,当删除编号为 2498227 的文件后, ta.txt 文件被删除了
拷贝、重命名、移动文件
下面的命令分别对文件 ha.txt 进行拷贝,移动,重命名操作
[root@ecs-centos-7 ~]# ls -il ha.txt
2498227 -rw-r--r-- 1 root root 6 Aug 1 01:12 ha.txt
[root@ecs-centos-7 ~]# cp ha.txt ha.txt.bak
[root@ecs-centos-7 ~]# ls -il ha.txt*
2498227 -rw-r--r-- 1 root root 6 Aug 1 01:12 ha.txt
2498236 -rw-r--r-- 1 root root 6 Aug 1 01:13 ha.txt.bak
[root@ecs-centos-7 ~]# mv ha.txt haa.txt
[root@ecs-centos-7 ~]# ls -il haa.txt
2498227 -rw-r--r-- 1 root root 6 Aug 1 01:12 haa.txt
[root@ecs-centos-7 ~]# mkdir testdir
[root@ecs-centos-7 ~]# mv haa.txt testdir/
[root@ecs-centos-7 ~]# ls -il testdir/haa.txt
2498227 -rw-r--r-- 1 root root 6 Aug 1 01:12 testdir/haa.txt
上面的例子中 ha.txt 文件的inode初始编号是 2498227
cp拷贝: ha.txt 拷贝到 testdir/ha.txt 之后,
inode 编号变成 2498236
mv重命名: ha.txt 重命名成 haa.txt,haa.txt文件的 inode 编号和重命名之前的一样,是 2498227
mv移动:haa.txt 移动到 testdir/ 目录中
,移动之后 testdir/haa.txt 的inode 编号和移动之前一样,是 2498227
从上面的例子可以知道:拷贝命令会重新分配新的 inode, 改名以及移动文件只会修改文件名或文件位置,文件的 inode 并不会改变