由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
由mv命令引发的对inode的思考的更多相关文章
- 【初级】linux mv 命令详解及使用方法实战
mv:移动文件或者将文件改名 前言: mv是move的缩写,顾名思义是移动.它的功能既能移动文件/文件夹,又可以用来改名,经常用来做文件的备份,比如再删除之前,先给文件做备份(保护数据)也是linux ...
- linux下mv命令使用方法
1.作用mv命令来为文件或目录改名或将文件由一个目录移入另一个目录中.该命令等同于DOS系统下的ren和move命令的组合.它的使用权限是所有用户.2.格式mv [options] 源文件或目录 目标 ...
- linux命令(7):mv命令
mv命令 mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 1.命令格式: mv [选项] ...
- 每天一个 Linux 命令(7):mv命令
mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 1.命令格式: mv [选项] 源文件或目 ...
- 每天一个linux命令(7):mv命令
mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 企业中常用的 [root@ local]# ...
- 每天一个linux命令(6):mv命令
mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 1.命令格式: mv [选项] 源文件或目 ...
- mv命令(转)
mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 1.命令格式: mv [选项] 源文件或目 ...
- linux mv命令
mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 1.命令格式: mv [选项] 源文件或目 ...
- adb上使用cp/mv命令的替代方法(failed on '***' - Cross-device link解决方法)
今天把玩手头的那部Android手机时碰到一个问题,即因为权限问题无法将文件复制到/system/和/data/分区中,经过一番折腾后,算是解决了,在此记录一笔.本方所涉及到的命令输入,均用斜体字表示 ...
随机推荐
- 内网 Maven 编译
内网 Maven 编译 有个特殊的需求,在不联网的情况下编译 Java 项目. 想到两种方案: 搭建 Nexus 私有镜像仓库. 直接把依赖 jar包 放在编译机的 maven 本地库中. 步骤简述 ...
- MyBatisPlus性能分析插件,条件构造器,代码自动生成器详解
性能分析插件 我们在平时的开发中,会遇到一些慢sql,测试,druid MP(MyBatisPlus)也提供性能分析插件,如果超过这个时间就停止 不过官方在3.2版本的时候取消了,原因如下 条件构造器 ...
- OpenCV之高斯平滑(Python实现)
假设一个列数为W,行数为H的高斯卷计算子gaussKernel,其中W,H均为奇数,描点位置在((H-1)/2 ,(W-1)/2),构建高斯卷积核的步骤如下 1.计算高斯矩阵 \[gaussMatri ...
- 2020-07-24:聊一下zookeeper的同步算法。
福哥答案2020-07-24: 同步算法基于 ZAB 协议,一种快速 Paxos 算法. 快速Paxos算法Paxos算法可能出现死循环,就是在两个Proposer总是在交替prepare.并且,Pa ...
- vue scss 样式穿透
使用2个style的方式不够优雅,可以使用下面方式做样式穿透 .normal-field /deep/ .el-form-item { margin-bottom: 0px; } .normal-fi ...
- Java多线程编程(6)--线程间通信(下)
因为本文的内容大部分是以生产者/消费者模式来进行讲解和举例的,所以在开始学习本文介绍的几种线程间的通信方式之前,我们先来熟悉一下生产者/消费者模式. 在实际的软件开发过程中,经常会碰到如下场景 ...
- Linux内核之 进程管理
正如上一篇我们提到过,进程是Linux系统中仅次于文件的基本抽象概念.正在运行的进程不仅仅是二进制代码,而是数据.资源.状态和虚拟的计算机组成.我们今天主要介绍进程的概念,组成,运行状态和生命周期等. ...
- Mybatis-08-动态SQL
动态SQL 什么是动态SQL? 根据不同的条件生成不同的SQL语句. if choose(where,otherwise) trim(where,set) foreach 搭建环境 create ta ...
- Python 读取word中表格数据、读取word修改并保存、替换word中词汇、读取word中每段内容,读取一段话中相同样式内容,理解Document中run
from docx import Document path = r'D:\pywork\12' # word信息表所在文件夹 w = Document(path + '/' + 'word信息表.d ...
- python接口自动化 - 断言(上)
我们在做接口自动化的时候会用当unittest框架,这个框架中是有assert方法 当我们写好我们的case后 总要有个验证是否正确的东西,assert就给我们提供了非常强大的结果验证 序号 断言方法 ...