一、inode是什么?

  理解inode,要从文件储存说起。文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector)。每个扇区储存512字节(相当于0.5KB)。操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最常见的是4KB,即连续八个 sector组成一个 block。文件数据都储存在"块"中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为"索引节点"。
 
二、inode的内容
  inode包含文件的元信息,具体来说有以下内容:
    * 文件的字节数
    * 文件拥有者的User ID
    * 文件的Group ID
    * 文件的读、写、执行权限
    * 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。
    * 链接数,即有多少文件名指向这个inode
    * 文件数据block的位置
  可以用stat命令,查看某个文件的inode信息:
    stat example.txt
  总之,除了文件名以外的所有文件信息,都存在inode之中。至于为什么没有文件名,下文会有详细解释。
 
三、inode的大小
  inode也会消耗硬盘空间,所以硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定,一般是每1KB或每2KB就设置一个inode。假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整块硬盘的12.8%。

  查看每个硬盘分区的inode总数和已经使用的数量,可以使用df命令:

    df -i
   查看每个inode节点的大小,可以用如下命令:
    sudo dumpe2fs -h /dev/hda | grep "Inode size"
   由于每个文件都必须有一个inode,因此有可能发生inode已经用光,但是硬盘还未存满的情况。这时,就无法在硬盘上创建新文件。
四、inode号
  每个inode都有一个号,操作系统用inode号来识别不同的文件。

  这里值得重复一遍,Unix/Linux系统内部不使用文件名,而使用inode号码来识别文件。对于系统来说,文件名只是inode号码便于识别的别称或者绰号。表面上,用户通过文件名,打开文件。实际上,系统内部这个过程分成三步:首先,系统找到这个文件名对应的inode号码;其次,通过inode号,获取inode信息;最后,根据inode信息,找到文件数据所在的block,读出数据。

   使用ls -i命令,可以看到文件名对应的inode号:
    ls -i example.txt
 
五、目录文件
  Unix/Linux系统中,目录(directory)也是一种文件。打开目录,实际上就是打开目录文件。
  目录文件的结构非常简单,就是一系列目录项(dirent)的列表。每个目录项,由两部分组成:所包含文件的文件名,以及该文件名对应的inode号码。

  ls命令只列出目录文件中的所有文件名:

    ls /etc
   ls -i命令列出整个目录文件,即文件名和inode号码:
    ls -i /etc
   如果要查看文件的详细信息,就必须根据inode号,访问inode节点,读取信息。ls -l命令列出文件的详细信息。
    ls -l /etc
 
六、硬链接
  一般情况下,文件名和inode号码是"一一对应"关系,每个inode号码对应一个文件名。但是,Unix/Linux系统允许,多个文件名指向同一个inode号码。这意味着,可以用不同的文件名访问同样的内容;对文件内容进行修改,会影响到所有文件名;但是,删除一个文件名,不影响另一个文件名的访问。这种情况就被称为"硬链接"(hard link)。
   ln命令可以创建硬链接:
    ln 源文件 目标文件
   运行上面这条命令以后,源文件与目标文件的inode号码相同,都指向同一个inode。inode信息中有一项叫做"链接数",记录指向该inode的文件名总数,这时就会增加1。反过来,删除一个文件名,就会使得inode节点中的"链接数"减1。当这个值减到0,表明没有文件名指向这个inode,系统就会回收这个inode号码,以及其所对应block区域。

  这里顺便说一下目录文件的"链接数"。创建目录时,默认会生成两个目录项:"."和".."。前者的inode号码就是当前目录的inode号码,等同于当前目录的"硬链接";后者的inode号码就是当前目录的父目录的inode号码,等同于父目录的"硬链接"。所以,任何一个目录的"硬链接"总数,总是等于2加上它的子目录总数(含隐藏目录),这里的2是父目录对其的“硬链接”和当前目录下的".硬链接“。

七、软链接
  除了硬链接以外,还有一种特殊情况。文件A和文件B的inode号虽然不一样,但是文件A的内容是文件B的路径。读取文件A时,系统会自动将访问者导向文件B。因此,无论打开哪一个文件,最终读取的都是文件B。这时,文件A就称为文件B的"软链接"(soft link)或者"符号链接(symbolic link)。

  这意味着,文件A依赖于文件B而存在,如果删除了文件B,打开文件A就会报错:"No such file or directory"。这是软链接与硬链接最大的不同:文件A指向文件B的文件名,而不是文件B的inode号码,文件B的inode"链接数"不会因此发生变化。

  ln -s命令可以创建软链接。

    ln -s 源文文件或目录 目标文件或目录
 
