zoukankan      html  css  js  c++  java
  • 由mv命令引发的对inode的思考

    一场机器迁移引起的思考

    最近团队一台机器老化了,准备做全量迁移,一不小心,就把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.cnblogs.com/peida/archive/2012/10/27/2743022.html

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

    http://www.ruanyifeng.com/blog/2011/12/inode.html

  • 相关阅读:
    c# 创建多线程
    使用opencvsharp通过mvvm在image中显示图片
    c# 创建文件/文件夹对话框
    wpf MVVM框架基础
    wpf DataBinding
    layui自动点击下拉列表的一项并选中
    LayUI默认样式调整
    mysql取某个组的前n条数据
    Kali3.0系统切换中文
    JS触发某元素周围元素的样式改变
  • 原文地址:https://www.cnblogs.com/yuxiuyan/p/13598363.html
Copyright © 2011-2022 走看看