您的位置:首页 > Web前端 > Node.js

由mv命令引发的对inode的思考

haotielili 2020-09-01 20:21 453 查看 https://www.cnblogs.com/yuxiuy

一场机器迁移引起的思考

最近团队一台机器老化了,准备做全量迁移,一不小心,就把100多个G的/data目录放到了新机器的/data/data目录下,上愁了,怎么削减一层data目录呢?难倒像Windows一样剪切过来吗?可是有100多个G啊?!抱着试试的心态,运行mv命令,没想到系统瞬间就完成了。为什么Linux可以这么快速剪切呢?这一切都要从Linux对文件的管理机制说起的。

inode是什么

要想理解inode,就要从Linux的文件存储开始说起。

文件存储在硬盘上,硬盘上最小的存储单位叫做“扇区”(sector),每一个扇区存储512字节。

操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最常见的是4KB,即连续八个 sector组成一个 block。

文件数据都储存在"块"中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为"索引节点"。

每一个文件都有对应的inode,里面包含了与该文件有关的一些信息。

inode包含文件的元信息,具体来说有以下内容:

  • 文件的字节数。
  • 文件拥有者的User ID。
  • 文件的Group ID。
  • 文件的读、写、执行权限。
  • 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。
  • 链接数,即有多少文件名指向这个inode。
  • 文件数据block的位置。

想要查看文件的inode信息,可以通过stat命令。

每一个inode都有一个编号,就像上面,inode编号为5278,操作系统就靠inode编号来识别文件。

强调一点,Linux不使用文件名,而是使用inode编号识别不同文件。

对于用户来说,通过文件名打开了文件;但是对于系统来说,首先,系统找到文件名对应的inode编号,通过这个编号获取了inode信息,再根据这个信息,找到文件数据所在的block,读取数据并显示。

目录文件

Linux中,目录(directory)本身也是一种文件。我们打开目录,其实就是打开了目录本身这个文件。

目录文件的结构很简单,就是一系列目录项(dirent)的列表。每个目录项包括两部分:所包含文件的文件名,以及该文件名对应的inode编号。也就是说,目录文件其实就是包含了文件名与inode编号的映射的集合。

通过ls -i命令可以查看文件名和inode编号。

理解了上面这些,就能理解目录的权限。目录文件的读权限(r)和写权限(w),都是针对目录文件本身。由于目录文件内只有文件名和inode号码,所以如果只有读权限,只能获取文件名,无法获取其他信息,因为其他信息都储存在inode节点中,而读取inode节点内的信息需要目录文件的执行权限(x)。

mv命令与inode

当运行mv命令后,构成这个文件的实际内容,不管是inode还是硬盘数据,都没有被转移。被改变的,仅仅是目录的映射(文件名与inode之间的映射)。

如果目标文件和原文件在同一个文件系统,mv会在目录映射表新建一行,删除带有源文件名的原有目录行。

如果目标文件和原文件不在同一个文件系统,mv就相当于cp与rm命令的组合。

cp命令:分配一个没有被使用的inode编号,在inode表中增加新项目,然后在目录映射表中新增一行,关联文件名与inode编号。

rm命令:递减链接计数,释放inode编号。然后把数据块挂载到可用空间,再删除目录映射表中相关行。

我们可以看到,其中底层数据并没有被删除,只是被标记为了可用,当数据块被另一个文件利用时,原来的数据就会被覆盖。

inode带来的特殊现象(热更新)

由于inode号码与文件名分离,这种机制导致了一些Unix/Linux系统特有的现象。

有时,文件名包含特殊字符,无法正常删除。这时,直接删除inode节点,就能起到删除文件的作用。

移动文件或重命名文件,只是改变文件名,不影响inode号码。

打开一个文件以后,系统就以inode号码来识别这个文件,不再考虑文件名。因此,通常来说,系统无法从inode号码得知文件名。

第3点使得软件更新变得简单,可以在不关闭软件的情况下进行更新,不需要重启。因为系统通过inode号码,识别运行中的文件,不通过文件名。更新的时候,新版文件以同样的文件名,生成一个新的inode,不会影响到运行中的文件。等到下一次运行这个软件的时候,文件名就自动指向新版文件,旧版文件的inode则被回收。

参考:

https://zh.wikipedia.org/wiki/Inode

https://www.geek-share.com/detail/2562351621.html

http://c.biancheng.net/cpp/html/2780.html

https://www.geek-share.com/detail/2746094361.html

标签: