(1)这些文件权限与属性分别记录在文件系统的哪个区块内?
这就得要谈到 filesystem 中的 inode 与 block 了
(2)为了虚拟化与大容量磁盘, 现在的 CentOS 7 默认使用大容量效能较佳的 xfs 当预设文件系统了!
(3)Linux 最传统的磁盘文件系统 (filesystem) 使用的是 EXT2 这个啦!
(2)磁盘盘上的物理组成:重点
(3)这里主要介绍的以实体磁盘及虚拟磁盘为主喔!
(4)CentOS 7 的分区软件, 已经将最小单位改成扇区了,所以容量大小的分区可以切的更细~此外,由于新的大容量磁盘大多得要使用 GPT 分区表才能够使用全部的容量, 因此过去那个 MBR 的传统磁盘分区表限制就不会存在了
(1) 在默认的情况下, windows 操作系统是不会认识 Linux 的 Ext2 的。
windows 98 以前的微软操作系统主要利用的文件系统是 FAT (或 FAT16);
windows 2000 以后的版本有所谓的 NTFS文件系统;
至于 Linux 的正统文件系统则为 Ext2 (Linux second extended file system, ext2fs)
(2)磁盘与文件系统之间的关系如下:
LVM 与软件磁盘阵列(software raid), 这些技术可以将一个分区槽格式化为多个文件系统(例如 LVM),也能够将多个分区槽合成一个文件系统(LVM, RAID)!
所以,一个可被挂载的数据为一个文件系统而不是一个分区槽
(3)文件系统是如何运作的呢?
例如 Linux 操作系统的文件权限(rwx)与文件属性(拥有者、群组、时间参数等)。
文件系统通常会将这两部份的数据分别存放在不同的区块,权限与属性放置到inode 中,至于实际数据则放置到 data block 区块中。 另外,还有一个超级区块 (superblock) 会记录整个文件系统的整体信息,包括 inode 与 block 的总量、使用量、剩余量等。
(5)用索引式文件系统来说明inode与block之间的关系
假设某一个文件的属性与权限数据是放置到 inode 4 号(下图较小方格内),而这个 inode 记
录了文件数据的实际放置点为 2, 7, 13, 15 这四个 block 号码,此时我们的操作系统就能够据此来排列磁盘的阅读顺序,可以一口气将四个 block 内容读出来!
(a)碎片整理的概念
需要碎片整理的原因就是文件写入的 block 太过于离散了,此时文件读取的效能将会变的很差所致。 这个时候可以透过碎片整理将同一个文件所属的 blocks 汇整在一起,这样数据的读取会比较容易啊!
(b)linux的EXT2相较于windows的FAT,是不需要磁盘整理的
(1)EXT2文件系统中区块群组block group
文件系统一开始就将 inode 与 block 规划好了,除非重新格式化(或者利用resize2fs 等指令变更文件系统大小),所有的 inode 与 block 通通放置在一起将是很不智的决定,因为 inode 与 block 的数量太庞大。
为此之故,因此 Ext2 文件系统在格式化的时候基本上是区分为多个区块群组 (block group) 的,每个区块群组都有独立的 inode/block/superblock 系统。
(i)data block 是用来放置文件内容数据地方, 在 Ext2 文件系统中所支持的 block 大小有 1K, 2K 及4K 三种而已。
(ii)EXT2文件系统的block的基本限制如下:
eg:
(iii)如果block太小?
因为如果 block 较小的话,那么大型文件将会占用数量更多的 block ,而 inode 也要记录更多的 block 号码,此时将可能导致文件系统不良的读写效能。
补充:事实上,现在的磁盘容量都太大了!所以,大概大家都只会选择 4K 的 block 大小吧!
(i) inode 的内容在记录文件的属性以及该文件实际数据是放置在哪几号 block 内!
(ii) inode 的数量和大小在格式化的时候就已经固定了,特点如下:
(iii)EXT2 的 inode / block 与文件大小的关系如下:
inode 记录一个 block 号码要花掉 4byte ;
假设我一个文件有400MB 且每个 block 为 4K 时, 那么至少也要十万笔 block 号码的记录呢!
但是呢?只有1K的block能这么计算。。。所以上面的计算,肯定是鸟哥的经验!
(4K/4=1024笔记录,如果是直接指向+间接指向的话是:12✖4K+1024✖4K)
(iiii)inode结构示意图
为此,我们的系统很聪明的将 inode 记录 block 号码的区域定义为 12 个直接,一个间接,一个双间接与一个三间接记录区。
说明:
直接:
上图最左边为 inode 本身 (128 bytes),里面有 12 个直接指向 block 号码的对照,这 12 笔记录就能够直接取得 block 号码啦! ;
间接:
再拿一个 block 来当作记录 block 号码的记录区,如果文件太大时, 就会使用间接的 block 来记录编号。
双间接:第一个 block 仅再指出下一个记录编号的 block 在哪里, 实际记录的在第二个 block 当中。
三间接:利用第三层 block 来记录编号。
(iiii)inode 能够指定多少个 block 呢?我们以较小的 1K block 来说明好了
(从block的方向去考虑)
注意:但这个方法不能用在 2K 及 4K block 大小的计算中, 因为大于 2K 的 block 将会受到 Ext2 文件系统本身的限制,所以计算的结果会不太符合之故。
(如果从inode本身去考虑的话)
eg:CentOS 6.x系统,那么默认还是使用 Ext4 的文件系统喔! Ext4 文件系统的 inode 容量已经可以扩大到 256bytes 了。
按照间接的方式的话:256/4=64笔记录,如果是指向1k的block,那么64*1k=64k,也就是说,指向的block的内容也就这么大点。。。
(i)Superblock 是记录整个 filesystem 相关信息的地方, 没有 Superblock ,就没有这个 filesystem 了。
记录的信息主要有:
(ii)一般来说, superblock 的大小为 1024bytes。
相关的 superblock 讯息我们等一下会以 dumpe2fs 指令来呼叫出来观察喔!
(iii)此外,每个 block group 都可能含有 superblock 喔!
而若含有 superblock 则该 superblock 主要是做为第一个 block group 内 superblock 的备份咯,这样可以进行 superblock 的救援呢!
现在是superblock的信息
现在是block group的信息
说明:
dumpe2fs查询的结果说明:
不过依内容主要可以区分为上半部是superblock 内容, 下半部则是每个 block group 的信息了;
从上面的表格中我们可以观察到鸟哥这个 /dev/vda5 规划的 block 为 4K, 第一个 block 号码为 0 号,且 block group 内的所有信息都以block 的号码来表示的。
至于 block group 的内容我们单纯看 Group0 信息好了: 主要如下
注意:4096*512代表的是:多少个bytes的block
数量的话,已经说清楚是512个block了。
(1) block 则是记录在这个目录下的文件名与该文件名占用的 inode 号码数据:
(2)查看目录内的文件所占用的 inode 号码,用ls -i
(3)当你使用『ll / 』时,出现的目录几乎都是 1024的倍数,为什么呢?因为每个 block 的数量都是 1K, 2K, 4K 嘛!
注意:目录并不只会占用一个 block 而已
在目录底下的文件数如果太多而导致一个 block 无法容纳的下所有的档名与 inode 对照表时, Linux 会给予该目录多一个 block来继续记录相关的数据;
(2)eg:举例来说,如果我想要读取 /etc/passwd 这个文件时,系统是如何读取的呢?
(6)filesystem 大小与磁盘读取效能:
(i)如果文件写入的 block 真的分的很散,会咋样?
(ii)如果 filesystem 真的太大了,会咋样?
(1)假设我们想要新增一个文件,此时文件系统的行为是:
(2)数据的不一致 (Inconsistent) 状态及早期的解决办法
出现日至式文件系统的原因:数据的不一致状态
(i)早filesystem 当中规划出一个区块,该区块专门在记录写入或修订文件时的步骤,
日志式文件的工作过程:
(ii)日志式文件最基础的功能
(iii)
(1)如果你常常编辑一个好大的文件, 在编辑的过程中又频繁的要系统来写入到磁盘中,由于磁盘写入的速度要比内存慢很多, 因此你会常常耗在等待磁盘的写入/读取上。
为了解决这个效率的问题,因此我们的 Linux 使用的方式是透过一个称为异步处理 (asynchronously)的方式。
(2)我们知道内存的速度要比磁盘快的多,因此如果能够将常用的文件放置到内存当中, 这不就会增加系统性能吗?
因此我们 Linux 系统上面文件系统与内存有非常大的关系喔:
(1)每个 filesystem 都有独立的 inode / block / superblock 等信息,这个文件系统要能够链接到目录树才能被我们使用。
将文件系统与目录树结合的动作我们称为『挂载』。
重点是: 挂载点一定是目录,该目录为进入该文件系统的入口。
so:因此并不是你有任何文件系统都能使用,必须要『挂载』到目录树的某个目录后,才能够使用该文件系统的。
说明:
(i)观察这三个目录的inode发现:
由于 XFS filesystem 最顶层的目录之 inode 一般为 128 号,因此可以发现 /, /boot, /home为三个不同的 filesystem 啰! (因为每一行的文件属性并不相同,且三个目录的挂载点也均不相同之故。 )
(ii)同一个 filesystem 的某个 inode 只会对应到一个文件内容而已(因为一个文件占用一个 inode 之故),
因此我们可以透过判断 inode 号码来确认不同文件名是否为相同的文件喔!
(iii)eg:曾经提到根目录下的 . 与 … 是相同的东西
说明:
上面的信息中由于挂载点均为 / ,因此三个文件 (/, /., /…) 均在同一个 filesystem 内(判断方法:看inde号码以及目录属性);
而这三个文件的 inode 号码均为 128 号,因此这三个档名都指向同一个 inode 号码,当然这三个文件的内容也就完全一模一样了!
(2)想要知道你的 Linux 支持的文件系统有哪些,可以察看底下这个目录:
(3)Linux VFS (Virtual Filesystem Switch):VFS文件系统
(i)整个 Linux 的系统都是透过一个名为 Virtual Filesystem Switch 的核心功能去读
取 filesystem 的。
也就是说,整个 Linux 认识的 filesystem 其实都是 VFS 在进行管理!!
(a)基本上 xfs 就是一个日志式文件系统,这个 xfs 就是被开发来用于高容量磁盘以及高性能文件系统之用。
(b)xfs 文件系统在资料的分布上,主要规划为三个部份,一个资料区 (data section)、一个文件系统活动登录区 (log section)以及一个实时运作区 (realtime section)。 这三个区域的数据内容如下:
(i)数据区 (data section)
xfs 的这个数据区的储存区群组 (allocation groups, AG),你就将它想成是 ext家族的 block 群组 (block groups) 就对了!
该数据区也是分为多个储存区群组(allocation groups) 来分别放置文件系统所需要的数据。
每个储存区群组都包含了
(1)磁盘的整体数据是在 superblock 区块中;每个各别文件的容量则在 inode 当中记载的;
(a)df的解释
由于 df 主要读取的数据几乎都是针对一整个文件系统,因此读取的范围主要是在Superblock 内的信息, 所以这个指令显示结果的速度非常的快速!
(b)df相关信息说明
说明:
(d)df -aT
注:/proc 的东西都是 Linux 系统所需要加载的系统数据,而且是挂载在『内存当中』
的, 所以当然没有占任何的磁盘空间啰!
那个 /dev/shm/ 目录, 其实是利用内存虚拟出来的磁盘空间,通常是总物理内存的一半! 由于是透过内存仿真出来的磁盘,因此你在这个目录底下建立任何数据文件时,访问速度是非常快速的!但是,建立的东西在下次开机时就消失了! 因为是在内存中嘛!
(1)在 Linux 底下的连结档有两种,
一种是类似 Windows 的快捷方式功能的文件,可以让你快速的链接到目标文件(或目录); 另一种则是透过文件系统的 inode 连结来产生新档名,而不是产生新文件!这种称为实体链接 (hard link)。
(a)其实文件名只与目录有关,但是文件内容则与 inode 有关。
(b)有没有可能有多个档名对应到同一个 inode 号码呢?
有的!那就是 hard link 的由来
eg:假设我系统有个 /root/crontab 他是 /etc/crontab 的实体链接,也就是说这两个档名连
结到同一个 inode , 自然这两个文件名的所有相关信息都会一模一样(除了文件名之外)。
解释:
(i)
(a)符号链接的含义
Symbolic link 就是在建立一个独立的文件,而这个文件会让数据的读取指向他 link 的那个文件的档名!由于只是利用文件来做为指向的动作。
所以, 当源文件被删除之后,symbolic link 的文件会『开不了』
(b)eg:我们先建立一个符号链接文件链接到 /etc/crontab 去看看,
解释:
(i)
(iii)
举上面的例子来说,我的/etc/crontab 与 /root/crontab 指向同一个文件,如果我删除了 /root/crontab 这个文件,该删除的动作其实只是将 /root 目录下关于 crontab 的关连数据拿掉而已, crontab 所在的 inode 与 block 其实都没有被变动喔!
(b)/tmp目录的作用:
您会发现,过去我们在进行测试时,都会将数据移动到 /tmp 底下去练习
(d)关于目录的 link 数量:
如果建立目录时,他默认的 link 数量会是多少?
(1)如果我们想要在系统里面新增一颗磁盘时,应该有哪些动作需要做的呢:
(1)磁盘分区是GPT格式的,用gdisk来处理分区;
磁盘分区是MBR格式的,用fdisk来处理分区;
(a)lsblk 可以看成『list block device 』的缩写,就是列出所有储存装置
(b)eg1
说明:
目前的系统主要有个 sr0 以及一个 vda 的装置,而 vda 的装置底下又有三个分区, 其中 vda3 甚至还有因为 LVM 产生的文件系统!
(a)UUID 是全局单一标识符 (universally unique identifier), Linux 会将系统内所有的装置都给予一个独一无二的标识符, 这个标识符就可以拿来作为挂载或者是使用这个装置/文件系统之用了。
(a) blkid 也知道了所有的文件系统, parted 来输出磁盘的分区类型
(b)
(c)eg:
(a)初步了解各个分区的信息:
说明:
(i)
(ii)老实说,使用 gdisk 这支程序是完全不需要背指令的!
只要离开 gdisk 时按下『q』,那么所有的动作『都不会生效!』相反的, 按下『w』就是动作生效的意思。所以,你可以随便玩 gdisk ,只要离开时按下的是『q』即可。
(iii)以鸟哥这颗磁盘为例,这个磁盘共有 40GB 左右的容量,共有 83886080 个扇区,每个扇区的容量为512bytes。
要注意的是,现在的分区主要是以扇区为最小的单位喔!
下半部的分区表信息主要在列出每个分区槽的个别信息项目。每个项目的意义为:
(iiii)使用的『装置文件名』请不要加上数字,因为 partition是针对『整个磁盘装置』 而不是某个 partition 呢!
(b)用 gdisk 新增分区槽:
(i)而经过上面的观察,我们也确认系统还有剩下的容量可以来操作练习分区! 假设我需要有如下的分区需求:
(ii)
说明:
重点在『Last sector 』那一行,那行绝对不要使用默认值!因为默认值会将所有的容量用光!
每次新增完毕后,请立即『p 』查看一下结果喔!
(iii)
(iiii)
(iiiii)
(c)partprobe 更新 Linux 核心的分区表信息
因为 Linux 此时还在使用这颗磁盘,为了担心系统出问题,所以分区表并没有被更新喔!这个时候我们有两个方式可以来处理:
(d)用 gdisk 删除一个分区槽
注意:万分注意!不要去处理一个正在使用中的分区槽!
(a)mkfs.xfs的用法如下
(b)
说明:
因为 xfs 可以使用多个数据流来读写系统,以增加速度,因此那个 agcount 可以跟 CPU 的核心数来做搭配!举例来说,如果我的服务器仅有一颗 4 核心,但是有启动 Intel 超线程功能,则系统会仿真出 8 颗 CPU 时,那个 agcount 就可以设定为 8 喔!
(c)
说明:
(i)XFS 文件系统 for RAID 效能优化 (Optional):针对于格式化后的文件系统设置
RAID磁盘阵列的含义:
磁盘阵列是多颗磁盘组成一颗大磁盘的意思, 利用同步写入到这些磁盘的技术,不但可以加快读写速度,还可以让某一颗磁盘坏掉时,整个文件系统还是可以持续运作的状态!
那就是所谓的容错。
(ii)stripe有啥用?
(iii)文件系统的读写要能够有优化,最好能够搭配磁盘阵列的参数来设计,这样效能才能够起来!
也就是说,你可以先在文件系统就将 stripe 规划好, 那交给 RAID 去存取时,它就无须重复进行文件的stripe 过程,效能当然会更好!
那格式化时,优化效能与什么咚咚有关呢?
我们来假设个环境好了:
结果如下:
说明:
从输出的结果来看, agcount 没啥问题, sunit 结果是 64 个 block,因为每个 block 为 4K,所以算出来容量就是 256K 也没错! 那个 swidth 也相同!使用 448 * 4K 得到 1792K!那个 extsz 则是算成 bytes 的单位,换算结果也没错啦!
(d)上面是个方式,那如果使用 sunit 与 swidth 直接套用在mkfs.xfs 当中呢?那你得小心了!因为指令中的这两个参数用的是『几个 512bytes 的 sector 数量』的意思! 是『数量』单位而不是『容量』单位!
因此先计算为:
(a)指令介绍
因为 ext4 的默认值已经相当适合我们系统使用,大部分的默认值写入于我们系统的 /etc/mke2fs.conf 这个文件中。
(b)
(a)指令介绍
(b)如果要将刚刚的 /dev/vda5 重新格式化为 VFAT 文件系统呢?
(1) 现在我们知道文件系统运作时会有磁盘与内存数据异步的状况发生,因此莫名其
妙的当机非常可能导致文件系统的错乱。
(1)挂载点是目录,不过要进行挂载前,你最好先确定几件事:
尤其是上述的后两点!如果你要用来挂载的目录里面并不是空的, 那么挂载了文件系统之后,原目录下的东西就会暂时的消失。并不是被覆盖掉, 而是暂时的隐藏了起来,等
到新分区槽被卸除之后,则 原本的内容就会再次的跑出来啦!
(3)CentOS是怎么找出文件系统类型的呢?
由于文件系统几乎都有 superblock ,我们的 Linux 可以透过分析superblock 搭配 Linux 自己的驱动程序去测试挂载, 如果成功的套和了,就立刻自动的使用该类型的文件系统挂载起来啊!
(4)那么系统有没有指定哪些类型的 filesystem 才需要进行上述的挂载测试呢?
主要是参考底下这两个文件:
(5)那我怎么知道我的 Linux 有没有相关文件系统类型的驱动程序呢?
Linux 支持的文件系统之驱动程序都写在如下的目录中:
(7)整个目录树最重要的地方就是根目录了,所以根目录根本就不能够被卸除的!
根目录出现『只读』状态时,如何重新挂载呢?
最可能的处理方式就是重新启动 (reboot)!
不过你也可以这样做:
说明:
(a)这并不是挂载文件系统,而是额外挂载某个目录的方法!
虽然上面的方法也可以使用 symbolic link 来连结,不过在某些不支持符号链接的程序运作中,还是得要透过这样的方法才行
(b)透过这个 mount --bind 的功能, 您可以将某个目录挂载到其他目录去喔!而并不是整块 filesystem 的啦!所以从此进入 /data/var 就是进入/var 的意思喔!
(ii)由于通通卸除了,此时你才可以退出光盘片、软盘片、 USB 随身碟等设备喔!
(iii)由于你目前正在 /data/cdrom/ 的目录内,也就是说其实『你正在使用该文件系统』的意思!所以自然无法卸除这个装置!那该如何是好?
就『离开该文件系统的挂载点』即可。
以上述的案例来说, 你可以使用『cd / 』回到根目录,就能够卸除 /data/cdrom 啰!简单吧!
(1)修改一下目前文件系统的一些相关信息;
举例来说,你可能要修改 Labelname , 或者是 journal 的参数,或者是其他磁盘/文件系统运作时的相关参数 (例如 DMA 启动与否~)。
就是透过文件的 major 与 minor 数值来替代的。
那个 major 与 minor 数值是有特殊意义的,不是随意设定的喔!我们在 lsblk 指令的用法里面也谈过这两个数值呢!
eg:在鸟哥的这个测试机当中, 那个用到的磁盘 /dev/vda 的相关装置代码如下:
(b)指令含义
(c)eg
(1)开机挂载,必须要修改/etc/fstab
(2)系统挂载的限制如下:
(3) /etc/fstab 的内容如下:
说明:
这个文件的内容共有六个字段,这六个字段非常的重要!
(a)第一栏:磁盘装置文件名/UUID/LABEL name:
(b)挂载点 (mount point):
挂载点是什么?一定是目录啊
(c)第三栏:磁盘分区槽的文件系统:
在手动挂载时可以让系统自动测试挂载,但在这个文件当中我们必须要手动写入文件系统才行!包括 xfs, ext4, vfat, reiserfs, nfs 等等。
(d)文件系统参数:
记不记得我们在 mount 这个指令中谈到很多特殊的文件系统参数?
还有我们使用过的『-o codepage=950』?这些特殊的参数就是写入在这个字段啦!
(e)能否被 dump 备份指令作用:
dump 是一个用来做为备份的指令,所以这个项目可以不要理会啦!
(f)是否以 fsck 检验扇区:
我们现在用的 xfs 文件系统就没有办法适用,因为 xfs会自己进行检验,不需要额外进行这个动作!所以直接填 0 就好了。
eg:
说明:
(i)/etc/fstab 是开机时的配置文件,不过, 实际 filesystem 的挂载是记录到 /etc/mtab 与 /proc/mounts 这两个文件当中的。
那时候的/ 可是 read only 的状态,当然你就无法修改 /etc/fstab ,也无法更新 /etc/mtab 啰
底下我们在 /srv 下建立一个 512MB 左右的大文件,然后将这个大文件格式化并且实际挂载来玩一玩!
假设我要建立一个空的文件在 /srv/loopdev ,那可以这样做:
(b)大型文件的格式化
预设 xfs 不能够格式化文件的,所以要格式化文件得要加入特别的参数才行喔!
注意UUID的参数。
那要如何挂载啊?利用 mount 的特殊参数,那个 -o loop 的参数来处理!
(1)从第零章的计算器概论当中,我们知道 CPU 所读取的数据都来自于内存, 那当内存不足的时候,为了让后续的程序可以顺利的运作,因此在内存中暂不使用的程序与数据就会被挪到 swap 中了。 此时内存就会空出来给需要执行的程序加载。
由于swap 是用磁盘来暂时放置内存中的信息, 所以用到 swap 时,你的主机磁盘灯就会开始闪个不停啊!
(2)下面的情况是:
你已经将系统建立起来了,此时却才发现你没有建置 swap ~那该如何是好呢?
(2)让我们继续分区出 512MB 的磁盘分区槽吧! 然后将这个磁盘分区槽做成 swap 吧!
如果是在实体分区槽无法支持的环境下,此时前一小节提到的 loop 装置建置方法就派的上用场啦!
(1)使用 dd 这个指令来新增一个 128MB 的文件在 /tmp 底下:
(2)使用 mkswap 将 /tmp/swap 这个文件格式化为 swap 的文件格式:
(3)使用 swapon 来将 /tmp/swap 启动啰!
(4)使用 swapoff 关掉 swap file,并设定自动启用
说明:
我们的 Linux 系统大概都用不到 swap这个玩意儿的。
不过, 如果是针对服务器或者是工作站这些常年上线的系统来说的话,那么,无论如何, swap 还是需要建立的。
另外,有某些程序在运作时,本来就会利用 swap 的特性来存放一些数据段, 所以, swap 来是需要建立的!只是不需要太大!
举例来说,那个 crontab 虽然仅有 451bytes , 不过他却占用了整个 block (每个 block 为 4K),所以将所有的文件的所有的 block加总就得到 12Kbytes 那个数值了。
(2)以 parted 列出目前本机的分区表资料
我们将上述的分区表示意拆成六部分来说明:
如果你想要固定单位,例如都用 MB 显示的话,可以这样做:
(3)
说明:如果你想要将原本的 MBR 改成 GPT 分区表,或原本的 GPT 分区表改成 MBR 分区表,也能使用 parted ! 但是请不要使用 vda 来测试!因为分区表格式不能转换!因此进行底下的测试后,在该磁盘的系统应该是会损毁的!
(4)接下来我们尝试来建立一个全新的分区槽吧!再次的建立一个 512MB 的分区来格式化为 vfat,且挂载于 /data/win 喔!
(1) 一个可以被挂载的数据通常称为『文件系统, filesystem』而不是分区槽 (partition) 喔!
(2)基本上 Linux 的传统文件系统为 Ext2 ,该文件系统内的信息主要有: