由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/分区中,经过一番折腾后,算是解决了,在此记录一笔.本方所涉及到的命令输入,均用斜体字表示 ...
随机推荐
- Java异步之《我call(),Future在哪里》
我们大家都知道,在 Java 中创建线程主要有三种方式: 继承 Thread 类: 实现 Runnable 接口: 实现 Callable 接口. 而后两者的区别在于 Callable 接口中的 ca ...
- 用大白话解释什么是Socket
好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 前言 我在去年就学习过Java中 ...
- Java集合最全解析,学集合,看这篇就够用了!!!
在看集合类之前, 我们要先明白一下概念: 1.数据结构 (1):线性表 [1]:顺序存储结构(也叫顺序表) 一个线性表是n个具有相同特性的数据元素的有限序列.数据元素是一个抽象的符号,其具体含义在不同 ...
- 安装mpi的那些坑
安装mpi可以用 yum 安装 具体从操作步骤可参考这个链接mpi的yum安装方式 mpi在linux下 使用root权限 会报错 修改方式有两种 1 2.换其他账户 mpi会自行评估我们cpu的 ...
- C#LeetCode刷题之#409-最长回文串(Longest Palindrome)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3788 访问. 给定一个包含大写字母和小写字母的字符串,找到通过这 ...
- Linux学习笔记 一 第一章 Linux 系统简介
Linux简介 一.UNIX与Linux发展史
- mysql表中已有数据,为表新增一个自增id。
第一步,在navicat中,例如表test新建查询,输入以下两行代码即可搞定. alter table test add id int; alter table `test` change id id ...
- ARM伪指令与伪操作
一.伪指令 ARM伪指令有四个,分别是LDR.ADR.ADRL和NOP,下边对其分别介绍. 1.1 LDR LDR 伪指令用于加载 32 位的立即数或一个地址值到指定寄存器 .形式如 LDR{con ...
- 畅购商城(九):Spring Security Oauth2
好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 畅购商城(一):环境搭建 畅购商 ...
- linux 解压与压缩
转http://www.cnblogs.com/eoiioe/archive/2008/09/20/1294681.html .tar 解包:tar xvf FileName.tar打包:tar cv ...