运维Tips | Linux系统文件命令执行时inode表如何变化?

5e8107e7763fa7fdcf8f75d50bd25409.jpeg

[ 知识是人生的灯塔,只有不断学习,才能照亮前行的道路。 ]

大家好,我是【WeiyiGeek/唯一极客】一个正在向全栈工程师(SecDevOps)前进的技术爱好者  

作者微信:WeiyiGeeker  
公众号/知识星球:全栈工程师修炼指南  
主页博客: https://weiyigeek.top - 为者常成,行者常至

Linux文件元数据之inode表结构

描述:文件元数据(Metadata)是文件的属性,它描述了文件的基本信息,例如文件大小、创建时间、类型、权限等。其通常是存放在inode (index node) 表中,inode 表中有很多条记录组成,第一条记录对应的存放了一个文件的元数据信息。

此处以ext4文件系统为例,每个 inode 表记录中大致包含以下信息:

  • inode Number 节点号

  • 文件类型和访问权限;

  • 文件所属用户 UID和组 GID;

  • 文件大小和占用磁盘块数;

  • 文件创建、修改和访问时间戳;

  • 文件的硬链接数;

  • 文件的数据块地址等。

温馨提示:如果小伙伴们在其他平台看到此文章,一定要关注作者首发公众号《全栈工程师修炼指南》,给作者持续创作的动力!

具体来说,一个 inode 结构体通常包含以下字段:

struct ext4_inode {
    __le16  i_mode;         // 文件类型和访问权限
    __le16  i_uid;          // 文件所属用户 ID
    __le32  i_size_lo;      // 文件大小
    __le32  i_atime;        // 上次访问时间
    __le32  i_ctime;        // 创建时间
    __le32  i_mtime;        // 上次修改时间
    __le32  i_dtime;        // 删除时间
    __le16  i_gid;          // 文件所属组 ID
    __le16  i_links_count;  // 硬链接数
    __le32  i_blocks_lo;    // 占用磁盘块数
    __le32  i_flags;        // 文件标志
    __le32  i_block[EXT4_N_BLOCKS];   // 数据块地址
    __le32  i_generation;             // 文件版本号
    __le32  i_file_acl_lo;            // 文件 ACL
    __le32  i_size_high;              // 文件大小(高位)
    __le32  i_obso_faddr;             // 文件的 fragment 地址
    union {
        struct {
            __le32  l_i_version;
        } linux1;
        struct {
            __u32  h_i_translator;
        } hurd1;
        struct {
            __u32  m_i_reserved1;
        } masix1;
    } osd1;                 // 操作系统相关数据
    union {
        struct {
            __le16  l_i_blocks_high;
            __le16  l_i_file_acl_high;
            __le16  l_i_uid_high;
            __le16  l_i_gid_high;
            __u16   l_i_checksum_lo;    // 低位校验和
            __u16   l_i_reserved;
        } linux2;
        struct {
            __le16  h_i_reserved1;
            __u16   h_i_mode_high;
            __u16   h_i_uid_high;
            __u16   h_i_gid_high;
            __u32   h_i_author;
        } hurd2;
        struct {
            __le16  h_i_reserved1;
            __u16   h_i_mode_high;
            __u16   h_i_uid_high;
            __u16   h_i_gid_high;
            __u32   h_i_reserved2[2];
        } masix2;
    } osd2;                 // 操作系统相关数据
};

其中比较重要的字段包括:i_modei_uidi_gidi_links_counti_size_loi_atimei_ctimei_mtimei_blocks_loi_block

  • 1.直接块指针,直接指向内存的数据区域,拥有12个直接指针,由于每个Block大小为4096B(4KB),则前12直接指针可保存48KB文件。

  • 2.间接指针,别称一级指针,其可以存储文件大小为1024*4096=4MB,存放1024个指针,每个指针又指向一个Block(4KB)。

  • 3.双重间接块指针,别称二级指针,其可存储文件大小为1024*1024*4096=4GB,存放1024*1024个指针,每个指针又指向一个Block(4KB)。

  • 4.三重间接块指针,别称三级指针,其可存储文件大小为1024*1024*1024*4096=4TB,存放1024*1024*1024个指针,每个指针又指向一个Block(4KB)。

06e96de7c1989a346dc4c98e54c7eb71.png

weiyigeek.top-inode表结构及其指针和存储空间图

从上图中可知在 ext4 文件系统中,目录是个特殊文件,目录文件的内容保存了此目录中的文件的列表及inode Number对应关系, 用户通过文件名访问文件时,首先在目录中查找文件的inode Number,然后根据inode Number找到对应的文件。

所以,一般inode表会占用文件系统磁盘空间的1%左右,一个目录文件的内容就是一个该目录下所有文件的目录项的列表。

# 查看 /boot 分区信息
$ df -Th /boot/
文件系统       类型  容量  已用  可用 已用% 挂载点
/dev/sda2      xfs   960M  251M  710M   27% /boot
$ df /boot
文件系统        1K-块   已用   可用 已用% 挂载点
/dev/sda2      983040 256144 726896   27% /boot

# 查看 /boot 分区 Inodes 总数量、已用、可用
$ df -i /boot
文件系统       Inodes 已用(I) 可用(I) 已用(I)% 挂载点
/dev/sda2      524288      22  524266       1% /boot

# 创建新文件验证系统 inodes 数量是否会新增
$ dd if=/dev/zero of=/tmp/test/file.txt bs=1M count=100
$ df -i /tmp/dir01
文件系统              Inodes 已用(I)  可用(I) 已用(I)% 挂载点
/dev/mapper/rl-root 35010560   47121 34963439       1% /
$ dd if=/dev/zero of=/tmp/test/file1.txt bs=1M 
$ df -i /tmp/dir01
文件系统              Inodes 已用(I)  可用(I) 已用(I)% 挂载点
/dev/mapper/rl-root 35010560   47122 34963438       1% /

cp 命令复制文件目录时inode变化

首先,分配一个空闲的inode号,并在inode表中生成新条目。 其次,在目录中创一个目录项,将新条目指向inode号(关联)。 最后,将文件数据块拷贝到inode号对应的磁盘块中。

$ ls -li
  134349770 -rw-r--r--. 1 root root 23  3月 24 16:12 issue~
$ cp issue~ issue~.bak
$ ls -li issue~.bak
  134612838 -rw-r--r--. 1 root root 23  3月 25 02:13 issue~.bak

rm 命令删除文件目录时inode变化

首先,将链接数递减,释放inode号,方便重用。 其次,将数据块存放在空闲列表中。 然后,将目录项从目录中删除。 最后,数据实际上并没有删除,只是被标记为空闲,当另外一个文件使用数据块时将被覆盖。


mv 命令移动重名文件目录时inode变化

首先,若mv命令的目标目录是当前目录,使用新文件名创建对应新的目录项,删除旧目录条目对应的旧的文件名,新文件与原始inode号绑定,变动的是时间戳。 其次,若mv命令的目标目录不是当前目录,mv相当于cp和rm命令的结合,首先将文件数据块拷贝到目标目录中,然后删除旧目录中的文件。

$ ls -li
  # 134612806 -rw-r--r--. 1 root root  5  3月 24 15:44 issue
$ mv issue issue.bak
$ ls -li
  # 134612806 -rw-r--r--. 1 root root  5  3月 24 15:44 issue.bak

ln 命令创建软、硬链接时inode变化

首先,创建硬链接,同一个文件,不支持目录、跨分区,与源文件的inode号相同。 其次,创建软链接,类似Windows快捷方式,支持目录、跨分区,新文件与新的inode号绑定。

# 硬链接
$ ln /tmp/dir01/file.txt /tmp/dir02/file.txt

# 软链接
$ ln -s /tmp/dir01/file.txt /tmp/dir02/file.txt
$ ln -s ../dir01/file.txt /tmp/dir03/file.txt  # 特殊:在 /tmp/dir01/ 目录中若要使用相对路径

