说说inode

曾经碰到过Linux ext3硬盘分区明明有空间但无法创建新文件的“妖异”事件,当初仅仅知道是由于inode空间被用满所导致。一段时间过去,回过头来重新理解下inode。

记得很多人通过各种渠道询问为什么 Linux/Unix没有类似于windows系统下的“磁盘碎片整理工具”,大多数的回应都是将话题转移到了*nix的文件系统如何如何先进上,底层次的深究就不再进行下去。其实这就是inode存在的意义。

inode是什么?

inode其实就是一个索引结点,存放了许多文件信息,可以直接通过stat 文件名的方式获取:

root@www:~# stat test.txt
File: `test.txt'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd01h/64769d Inode: 137295 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2012-11-20 09:18:00.277494826 +0800
Modify: 2012-11-20 09:18:00.277494826 +0800
Change: 2012-11-20 09:18:00.277494826 +0800
Birth: -

File是文件名,Size是文件大小以及是否是一个符号链接,Device是该文件存放的磁盘/磁盘簇(block)位置以及对应的链接计数器,第一个Access是用户的属组和权限,第二个Access是上次访问时间(很奇怪的lable设置),Modify/change分别是上次修改时间和变动时间(系统级别的)。

为什么*nix会有软硬链接?软硬链接有什么区别?

*nix文件系统的一个特色是支持通过ln命令创建一个链接标示,不同的是-s参数创建一个软链接时,仅仅只是针对文件名的映射;而不加-s的硬链接则是重用源文件的inode并将link数量增加。在删除源文件之后,由于link数-1不为0,硬链接依然有效,但源文件已经不存在,软链接宣告失效。

一旦删除操作导致linke数为0系统将回收inode编号,重用文件所在的簇。

root@www:~# ln -s test.txt test_soft_link.txt
root@www:~# stat test_soft_link.txt
File: `test_soft_link.txt' -> `test.txt' <---指定了源文件名

Size: 8 Blocks: 0 IO Block: 4096 symbolic link <--- 是一个符号链接
Device: fd01h/64769d Inode: 131800 Links: 1 <--- 物理位置不变,inode编号改变,link数为1
Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2012-11-20 09:54:29.585511045 +0800
Modify: 2012-11-20 09:54:27.473489887 +0800
Change: 2012-11-20 09:54:27.473489887 +0800
Birth: -

root@www:~# ln test.txt test_hard_link.txt
root@www:~# stat test_hard_link.txt
File: `test_hard_link.txt'  <---没有指定源文件名
Size: 0 Blocks: 0 IO Block: 4096 regular empty file <---  是一个真实文件
Device: fd01h/64769d Inode: 137295 Links: 2  <--- 物理位置不变,inode编号不变,link数+1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2012-11-20 09:18:00.277494826 +0800
Modify: 2012-11-20 09:18:00.277494826 +0800
Change: 2012-11-20 09:54:59.497502632 +0800
Birth: -
root@www:~# rm test.txt

root@www:~# stat test_soft_link.txt
File: `test_soft_link.txt' -> `test.txt' <--- 文件名不变
Size: 8 Blocks: 0 IO Block: 4096 symbolic link
Device: fd01h/64769d Inode: 131800 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2012-11-20 09:54:29.585511045 +0800
Modify: 2012-11-20 09:54:27.473489887 +0800
Change: 2012-11-20 09:54:27.473489887 +0800
Birth: -

root@www:~# stat test_hard_link.txt
File: `test_hard_link.txt'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd01h/64769d Inode: 137295 Links: 1 <--- 物理位置不变,inode编号不变,link数-1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2012-11-20 09:18:00.277494826 +0800
Modify: 2012-11-20 09:18:00.277494826 +0800
Change: 2012-11-20 10:03:50.697496349 +0800
Birth: -

 inode的分配

inode的分配情况可以通过df -i 的方式获得,df -ih则是可读优化的结果:

root@www:~# df -ih
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/vda1 448K 114K 335K 26% /
udev 61K 395 61K 1% /dev
tmpfs 62K 281 62K 1% /run
none 62K 1 62K 1% /run/lock
none 62K 1 62K 1% /run/shm

一个文件系统在被创建的同时,会创建一个数据区和一个inode区,默认情况下每2个硬盘簇设置一个inode,每个inode的大小为256bit(部分系统为128bit)。当系统中充斥着大量的仅占一个簇的琐碎文件或者大量的链接文件时就会导致我一开头提及的妖异问题。避免这种情况的发生只有在一开始格式化磁盘时通过mkfs的 -N参数手工指定inode数量。

由于这个过程事实上是一个重新格式化的动作,在操作前需要umount并且需要备份该分区下所有文件。

inode的“滥用”

系统中可以通过ls -i命令查看文件的inode编号

root@www:~# ls -i
131818 test_hard_link.txt 131800 test_soft_link.txt 135712 test.txt

系统在底层操作文件的时候,事实上仅仅只需要获取inode编号即可,跟文件名无关。文件在同一分区下做mv时,事实上并不会改动inode编号。假设一个文件被某一进程使用的时候,文件被mv,由于系统仅仅只跟inode编号打交道,文件的修改仍然会被写入新的文件名中。

为什么linux不需要磁盘碎片整理

不同于windows的存储方式,因为有inode索引的存在,磁盘上的文件都是连续存放的,这也就意味着每次读取文件时磁头的活动都是连续的,可以理解为不会产生磁盘碎片。

root@www:/var/log/nginx# stat access.log
  File: `access.log'
  Size: 338241    	Blocks: 672        IO Block: 4096   regular file
Device: fd01h/64769d	Inode: 263587      Links: 1
Access: (0640/-rw-r-----)  Uid: (   33/www-data)   Gid: (    4/     adm)
Access: 2012-11-20 06:55:07.893496000 +0800
Modify: 2012-11-20 11:05:00.545496324 +0800
Change: 2012-11-20 11:05:00.545496324 +0800
 Birth: -

#access.log文件存放位置为 fd01h/64769d开始的672个大小为4096字节簇

“说说inode”的2个回复

  1. zhiwei :

    还有个问题就是ext3的单个目录只能容纳3万个文件,超过之后也不能创建文件了。

    ext3的文件系统子目录中最多只能支持32000个文件,加上’.’和’..’理论上最大只有31998个文件。这不是ext3文件系统本身的限制,而是Linux为了避免过多的文件影响到读取性能而在内核中进行了软性的规避,或者不客气的说是遵守了ext2时代的限制。

    以最新的Linux 3.5.7内核为例:

    include/linux/ext2_fs.h
     24 /*
     25  * Maximal count of links to a file
     26  */
     27 #define EXT2_LINK_MAX           32000
    

    fs/ext3/ext3.h
      72 /*
      73  * Maximal count of links to a file
      74  */
      75 #define EXT3_LINK_MAX           32000
    

    同样的,作为网上一直宣传没有限制的ext4事实上也有这个限制,只是提高到了65000

    fs/ext4/ext4.h
     242 /*
     243  * Maximal count of links to a file
     244  */
     245 #define EXT4_LINK_MAX           65000
    

    如果确实有变态的需求不能满足,不妨把这个数值自行调整,重编内核即可,但这个数值最终的限制还是在于inode的数量。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

请补全下列算式: *

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据