Linux文件元数据和节点表结构
文件元数据
一块硬盘的分区可以认为有两部分组成,保存元数据的成为节点表,用来保存属性等。
元数据中有个小指针,指向数据存放的实际空间。
元数据(Metadata)
又称中介数据、中继数据,为描述数据的数据(data about data),主要是描述数据属性(property)的信息,用来支持如指示存储位置、历史数据、资源查找、文件记录等功能。
inode表结构
每个文件的属性信息,比如:文件的大小,时间,类型等,称为文件的元数据(meta data)。这此元数
据是存放在node(index node)表中。node 表中有很多条记录组成,第一条记录对应的存放了一个文件的元数据信息
第一个node表记录对应的保存了以下信息:
- inode number 节点号 每个数据都有一个唯一标识 stat查看
- 文件类型
- 权限
- UID
- GID
- 链接数(指向这个文件名路径名称个数)
- 该文件的大小和不同的时间戳
- 指向磁盘上文件的数据块指针
- 有关文件的其他数据
[root@C8-1 ~]# ls -i
34011033 a{1-3}.test 34060751 b{1-3}.test 34060752 c{1-3}.test
[root@C8-1 ~]# stat a\{1-3\}.test
File: a{1-3}.test
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fd00h/64768d Inode: 34011033 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2020-06-19 09:59:08.761754380 -0400
Modify: 2020-06-19 09:59:08.761754380 -0400
Change: 2020-06-19 09:59:08.761754380 -0400
Birth: -
指针
磁盘是一种块文件,以块的方式来存储数据,每块通常都是4K,
- 直接指针
直接指针直接指向存放的位置,直接指针只有12个,12x4K=48K,可以表达48K的数据
一个文件假如是1K或者哪怕是一个字节,也要分配一块4k的空间来存储这个文件,
一个文件假如是10k,分配3块空间来存放,就有3个指针来指向存放的3个块 - 间接指针
指针不是直接指向数据存储的位置,而是指向指针块,指针块也是4K大小,
一个指针放4个字节,一个指针块可以放1024个指针,4Kx1024=4M ,可以表达4M的数据
超过48K低于4M,就可以用间接指针来表示 - 双重间接指针
一个间接指针块指向另一个间接指针块矩阵
4Kx1024x1024=4G,可以表达4G的数据 - 三重间接指针
4Kx1024x1024x1024=4T,可以表达4T的数据
指针是有很多个组合而成的
不同的系统底层并不完全相同,仅此ext格式为例,逻辑相通
如果文件越大,速度越慢!
找一个文件,现在分区中找节点表,
目录
目录是个特殊文件,目录的文件内容保存了此目录中文件的列表及inode number对应关系
节点表里没有文件名,文件名是放在目录中的。在目录块里存放着每个文件的文件名和节点编号的对应关系。
- 文件引用一个是 inode号
- 人是通过文件名来引用一个文件
- 一个目录是目录下的文件名和文件inode号之间的映射
示例:
有一个节点表,每个节点表中放的就是元数据,node1代表着这个文件夹对应的节点表。
dir1的数据块里边存放着两个文件a和b,a对应inode1,b对应inode2,通过节点表对应到他数据的所在位置,
文件命令的本质
cp和inode
cp 命令:
- 分配一个空闲的inode号,在inode表中生成新条目
- 在目录中创建一个目录项,将名称与inode编号关联
- 拷贝数据生成新的文件
rm和inode
rm 命令:
- 链接数递减,从而释放的inode号可以被重用
- 把数据块放在空闲列表中
- 删除目录项
- 数据实际上不会马上被删除,但当另一个文件使用数据块时将被覆盖
mv和inode
移动相当于拷贝加删除,在同一分区,只是改一下记录,数据没动
- 如果mv命令的目标和源在相同的文件系统,作为mv 命令
- 用新的文件名创建对应新的目录项
- 删除旧目录条目对应的旧的文件名
- 不影响inode表(除时间戳)或磁盘上的数据位置:没有数据被移动!
- 如果目标和源在一个不同的文件系统, mv相当于cp和rm
节点编号的限制
节点编号是有使用范围的,可以反复使用。
在一个分区中,节点编号是有限资源。
同一分区移动文件,节点编号不变。
一旦跨了分区,节点编号改变。
查看分区情况和节点编号
每个独立的分区都有自己Inodes可分配额
使用df -i命令查看最多可分配Inodes的数量
[root@C8-1 ~]# df -h ##查看分区使用情况
Filesystem Size Used Avail Use% Mounted on
devtmpfs 886M 0 886M 0% /dev
tmpfs 904M 0 904M 0% /dev/shm
tmpfs 904M 8.7M 895M 1% /run
tmpfs 904M 0 904M 0% /sys/fs/cgroup
/dev/mapper/cl-root 17G 2.1G 15G 12% /
/dev/sda1 976M 139M 771M 16% /boot
tmpfs 181M 0 181M 0% /run/user/0
[root@C8-1 ~]# df -i ##可以查看最多可分配Inodes的数量
Filesystem Inodes IUsed IFree IUse% Mounted on
devtmpfs 226760 376 226384 1% /dev
tmpfs 231191 1 231190 1% /dev/shm
tmpfs 231191 584 230607 1% /run
tmpfs 231191 17 231174 1% /sys/fs/cgroup
/dev/mapper/cl-root 8910848 60173 8850675 1% /
/dev/sda1 65536 309 65227 1% /boot
tmpfs 231191 5 231186 1% /run/user/0
范例:
- 耗尽节点编号
[root@C8-1 ~]# mkdir /boot/testdir ##创建测试文件夹
[root@C8-1 ~]# df -i ##查看Inodes情况
Filesystem Inodes IUsed IFree IUse% Mounted on
devtmpfs 226760 376 226384 1% /dev
tmpfs 231191 1 231190 1% /dev/shm
tmpfs 231191 584 230607 1% /run
tmpfs 231191 17 231174 1% /sys/fs/cgroup
/dev/mapper/cl-root 8910848 60173 8850675 1% /
/dev/sda1 65536 310 65226 1% /boot ##还有65226个可用
tmpfs 231191 5 231186 1% /run/user/0
[root@C8-1 ~]# cd /boot/testdir/
[root@C8-1 testdir]# ll
total 0
[root@C8-1 testdir]# touch {1..65526}.test ##创建65526个空文件
touch: cannot touch '65227.test': No space left on device ##创建到65527个文件的时候报错了
[root@C8-1 testdir]# df -i ##查看Inodes情况
Filesystem Inodes IUsed IFree IUse% Mounted on
devtmpfs 226760 376 226384 1% /dev
tmpfs 231191 1 231190 1% /dev/shm
tmpfs 231191 584 230607 1% /run
tmpfs 231191 17 231174 1% /sys/fs/cgroup
/dev/mapper/cl-root 8910848 60173 8850675 1% /
/dev/sda1 65536 65536 0 100% /boot ##节点编号已耗尽
tmpfs 231191 5 231186 1% /run/user/0
[root@C8-1 testdir]# df -h ##查看Inodes使用情况
Filesystem Size Used Avail Use% Mounted on
devtmpfs 886M 0 886M 0% /dev
tmpfs 904M 0 904M 0% /dev/shm
tmpfs 904M 8.7M 895M 1% /run
tmpfs 904M 0 904M 0% /sys/fs/cgroup
/dev/mapper/cl-root 17G 2.1G 15G 12% /
/dev/sda1 976M 141M 769M 16% /boot ##/boot分区仍有可用空间,但已无法创建文件
tmpfs 181M 0 181M 0% /run/user/0
##删除后恢复
[root@C8-1 ~]# rm -rf /boot/testdir/
[root@C8-1 ~]# type rm
rm is aliased to `rm -i'
[root@C8-1 ~]# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
devtmpfs 226760 376 226384 1% /dev
tmpfs 231191 1 231190 1% /dev/shm
tmpfs 231191 583 230608 1% /run
tmpfs 231191 17 231174 1% /sys/fs/cgroup
/dev/mapper/cl-root 8910848 60173 8850675 1% /
/dev/sda1 65536 309 65227 1% /boot
tmpfs 231191 5 231186 1% /run/user/0
- 耗尽分区空间
dd可以创建一个大文件
[root@C8-1 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 886M 0 886M 0% /dev
tmpfs 904M 0 904M 0% /dev/shm
tmpfs 904M 8.7M 895M 1% /run
tmpfs 904M 0 904M 0% /sys/fs/cgroup
/dev/mapper/cl-root 17G 2.1G 15G 12% /
/dev/sda1 976M 139M 771M 16% /boot
tmpfs 181M 0 181M 0% /run/user/0
[root@C8-1 ~]# mkdir /boot/testdir/
[root@C8-1 ~]# dd if=/dev/zero of=/boot/bigfile bs=1M count=771
771+0 records in
771+0 records out
808452096 bytes (808 MB, 771 MiB) copied, 6.70666 s, 121 MB/s
[root@C8-1 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 886M 0 886M 0% /dev
tmpfs 904M 0 904M 0% /dev/shm
tmpfs 904M 8.7M 895M 1% /run
tmpfs 904M 0 904M 0% /sys/fs/cgroup
/dev/mapper/cl-root 17G 2.1G 15G 12% /
/dev/sda1 976M 910M 0 100% /boot
tmpfs 181M 0 181M 0% /run/user/0
[root@C8-1 ~]# ll -h /boot/bigfile
-rw-r--r--. 1 root root 771M Jun 20 02:18 /boot/bigfile
当文件被使用时,虽然删掉了,但空间仍然没有释放,因为文件存在于内存中
[root@C8-1 ~]# rm -rf /boot/bigfile
[root@C8-1 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 886M 0 886M 0% /dev
tmpfs 904M 0 904M 0% /dev/shm
tmpfs 904M 8.7M 895M 1% /run
tmpfs 904M 0 904M 0% /sys/fs/cgroup
/dev/mapper/cl-root 17G 2.1G 15G 12% /
/dev/sda1 976M 910M 0 100% /boot
tmpfs 181M 0 181M 0% /run/user/0
使用lsof查看一下已经删掉的文件
[root@C8-1 ~]# lofs |grep delete
-bash: lofs: command not found
[root@C8-1 ~]# lsof |grep delete
systemd-u 704 root 8r REG 253,0 6406312 34011028 /var/lib/sss/mc/group (deleted)
systemd-u 704 root 9r REG 253,0 8406312 34011025 /var/lib/sss/mc/passwd (deleted)
auditd 853 root 4r REG 253,0 6406312 34011028 /var/lib/sss/mc/group (deleted)
auditd 853 854 auditd root 4r REG 253,0 6406312 34011028 /var/lib/sss/mc/group (deleted)
auditd 853 856 auditd root 4r REG 253,0 6406312 34011028 /var/lib/sss/mc/group (deleted)
mcelog 878 root 4r REG 253,0 8406312 34011025 /var/lib/sss/mc/passwd (deleted)
lsmd 880 libstoragemgmt 3r REG 253,0 8406312 34011025 /var/lib/sss/mc/passwd (deleted)
dbus-daem 881 dbus 5r REG 253,0 8406312 34011025 /var/lib/sss/mc/passwd (deleted)
dbus-daem 881 dbus 6r REG 253,0 10406312 34011031 /var/lib/sss/mc/initgroups (deletd)
dbus-daem 881 893 dbus-daem dbus 5r REG 253,0 8406312 34011025 /var/lib/sss/mc/passwd (deleted)
dbus-daem 881 893 dbus-daem dbus 6r REG 253,0 10406312 34011031 /var/lib/sss/mc/initgroups (deletd)
sssd 883 root 6r REG 253,0 8406312 34011025 /var/lib/sss/mc/passwd (deleted)
sssd 883 root 16r REG 253,0 10406312 34011031 /var/lib/sss/mc/initgroups (deletd)
polkitd 884 polkitd 4r REG 253,0 10406312 34011031 /var/lib/sss/mc/initgroups (deletd)
polkitd 884 900 gmain polkitd 4r REG 253,0 10406312 34011031 /var/lib/sss/mc/initgroups (deletd)
polkitd 884 901 gdbus polkitd 4r REG 253,0 10406312 34011031 /var/lib/sss/mc/initgroups (deletd)
polkitd 884 907 JS\x20Hel polkitd 4r REG 253,0 10406312 34011031 /var/lib/sss/mc/initgroups (deletd)
polkitd 884 908 JS\x20Hel polkitd 4r REG 253,0 10406312 34011031 /var/lib/sss/mc/initgroups (deletd)
polkitd 884 923 polkitd polkitd 4r REG 253,0 10406312 34011031 /var/lib/sss/mc/initgroups (deletd)
VGAuthSer 885 root 8r REG 253,0 8406312 34011025 /var/lib/sss/mc/passwd (deleted)
vmtoolsd 886 root 3r REG 253,0 8406312 34011025 /var/lib/sss/mc/passwd (deleted)
vmtoolsd 886 914 gmain root 3r REG 253,0 8406312 34011025 /var/lib/sss/mc/passwd (deleted)
chronyd 892 chrony 5r REG 253,0 8406312 34011025 /var/lib/sss/mc/passwd (deleted)
sssd_be 909 root 18r REG 253,0 8406312 34011025 /var/lib/sss/mc/passwd (deleted)
sssd_be 909 root 19r REG 253,0 10406312 34011031 /var/lib/sss/mc/initgroups (deletd)
sssd_nss 916 root 17r REG 253,0 8406312 34011025 /var/lib/sss/mc/passwd (deleted)
firewalld 926 root 7u REG 253,0 4096 609362 /tmp/#609362 (deleted)
firewalld 926 1373 gmain root 7u REG 253,0 4096 609362 /tmp/#609362 (deleted)
vim 1796 root 5r REG 8,1 808452096 309 /boot/bigfile (deleted)
发现 309 /boot/bigfile (deleted)正在由root执行vim占用着,所以没有释放空间,还在内存中
直接把占用程序kill掉,可以释放,但不安全。
使用重定向null直接清空大文件,然后再删除,可以快速释放空间。
cat null只是将文件清空,并没有删除文件。可以快速释放空间。
[root@C8-1 ~]# ll -h /boot/bigfile
-rw-r--r--. 1 root root 771M Jun 20 02:57 bigfile
[root@C8-1 ~]# cat /dev/null > /boot/bigfile
[root@C8-1 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 886M 0 886M 0% /dev
tmpfs 904M 0 904M 0% /dev/shm
tmpfs 904M 8.7M 895M 1% /run
tmpfs 904M 0 904M 0% /sys/fs/cgroup
/dev/mapper/cl-root 17G 2.1G 15G 12% /
/dev/sda1 976M 139M 771M 16% /boot
tmpfs 181M 0 181M 0% /run/user/0
[root@C8-1 ~]# ll -h /boot/bigfile
-rw-r--r--. 1 root root 0 Jun 20 02:58 bigfile