【环境】
虚拟机VirtualBox
Ubuntu20虚拟机上有2块硬盘
一个30G大小, 一个10G大小
【分区,格式化,挂载】
启动Ubuntu20虚拟机后, 使用 fdisk -l 查看磁盘信息
接下来对10G的硬盘进行分区,格式化,挂载.
fdisk /dev/sdb
【1】输入n 表示添加一个新的分区
【2】输入p表示分区类型是主分区
【3】输入1表示这个主分区是磁盘的第一个分区
【4】default 2048表示这个主分区的起始扇区是2048
【5】+5120M 表示这个主分区大小是5120M = 5G, 我们把这个10G的磁盘先拿出来5G作为第一个主分区
【6】输入w表示分区信息持久化
再次使用fdisk -l查看磁盘信息,就可以看到刚才的分区了
分区完成之后, 紧接着就是对这个新的/dev/sdb1分区进行格式化.
mkfs -t ext3 -c /dev/sdb1
格式化完成之后, 紧接着就是挂载, 将这个分区挂载到某个目录下, 我们挂载到/mnt目录下
使用df -TH 查看
信息都是正确的
但是,一旦重启机器, 挂载信息就不存在了, 因此还需要修改一下/etc/fstab文件, 新增一条关系记录
环境搭建完成
【创建硬链接和符号链接】
给read_disk.py文件创建硬链接和符号链接.
ln read_disk.py sl_read_disk.py
硬链接
ln -s read_disk.py sl_read_disk.py
软链接
同时查看下这3个文件的inode值
最左侧表示每个文件的inode值, 可以看出来, 硬链接文件与原文件的inode值相同, 软链接文件生成了新的inode值.
使用stat命令分别查看三个文件信息
可以看到原文件和硬链接文件的信息是一样的, 而软链接的信息就是不同的.
而且软链接的内容大小是12, 这12个字符是什么信息呢? 也就是说软链接sl_read_disk.py文件里面存储的是什么?
我们可以数一下软链接指向的原文件名称的字符数,正好是12字符, 难道是巧合?
而且我们还发现一个问题
软链接占用的磁盘空间居然是0, 明明实际大小是12, 怎么会不占用磁盘块呢? 不敢相信. 其实这是操作系统的优化, 因为这个软链接只有12个字符大小, 操作系统虽然默认会给每个文件至少分配4K大小的空间, 但如果给这个软链接分配4K大小空间, 几乎是浪费了4K的空间, 因此当文件很小的时候, 文件的实际内容是与元信息存储在一起的.
文件的信息分为元信息和实际数据两个部分, 我们使用stat看到的都是元信息
假如我们创建一个文件名称大于60个字符的文件, 然后给它创建一个软链接那么就会看到软链接占用了磁盘块.
我用的Ubuntu20只有文件名称大于等于60个字符, 软链接文件才会占用磁盘块
创建012345678901234567890123456789012345678901234567890123456789.c文件,并给它创建了一个软链接文件 number_sl.c 查看软链接文件元信息, 显示占用了8个磁盘块
每个磁盘块默认512字节
这个number_sl.c软链接文件大小是62字节, 我们就看下这个62字节是什么内容.
首先查看下number_sl.c所在的挂载点
stat --format=%m number_sl.c
查看挂载点所在的分区
dubug指定的/dev/sda5分区
debugfs /dev/sda5
如上图, 软链接number_sl.c文件中存储的就是原文件的名称, 也就是使用ln -s 012345678901234567890123456789012345678901234567890123456789.c number_sl.c 命令创建软链接的原文件名称.
总结: 软链接占用实际的磁盘块空间, 软链接中存储的是原文件名称
接下来我们把软链接都删除, 只保留原文件和硬链接, 以及再新增一个1.txt文件
通过ll 命令查看文件大小共计20K. 然而你现在看到的都不是真实的.
首先1.txt文件内容我只写了4个字符, 所以它实际大小4个字节, 但是霸占了4K的磁盘空间, 因为操作系统默认会给每个文件至少分配4K大小空间. read_disk.py是原文件, 也会霸占4K的磁盘空间. 而硬链接指向的是原文件, 硬链接并没有占有实际的磁盘空间, 但是ll命令在统计大小的时候, 不会在意这些的, 虽然原文件和硬链接都执向同一个文件, 实际只占有4K磁盘空间, 但是ll命令依然按照4K+4K来统计大小.
我们使用du -h 命令统计的才是实际占有磁盘块大小空间
实际上只有当前目录占有4K, 1.txt文件占有4K, 原文件read_disk.py占有4K的磁盘块空间, 所以实际是12K,并非ll命令统计的20K. 毕竟这两个命令站在的角度不同, 看待`问题`的结果也不同.
总结: 硬链接不会占用磁盘块, 它指向原文件
再来看一个情况, 如下图
文件大小40984个字节, 文件占用磁盘大小16*512=8192个字节. 文件的实际大小居然比装它的所有磁盘块的和还大, 这是本文中第二种遇到的size > 磁盘块的情况了. 而这里说的这种情况是因为这个3.txt文件是个空洞文件, 也就是说文件头尾有数据, 中间大片空间都是没有数据的.
使用命令od -c 3.txt 查看文件内容, 文件头部有www.infuq.com信息, 尾部有个字符v, 文件中间没有任何数据.
网上之前看过一篇文章, 大概就是说某个文件大约几个G大小, 可以删除那个文件一下子就删除了. 根本原因就在于那个文件是个空洞文件. 使用ll命令看文件大小貌似很大, 但是ll命令欺骗了我们, 实际文件大小很小, 使用du命令看到的大小才是真实的.
之前还在网上看过一篇文章说, 一个数据库文件几百G, 怎么可以很快把它删除掉. 也是运用了硬链接的原理,给文件创建一个硬链接, 然后就可以把原文件删除了. 其实删除原文件也只是把原文件的元信息删除掉,实际的数据块并没有被删除, 因为硬链接还指向着数据块, 这也是运用硬链接解决删除大文件的原理.
在文章一开始我们新增了一个分区, 现在就可以派上用场了. 上面的实验说明都是在同一个目录下创建软链接和硬链接, 也就是说它们都属于同一个磁盘同一个分区.
现在, 原文件还是这个原文件read_disk.py 接下来我要在新的/mnt挂载点对应的/dev/sdb1分区创建硬链接和软链接.
创建硬链接失败
创建软链接成功
总结: 软链接可以跨分区创建, 硬链接不可以跨分区创建
即便两个分区是相同的文件系统也不可以跨分区创建硬链接, 是机制不允许, 并不是文件系统的区别.