inode和block
概述
-
文件数据包括元信息与实际数据。
-
文件存储在硬盘上,硬盘最小存储单位是“扇区”,每个扇区存储512字节。
-
block(块)
- 连续的八个扇区组成一个block
- 是文件存取的最小单位
-
inode(索引节点)
- 中文译名为“索引节点”,也叫 i 节点
- 用于存储文件元信息
- 一个文件必须占用一个inode ,至少占用一个block
关系
-
文件是存储在硬盘上的,硬盘的最小存储单位叫做“扇区”(sector),每个扇区存储512字节。
-
一般连续八个扇区组成一个"块”(block),一个块是4K大小,是文件存取的最小单位。操作系统读取硬盘的时候,是一次性连续读取多个扇区,即一个块一个块的读取的。
-
文件数据包括实际数据与元信息(类似文件属性)。文件数据存储在“块"中,存储文件元信息(比如文件的创建者、创建日期、文件大小、文件权限等)的区域就叫做inode。 因此,一个文件必须占用一个inode,并且至少占用一个block。
-
inode不包含文件名。文件名是存放在目录文件夹当中的。Linux 系统中一切皆文件,因此目录也是一种文件。
-
每个inode都有一个号码,操作系统用inode号码来识别不同的文件。Linux系统内部不使用文件名,而使用inode号码来识别文件。对于系统来说,文件名只是inode号码便于识别的别称,文件名和inode号码是一一对应关系,每个inode号码对应一个或多个文件名。
-
所以,当用户在Linux系统中试图访问一个文件时,系统会先根据文件名去查找自己文件夹中的目录项,之后找到对应的inode号码;通过inode号码,获取inode信息;根据inode信息,看该用户是否具有访问这个文件的权限;如果有,就指向相对应的数据block,并读取数据。
inode
inode 表结构
每个文件的属性信息,比如:文件的大小,时间,类型,权限等,称为文件的元数据(meta data)。
元数据是存放在inode(index node)表中。inode 表中有很多条记录组成,第一条记录对应的存放了一个文件的元数据信息。
每一个inode表记录对应保存了文件的元信息:
- inode number 节点号
- 文件类型
- 文件的读、写、执行权限
- 文件属主的UID
- 文件属组的GID
- 链接数(指向这个文件名路径名称个数)
- 该文件的大小和不同的时间戳
- 指向磁盘上文件的数据块指针
- 有关文件的其他数据
Linux系统文件三个主要的时间属性
-
atime(access time):最近访问
最后一次访问文件的时间
-
mtime(modify):最近更改
最后一次更改文件内容的时间
-
ctime(change time):最近改动
最后一次改变文件元信息的时间
注意:
- 不打开文件的话,atime不变。例如使用echo追加内容,atime不会变,因为文件没有被打开访问。
- 修改文件内容的话,mtime会变,ctime也会变。
- 如果只修改文件的权限,ctime变,mtime不变。
目录文件的结构
目录是个特殊文件,目录文件的内容保存了此目录中文件的列表,以及inode number对应关系。
- 目录文件的结构非常简单,就是一系列目录项(dirent)的列表。
- 每个目录项,由两部分组成:所包含文件的文件名,以及该文件名对应的inode号码。
- 一个目录是目录下的文件名和文件inode号之间的映射。
- 每个inode都有一个号码,操作系统用inode号码来识别不同的文件。
- Linux系统内部不使用文件名,而使用inode号码来识别文件。
- 对于用户,文件名只是Inode号码便于识别的别称。
inode的号码
用户通过文件名打开文件时,系统内部的过程:
-
用户访问文件时,系统先去查找文件所属目录中的目录项,根据文件名找到对应的inode号码。
-
通过inode号码,获取inode信息。
-
根据inode信息,判断用户是否具备访问权限。
- 如果有访问权限,则利用指针去指向实际数据所在的block,读出数据。
- 如果没有访问权限,则返回Permission denied。根据inode信息,利用指针去指向实际数据所在的block,读出数据。 查看inode号码的方法:
- ls -i 命令:查看文件名对应的inode号码
- stat 命令:查看文件inode信息中的inode号码
[root@localhost data]# ls -i
64 aa 64 bb 64 mail
[root@localhost data]# stat /data/aa
文件:"/data/aa"
大小:37 块:0 IO 块:4096 目录
设备:811h/2065d Inode:64 硬链接:2
权限:(0755/drwxr-xr-x) Uid:( 0/ root) Gid:( 0/ root)
最近访问:2023-04-17 09:48:00.762262741 +0800
最近更改:2023-04-17 09:47:58.462261957 +0800
最近改动:2023-04-17 09:47:58.462261957 +0800
创建时间:-
inode 与文件存储
硬盘分区后的结构
inode 的大小
-
inode也会消耗硬盘空间
- 每个inode的大小一般是128字节或256字节
-
格式化文件系统时确定inode的总数
- 如果磁盘还有空间,但inode号被全部占用,也无法创建新文件。
- inode号在同一个文件系统内唯一,在不同的文件系统中可以重复。
-
使用 "df -i" 命令可以查看每个硬盘分区的inode总数和已经使用的数量
[root@localhost ~]# df -i
文件系统 Inode 已用(I) 可用(I) 已用(I)% 挂载点
/dev/mapper/centos-root 20078592 146484 19932108 1% /
devtmpfs 229401 458 228943 1% /dev
tmpfs 233381 1 233380 1% /dev/shm
tmpfs 233381 671 232710 1% /run
tmpfs 233381 16 233365 1% /sys/fs/cgroup
/dev/sda1 524288 329 523959 1% /boot
/dev/mapper/centos-home 9801728 381 9801347 1% /home
tmpfs 233381 18 233363 1% /run/user/0
/dev/sr0 0 0 0 - /run/media/root/CentOS 7 x86_64
tmpfs 233381 22 233359 1% /run/user/2007
inode的特殊作用
由于inode号码与文件名分离,导致一些Unix/Linux系统具有以下的现象:
当文件名包含特殊字符,可能无法正常删除文件,直接删除inode,也可以删除文件。
[root@localhost jlx]# ls -i //查看文件的inode号
68101626 1.txt 3600 24 102875075 25 68101629 2.txt
[root@localhost jlx]# find -inum 3600 -delete //通过inode号删除文件
[root@localhost jlx]# ls //查看目录内容,文件已被删除
1.txt 25 2.txt
在同一个文件系统中移动或重命名文件时,只改变文件名,不影响inode号码。
[root@localhost jlx]# ls -i 1.txt
68101626 1.txt
[root@localhost jlx]# mv 1.txt ../pp/2.txt
[root@localhost jlx]# ls -i ../pp/2.txt
68101626 ../pp/2.txt
命令和inode号之间的关系
cp 命令:
- 分配一个空闲的inode号,在inode表中生成新条目
- 在目录中创建一个目录项,将名称与inode编号关联
- 拷贝数据生成新的文件
rm 命令:
- 硬链接数递减,从而释放的inode号可以被重用
- 把数据块放在空闲列表中
- 删除目录项
- 数据实际上不会马上被删除,但当另一个文件使用数据块时将被覆盖
mv命令:
-
如果mv命令的目标和源在同一设备,
不影响inode表(除时间戳)或磁盘上的数据位置;
系统会删除旧的目录对应关系,新建目录对应关系。
硬链接和软链接
对比项 | 硬链接 | 软链接(符号链接) |
---|---|---|
本质 | 本质是同一个文件 | 本质不是同一个文件 |
inode | 和源文件相同 | 和源文件不同 |
链接数 | 创建新的硬链接,链接数会增加;删除硬链接,链接数减少 | 删除新建不会改变 |
目录 | 不支持给目录创建 | 支持 |
删除源文件 | 只是链接数减一,但链接文件的访问不受影响 | 无法访问链接文件 |
文件类型 | 和源文件相同 | 链接文件,和源文件无关 |
文件大小 | 和源文件相同 | 源文件的路径的长度 |
能否交叉文件系统 | 不支持 | 支持 |
对不存在的文件 | 不支持创建硬链接 | 支持创建软链接 |
创建链接文件:
ln 源文件 目标文件 //创建硬链接文件
ln -s 源文件或目录 目标文件 //创建软连接文件
注意:
创建软链接时,源文件必须使用绝对路径。
删除文件后空间不释放的处理方法
删除文件后,如果磁盘空间没有释放,是因为文件正在被其他人打开。 其他人退出使用该文件后空间会被释放。
可以使用 w 命令或 lsof 命令查看是否有人在使用该文件。
[root@localhost ~]# w
22:23:08 up 1:14, 4 users, load average: 0.17, 0.14, 0.08
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.177.1 21:17 4.00s 0.12s 0.03s vim 1.txt
root pts/1 192.168.177.1 21:17 1:05m 4.45s 4.43s top
root pts/2 192.168.177.1 22:22 4.00s 0.02s 0.00s w
root pts/3 192.168.177.1 22:22 11.00s 0.04s 0.01s top
如果确定有人打开了该文件,可以使用三种方法释放空间:
1.echo " " > f1.txt //将被打开的文件变成空文件,依赖shell环境
2.cat /dev/null > f1.txt //导入空文件
3.lsof | grep f1.txt //查看被删除的文件和对应PID,之后杀死该进程
kill -9 PID