文件简介
linux下一切皆文件,包括内存,磁盘,网络都可以用文件的形式表示。操作系统的主要功能之一就是文件管理,所以文件是一种非常重要的资源。目录是一种特殊的文件,他的存储文件的名称和相关信息。
文件组成
文件主要由两部分组成,一是文件的元信息,由inode表示,二是文件的数据,由block表示
inode
用于存储文件的各属性,如下表
元数据 | 说明 |
---|---|
所有者信息 | owner, group, other |
权限信息 | read, write, execute |
时间信息 | 修改时间(mtime),访问时间(atime),状态时间(ctime) |
标志信息 | 文件的一些flag |
链接数 | 有多少文件名指向这个inode |
内容信息 | type, size和对应的block的位置信息 |
- inode也会消耗硬盘空间,所以硬盘格式化的时候,操作系统自动将硬盘分成两个区域。
- 一个是数据区,存放文件数据,另一个是inode区(inode table),存放 文件元信息。
- 每个inode节点的大小,一般是128字节或256字节。
- inode节点的总数,在格式化时就给定,一般是每1KB或每2KB就设置一个inode。
- 假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整块硬盘的12.8%
block
用来存储文件的内容数据
软链接和硬链接
软链接
- 软链接(也叫符号链接)是指向另一个文件的特殊文件,这种文件的数据部分仅包含它所要链接文件的路径名。
- 软链接是为了克服硬链接的不足而引入的,软链接不直接使用inode号作为文件指针,而是使用文件路径名作为指针(软链接:文件名+数据部分‐‐>目标文件的路径名)。
- 软链接有自己的inode,并在磁盘上有一小片空间存放路径名。因此,软链接能够跨文件系统,也可以和目录链接。
- 软链接可以对一个不存在的文件名进行链接,但直到这个名字对应的文件被创建后,才能打开其链接。
- 当软链接指向的文件删除重命名或移动后,软链接并不会发生更新。
硬链接
- 硬链接是通过索引节点进行的链接。
- 该登记项具有一个新的文件名和要连接文件的inode 号,文件的目录登记项就是源文件的硬链接(硬链接,目录登记项: 文件名‐‐>文件的inode;文件名可以有多个,但文件inode 只是一个)。
- 不论一个文件有多少硬链接,在磁盘上只有一个描述它的inode,只要该文件的链接数不为0,该文件就保持存在。硬链接不能跨越文件系统,为避免无限递归,一般也不能在目录上建立hard link。
- 硬连接是直接建立在节点表上的(inode),建立硬连接指向一个文件的时候,会更新节点表上面的计数值。举个例子,一个文件被连接了两次(硬连接),这个文件的计数值是3,而无论通过3个文件名中的任何一个访问,效果都是完全一样的,但是如果删除其中任意一个,都只是把计数值减1,不会删除实际的内容的,(任何存在的 文件本身就算是一个硬连接)只有计数值变成0也就是没有任何硬连接指向的时候才会真实的删除内容。
- 对任何一个硬链接文件修改,都会对原文件进行修改。
链接命令
格式如下
ln [选项] <源文件或目录> <目的文件或目录>
选项 | 说明 |
---|---|
-s, --symbolic | 建立软链接,否则就是硬链接 |
-f, --force | 如果文件已存在,强制覆盖 |
-i, --interactive | 如果文件已存在,则提示 |
windows和linux链接的异同
详情参见这里
lsof
lsof的意思是’列出打开的文件’(list openfiles),用于找出文件被哪些进程打开或是占用。我们都知道Linux/UNIX的理念就是一切皆文件(包括pipes管道、sockets、directories目录、devices设备等等)。 使用lsof这个命令我们可以轻易的识别哪些文件正在被占用,详情参见这里
文件名和inode的关系
文件名可以看作inode的别名,进程已经打开文件后,删除文件名对应的文件不会影响进程的读写,因为进程依然持有文件的inode,有些时候这会引发一些问题。windows中没有inode的概念,当删除已打开的的文件的时候,会提示文件正在被使用的信息,原因参考这里。
inode引发的问题
文件已经删掉,但磁盘空间并没有减小。原因是因为文件名只是别名,文件并没有真正的删除,依然在被某个进程使用。解决步骤如下:
- 查找已经删除的文件
lsof | grep deleted
- 根据文件名查找进程
lsof <文件名>
- 关闭或重新启动进程
- 查找已经删除的文件
写磁盘时明明还有空间,却报No space left on device(磁盘空间不足)的问题,原因可能是inode耗尽了,需要删除没用的小文件释放inode资源
日志切割后,日志采集程序无法继续采集。原因是日志切割时,旧文件A被命名为新文件B,日志采集程序此时持有的依然是B的inode,所以实际打开的还是新文件B,而新日志写到是A里面而不是B里面,所以采集程序无法继续采集。解决方案如下
- 低版本的采集程序有可能支持nohup信号重新打开文件,例如rsyslog
- 高版本的程序可能支持切割后重新打开文件的配置,例如rsyslog v8.16.0以上的reopenOnTruncate
- 最笨的方法,添加定时任务,在日志切割后重启日志采集程序
参考
Linux文件系统的最基本数据结构:inode和block
理解inode
Linux软链接和硬链接详解
Windows的四种链接方式
lsof在Linux中的10个例子
linux删除文件后没有释放空间
Linux服务器磁盘占满问题解决(/dev/sda3 满了)
为什么Windows在删除正在使用的文件时会提示“文件已在 XX 中打开”并拒绝删除,而安卓不会
Linux的inode的理解