# 删除软链接目录时,一定不要在尾部加上 /,否则会删除软链接源目录文件
rm -rf /tmp/dir03

Tips: Linux 系统中软链接与硬链接特征区别?

区别软链接硬链接
本质非同一个文件同一个文件
垮设备、分区支持不支持
文件夹支持不支持
inode 值不相同与源文件相同
链接数创建、删除链接数不会变化创建新的硬链接,数量会增加,删除硬链接,数量减少
相对路径必须使用绝对路径,源文件可以不存在无必须使用绝对路径,也可以使用相对路径,且原文件必须存在
文件类型链接文件和源文件无关和源文件相同
文件大小源文件的路径的长度和源文件相同
删除源文件软链接文件将无法访问链接数减一,删除最后一个链接后,源文件被删除

生产案例Tips

  1. 提示磁盘空间满 No Space Left On Device,但是 df 可以看到空间有剩余,为什么? A: 实际上是因为 inode 表数量使满了,此时删除我们创建的 /boot/testdir/ 便可以正常使用。

# 以 /boot 分区为例,将硬盘撑满。
$ cp /dev/zero /boot/test.img
  # cp: 写入 '/boot/test.img' 出错: 设备上没有空间
$ df -i /boot
  文件系统       Inodes 已用(I) 可用(I) 已用(I)% 挂载点
  /dev/sda2      524288  502   523786       5%   /boot
$ df -h /boot
  文件系统        容量  已用  可用 已用% 挂载点
  /dev/sda2       960M  960M  112K  100% /boot
# 此时无法再创建文件了  
$ touch a.txt
  touch: 无法创建 'a.txt': 设备上没有空间

# 然后,删除 /boot/test.img 文件
rm -rf /boot/test.img
# 前面,已知inode数量为524288,我们将剩余的inode数量填满,创建剩余数量的文件。
mkdir -vp /boot/testdir/
echo /boot/testdir/{1..523786}.txt | xargs -n 10000 touch
# 此时,将可以看到剩余的inode数量为 0,创建文件提示 No Space Left On Device,但是 df 命令仍然显示有剩余控制。

152dd08fa3f65fb5d121bc86402544d2.png

weiyigeek.top-inode数量用完结果图
  1. 提示磁盘空间快满,使用rm命令删除了很大的无用文件后,df仍然看到空间没被释放,为什么,如何解决? A: 一个目录文件若正在使用,则不会立即删除,虽然你在终端中可能看不到了,但是实际上目录文件系统没有及时释放inode,若想立即释放空间则可以按照下述方法。

$ cp /dev/zero /boot/test.img
$ df -h /boot
# 通用
$ cat /dev/null > /boot/test.img
# 在 sh 与 bash Shell 使用的方法,可能不通用
> /boot/test.img

89a6e86e247fbe5f26cdd4348086dc95.png

温馨提示:作者最近正在整理自己10年笔记,全栈系列从门到实践教程将会逐步持续同步到公众号内,若需要在线实时浏览作者笔记的童鞋,请添加作者[WeiyiGeeker],当前价格¥168,获取在网络、安全、运维、开发(Sec、Ops、Dev)中的所有学习实践笔记,和问题答疑以及远程技术支持,希望大家多多支持!

a18572f3e8c8ae7b1685306e00a8d3ec.png

至此完毕,更多技术文章,请持续关注公众号并添加星标,获取及时文章推送!

作者博客: https://blog.weiyigeek.top


如果此篇文章对你有帮助,请你将它分享给更多的人! 

382dfb71b0ff1a92d96fd91c8a6ebc1e.gif

8a6f298a1ece35613e6834e1f24060f9.png 学习推荐 往期文章 6cb17e0dc3620ce14c849fa614b73f2b.png

  • 🔥【最新】Linux 运维 | 2.文件系统目录结构及文件目录管理学习实践

  • 🔥【最新】运维学习 | Linux 命令大全,从A到Z

  • 🔥【必备】网络安全攻击防护及等级保护(过保)落地实践

  • 运维必备:Linux系统下的两款终端多重会话工具

  • Ops实践 | 从零开始:落实企业网络审计日志采集留存,等保合规!

  • Linux 命令 | 运维必学,文件目录管理操作命令实践集锦

bbc8d26d0e107b1205e9f15a6ac75a9b.gif

全栈工程师修炼指南】邀你加入学习交流群!

feaa03cb3bff33b42b6df5bbdf6070f6.gif

1a6d65eacd6d686f057e9b56c7caeac3.gif

此文,为作者原创文章,希望大家多多支持,若对看友您有帮助请帮忙转发,点👍、在看,若有疑问的小伙伴,可在文末留言哟!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/641080.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux下自旋锁的学习使用

前言 前面我们讲到定时器的使用,本篇讲下自旋锁的使用。想第一时间看我的文章的话可以点击公众号主页右上角有个设为星标,以免错过好文。本文源码采用Linux内核5.10 自旋锁简介 自旋锁是Linux内核里最常用的锁之一,自旋锁的概念很简单,就是…

误差反向传播简介与实现

误差反向传播 导语计算图反向传播链式法则 反向传播结构加法节点乘法节点 实现简单层加法乘法 激活函数层实现ReLUSigmoid Affine/Softmax层实现Affine基础版批版本 Softmax-with-Loss 误差反向传播实现梯度确认总结参考文献 导语 书上在前一章介绍了随机梯度下降法进行参数与…

ubuntu20.04 开机自动挂载外加硬盘

文章目录 一、问题描述二、操作1. 查找新添盘符2. 格式化硬盘文件系统3. 挂载硬盘4. 开机自动挂载5. 取消挂载6. 查看挂载的硬盘信息 一、问题描述 因电脑使用一段时间后自身硬盘不足,需外加硬盘使得电脑自动识别加载。 二、操作 1. 查找新添盘符 sudo blkid自己…

linux中的arch命令使用

arch 显示当前主机的硬件架构类型 概要 arch [OPTION]...主要用途 打印机器架构信息;arch 命令输出结果有:i386、i486、i586、alpha、sparc、arm、m68k、mips、ppc、i686等。 选项 --help 显示帮助信息并退出。 --version 显示版本信息并…

windows7的ie11降级到ie8

重点是要在程序管理窗口中“查看已安装的更新”打开当前系统中已安装更新列表,找到两个IE11的更新(见下图“卸载文件“)并卸载掉,这样windows功能中的ie11才会变成ie8. 打开控制面板 进入面板,点击程序,进…

hot100 -- 回溯(上)

目录 🍞科普 🌼全排列 AC DFS 🚩子集 AC DFS 🎂电话号码的字母组合 AC DFS 🌼组合总和 AC DFS 🍞科普 忘记 dfs 的,先看看这个👇 DFS(深度优先搜索&#xf…

ping 探测网段哪些地址被用

#!/bin/bash# 遍历192.168.3.1到192.168.3.254 for i in {1..254} doip"192.168.3.$i"# 对每个IP地址进行三次ping操作if ping -c 3 -W 1 $ip > /dev/null 2>&1thenecho "$ip: yes"fi done$ sh test.sh 192.168.3.1: yes 192.168.3.95: yes 192.…

MySQL中的sql语句

MySQL中的sql语句 DML、 DDL、 DCL DML(Data Manipulation Language),用于对数据库中的数据进行操作,包括插入、查询、更新和删除数据等操作。常见的 DML 命令包括 SELECT(查询)、INSERT(插入)、UPDATE&a…

Windows系统安装dlib及face_recognition搭建人脸识别环境

关于face_recognition face_recognition被称为世界上最简洁的人脸识别库,借助face_recognition库,我们可以使用Python和命令行提取、识别、操作人脸。 face_recognition的人脸识别是基于业内领先的C开源库 dlib中的深度学习模型,用Labeled …

数据结构——栈(详细分析)

目录 🍉引言 🍉栈的本质和特点 🍈栈的基本操作 🍈栈的特点 🍍后进先出 🍍操作受限 🍍动态调整 🍈栈的优缺点 🍍优点 🍍缺点 🍉栈的应用…

STM32F407VET6 学习笔记4:DAC数模转换功能的配置

今日继续学习使用嘉立创的 立创梁山派天空星,芯片是 STM32F407VET6 使用库函数编程 最近突然发现很久没有接触过单片机的AD转换功能了,之前还是学习51单片机时学习驱动PCF8591芯片实现AD转换功能的,还从未在STM32平台上进行过相关的实验经验…

解决go install 网络问题

rootiZbp1hiqzlhh6w05gloffgZ:~# go install mvdan.cc/garblelatest go: mvdan.cc/garblelatest: module mvdan.cc/garble: Get "https://proxy.golang.org/mvdan.cc/garble/v/list": dial tcp 172.217.160.81:443: i/o timeout解决方法 更换阿里代理 rootiZbp1hiq…

保障餐饮场所安全:定期送检可燃气体报警器

在餐饮行业,火灾隐患一直备受关注。餐厅、茶饮店等场所常常使用燃气设备,而这些设备带来了潜在的安全隐患。 为了及时发现并预防可燃气体泄漏,可燃气体报警器的定期送检显得尤为重要。那么,为什么可燃气体报警器需要定期送检呢&a…

python中的线程并行

文章目录 1. 单线程2. 线程池ThreadPoolExecutor 1. 单线程 现在有1154张图片需要顺时针旋转后保存到本地,一般使用循环1154次处理,具体代码如下所示,img_paths中存储1154个图片路径,该代码段耗时约用97ms。 t1time.time() for …

【再探】设计模式—代理模式

代理是指授权代理人在一定范围内代表其向第三方进行处理有关事务。 1 代理模式 需求:1)将业务代码与非业务代码分离,在不改变代码结构的基础上,为其添加新的功能。2)为系统中的某些操作做同一处理,例如进…

Dilworth 定理

这是一个关于偏序集的定理,事实上它也可以扩展到图论,dp等中,是一个很有意思的东西 偏序集 偏序集是由集合 S S S以及其上的一个偏序关系 R R R定义的,记为 ( S , R ) (S,R) (S,R) 偏序关系: 对于一个二元关系 R ⊂…

Python筑基之旅-MySQL数据库(四)

目录 一、数据表操作 1、新增记录 1-1、用mysql-connector-python库 1-2、用PyMySQL库 1-3、用PeeWee库 1-4、用SQLAlchemy库 2、删除记录 2-1、用mysql-connector-python库 2-2、用PyMySQL库 2-3、用PeeWee库 2-4、用SQLAlchemy库 3、修改记录 3-1、用mysql-conn…

力扣HOT100 - 21. 合并两个有序链表

解题思路&#xff1a; class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {ListNode dum new ListNode(0), cur dum;while (list1 ! null && list2 ! null) {if (list1.val < list2.val) {cur.next list1;list1 list1.next;} els…

力扣刷题---3146. 两个字符串的排列差

题目描述 给你两个字符串 s 和 t&#xff0c;每个字符串中的字符都不重复&#xff0c;且 t 是 s 的一个排列。 排列差 定义为 s 和 t 中每个字符在两个字符串中位置的绝对差值之和。 返回 s 和 t 之间的 排列差 。 示例 1&#xff1a; 输入&#xff1a;s “abc”, t “b…

四万字长文详解——node.js使用移动云,EOS对象存储

目录 前言 安装及安装前的操作 前置条件 如何创建认证信息 使用npm安装SDK开发包 安装开发包命令 初始化操作 存储桶 查看结果命令 查看桶列表 查看结果命令 删除桶 查看结果命令 创建桶 获取桶列表 判断桶是否存在 查询桶所属地域 查询桶的访问权限 管理桶的…