八、实验软硬连接

  [oracle@Linux]$ touch f1          #创建一个测试文件f1
  [oracle@Linux]$ ln f1 f2          #创建f1的一个硬连接文件f2
  [oracle@Linux]$ ln -s f1 f3       #创建f1的一个符号连接文件f3
  [oracle@Linux]$ ls -li            # -i参数显示文件的inode节点信息
  total 0
  9797648 -rw-r--r--  2 oracle oinstall 0 Apr 21 08:11 f1
  9797648 -rw-r--r--  2 oracle oinstall 0 Apr 21 08:11 f2
  9797649 lrwxrwxrwx  1 oracle oinstall 2 Apr 21 08:11 f3 -> f1

  从上面的结果中可以看出,硬连接文件f2与原文件f1的inode节点相同,均为9797648,然而符号连接文件的inode节点不同。

  [oracle@Linux]$ echo "I am f1 file" >>f1
  [oracle@Linux]$ cat f1
  I am f1 file
  [oracle@Linux]$ cat f2
  I am f1 file
  [oracle@Linux]$ cat f3
  I am f1 file
  [oracle@Linux]$ rm -f f1
  [oracle@Linux]$ cat f2
  I am f1 file
  [oracle@Linux]$ cat f3
  cat: f3: No such file or directory

  通过上面的测试可以看出:当删除原始文件f1后,硬连接f2不受影响,但是符号连接f1文件无效

  依此您可以做一些相关的测试,可以得到以下全部结论:
    1).删除符号连接f3,对f1,f2无影响;
    2).删除硬连接f2,对f1,f3也无影响;
    3).删除原文件f1,对硬连接f2没有影响,导致符号连接f3失效;
    4).同时删除原文件f1,硬连接f2,整个文件会真正的被删除。

九、inode的特殊作用
  由于inode号与文件名分离,这种机制导致了一些Unix/Linux系统特有的现象。
    1. 有时,文件名包含特殊字符,无法正常删除。这时,直接删除inode节点,就能起到删除文件的作用。
    2. 移动文件或重命名文件,只是改变文件名,不影响inode号。
    3. 打开一个文件以后,系统就以inode号来识别这个文件,不再考虑文件名。因此,通常来说,系统无法从inode号得知文件名。
      第3点使得软件更新变得简单,可以在不关闭软件的情况下进行更新,不需要重启。因为系统通过inode号码,识别运行中的文件,不通过文件名。更新的时候,新版文件以同样的文件名,生成一个新的inode,不会影响到运行中的文件。等到下一次运行这个软件的时候,文件名就自动指向新版文件,旧版文件的inode则被回收。

十、实际问题

  在一台配置较低的Linux服务器(内存、硬盘比较小)的/data分区内创建文件时,系统提示磁盘空间不足,用df -h命令查看了一下磁盘使用情况,发现/data分区只使用了66%,还有12G的剩余空间,按理说不会出现这种问题。 后来用df -i查看了一下/data分区的索引节点(inode),发现已经用满(IUsed=100%),导致系统无法创建新目录和文件。

  查找原因:
    /data/cache目录中存在数量非常多的小字节缓存文件,占用的Block不多,但是占用了大量的inode。
  解决方案:
    1、删除/data/cache目录中的部分文件,释放出/data分区的一部分inode。    
    2、用软连接将空闲分区/opt中的newcache目录连接到/data/cache,使用/opt分区的inode来缓解/data分区inode不足的问题: 
      ln -s /opt/newcache /data/cache

done!

  

转自:

  http://www.cnblogs.com/itech/archive/2009/04/10/1433052.html

  http://www.cnblogs.com/itech/archive/2012/05/15/2502284.html

inode、软连接、硬链接的更多相关文章

  1. [转帖]详解Linux系统inode原理--硬链接、软链接、innodb大小和划分等

    详解Linux系统inode原理--硬链接.软链接.innodb大小和划分等 原创 波波说运维 2019-07-17 00:03:00 https://www.toutiao.com/i6713116 ...

  2. 认识Linux系统中的inode,硬链接和软链接

    在学习和创建软链接遇到了一点问题,总结一下: 在当前文件夹下面建立了两个临时文件夹tempdir1和tempdir2,然后在tempdir2里面创建了一个hello文件,然后用指令ln -s temp ...

  3. 深入理解inode和硬链接和软连接和挂载点

    inode 一.inode是什么? 理解inode,要从文件储存说起. 扇区 文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector).每个扇区储存512字节(相当于0.5 ...

  4. Linux入门之常用命令(10)软连接 硬链接

    在Linux系统中,内核为每一个新创建的文件分配一个Inode(索引结点),每个文件都有一个惟一的inode号.文件属性保存在索引结点里,在访问文件时,索引结点被复制到内存在,从而实现文件的快速访问. ...

  5. inode 软/硬链接

    一.inode是什么? 理解inode,要从文件储存说起. 文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector).每个扇区储存512字节(相当于0.5KB). 操作系统 ...

  6. Linux:ln命令详解(软连接,硬链接)

    ln ln命令用来为文件创件连接,连接类型分为硬连接和软连接(符号连接)两种,默认的连接类型是硬连接.如果要创建软连接必须使用"-s"选项. 硬链接 建立硬链接时,在另外的目录或本 ...

  7. Linux 软连接 & 硬链接

    1.Linux链接概念Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link).默认情况下,ln命令产生硬链接. [硬连接]硬连接指通过索引节点 ...

  8. linux之软连接 硬链接 link ln

    p.p1 { margin: 0; font: 12px "Helvetica Neue"; color: rgba(220, 161, 13, 1) } p.p2 { margi ...

  9. [svc]linux的inode和block-软硬链接

    磁盘结构 容量 磁盘结构 磁盘容量 = 一个柱面大小柱面的总数 = 磁头数量每个磁道上的扇区数一个扇区大小柱面总数 存储容量=磁头数 × 磁道(柱面)数 × 每道扇区数 × 每扇区字节数 了解-什么是 ...

  10. linux基础进阶命令详解(输出重定向(2>&1,1>&2,&>file)、输入重定向、管道符、通配符、三种引号、软连接、硬链接、根“/”、绝对路径vs相对路径)

    本章命令(共9个): 1 2 3 4 5 6 7 8 9 输出重定向 输入重定向 管道符 通配符 三种引号 软连接 硬链接 根"/" 绝对路径vs相对路径 1.输出重定向 作用:一 ...

随机推荐

  1. HttpClient 模拟登录搜狐微博

    http://mengyang.iteye.com/blog/575671 第一次遇到一个这样的问题,"PKIX path building failed" 异常   详解异常:  ...

  2. python中给程序加锁之fcntl模块的使用

    python 中给文件加锁——fcntl模块import fcntl 打开一个文件##当前目录下test文件要先存在,如果不存在会报错.或者以写的方式打开f = open('./test')对该文件加 ...

  3. Runtime.getRuntime().exec()----记录日志案例

    Runtime.getRuntime().exec()方法主要用于运行外部的程序或命令. Runtime.getRuntime().exec共同拥有六个重载方法: 1.public Process e ...

  4. PHP RSA加解密示例(转)

    1.生成密钥和公钥 开始前需要准备openssl环境 linux 需要安装openssl工具包,传送门http://www.openssl.org/source/ window 下需要安装openss ...

  5. Java设计模式(九)责任链模式 命令模式

    (十七)责任链模式 责任链模式的目的是通过给予多个对象处理请求的机会,已解除请求发送者与接受者之间的耦合关系.面对对象的开发力求对象之前保持松散耦合,确保对象各自的责任最小化.这种设计能够使得系统更加 ...

  6. HDFS源码分析EditLog之读取操作符

    在<HDFS源码分析EditLog之获取编辑日志输入流>一文中,我们详细了解了如何获取编辑日志输入流EditLogInputStream.在我们得到编辑日志输入流后,是不是就该从输入流中获 ...

  7. 21-nginx单机1W并发优化

    一:优化思路 (1)建立socket连接 (2)打开文件,并沿socket返回.二:优化  (1) 修改nginx.conf 进程数量 默认是1024 改成20140 worker_rlimit_no ...

  8. RRDTool详解(转)

    原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处.作者信息和本声明.否则将追究法律责任.http://freeloda.blog.51cto.com/2033581/1307492 大纲 ...

  9. MySQL 创建自定义函数(2)

    说明:下面创建一个函数,调用自定义函数返回一个返回一个随机数. (1) 创建自定义函数

  10. T-SQL高级查询语句(父子查询)

    T-SQL高级查询语句 高级查询 1.连接查询,对结果集列的扩展 select * from info select * from info,nation #形成笛卡尔积 select * from ...