鸟哥的私房菜:Linux磁盘与文件系统原理
1 硬盘物理组成 //原理
磁头负责读写
磁道(硬盘同半径的一圈) 磁柱(所有盘磁道叠加起来的柱)
扇区(2条半径将磁道分开的一个扇形区域,是磁盘的最小存储单位)
-----------------------------------------------------------------------------------------------------------------------------------
2 磁盘分割 //原理
磁柱是磁盘分割的最小单位
磁盘分割就是指定一个分割(Partition)的是从A磁柱到B磁柱
所有磁盘的分割信息存放在MBR(主要开机扇区,master boot recoder),即一块硬盘的第0轨上。计算机一开机就会去读取这个区域。
由MBR的含义知,若一个硬盘的MBR挂了,这块硬盘就等于挂了。
MBR的限制:MBR的大小决定了它不能存储很多的分割信息,最多只能记忆四个分割的信息(主分区和扩展分区都称为一个分割),而扩展分区最多只能有一个。
由以上知识知,一块硬盘最多四个分割,且扩展分区只能有一个。举个例子,若你分割了3p+1E,那么你就不能再分割分区了。
3 档案系统(文件系统) //原理
在告知系统我的 partition 所在的起始与结束磁柱之后,再来则是需要将 partition 格式化为『我的操作系统认识的档案系统( Filesystem )』
我们可以说,每一个 partition 就是一个 Filesystem。
刚刚我们提到硬盘的最小储存单位是 sector ,不过数据所储存的最小单位并不是 sector ,因为用 sector 来储存太没有效率了。 为了克服这个效率上的困扰,所以就有逻辑区块(
Block )的产生了! 逻辑区块是在 partition 进行 filesystem 的格式化时, 所指定的『最小储存单位』,这个最小储存单位当然是架构在 sector 的大小上面( 因为 sector 为硬盘的最小物理储存单位啊! ),所以 Block 的大小为 sector 的 2 的次方倍数。
规划Block大小的考量:档案读取效率;档案大小可能造成的空间浪费
Superblock:如同前面说的,当我们在进行磁盘分割( partition )时,每个磁盘分割槽( partition )就是一个档案系统(
filesystem ), 而每个档案系统开始的位置的那个 block 就称为 superblock ,superblock 的作用是储存像是档案系统的大小、空的和填满的区块,以及他各自的总数和其它诸如此类的信息等等, 这也就是说,当您要使用这一个磁盘分割槽( 或者说是档案系统 )来进行数据存取的时候,第一个要经过的就是 superblock 这个区块了,所以啰, superblock 坏了,您的这个磁盘槽大概也就回天乏术了!
注意啦,MBR和Superblock是两个层次上的东西!!!
磁盘分割,档案系统的关系:在磁盘分割选择文件系统的格式时,此时格式化,就把某种格式的文件系统架构在磁盘之上了。
------------------------------------------------------------------------------------------------------------------------------------
4 Linux的EX3档案系统 //原理
Linux的档案不仅具有档案内容,还有档案属性。Linux文件系统将档案属性(存放在inode中)和档案内容(存放在block中)分开来存储。
当一个partition被格式化为ext2文件系统时,就会有inode table和block area这两个区域,inode都在inode table这个区域,block在block area区域。
Block 已经在前面说过了,他是数据储存的最小单位。那么 inode 是什么?!简单的说, Block 是记录『档案内容数据』的区域,至于 inode 则是记录『该档案的相关属性,以及档案内容放置在哪一个 Block 之内』的信息。 简单的说, inode 除了记录档案的属性外,同时还必须要具有指向( pointer
)的功能,亦即指向档案内容放置的区块之中,好让操作系统可以正确的去取得档案的内容。
Linux 系统到底是如何读取一个档案的内容呢?底下我们分别针对目录与档案来说明:
目录: 当我们在 Linux 下的 ext2 档案系统建立一个目录时, ext2 会分配一个 inode 与至少一块 Block 给该目录。其中,inode 记录该目录的相关属性,并指向分配到的那块 Block ;而 Block 则是记录在这个目录下的相关连的档案(或目录)的关连性!
档案: 当我们在 Linux 下的 ext2 建立一个一般档案时, ext2 会分配至少一个 inode 与相对于该档案大小的 Block 数量给该档案。例如:假设我的一个 Block 为 4 Kbytes ,而我要建立一个 100 KBytes 的档案,那么 linux 将分配一个 inode 与 25 个 Block 来储存该档案!
要注意的是, inode 本身并不纪录文件名,而是记录档案的相关属性,至于文件名则是记录在目录所属的 block 区域! 那么档案与目录的关系又是如何呢?就如同上面的目录提到的,档案的相关连结会记录在目录的 block 数据区域, 所以当我们要读取一个档案的内容时,我们的
Linux 会先由根目录 / 取得该档案的上层目录所在 inode , 再由该目录所记录的档案关连性 (在该目录所属的 block 区域) 取得该档案的 inode , 最后在经由 inode 内提供的 block 指向,而取得最终的档案内容。我们以 /etc/crontab 这个档案的读取为例, 他的内容数据是这样取得的:
另外,关于 EXT2 档案系统,这里有几点小事情要提醒一下:(理解一下)
? ext2 与 ext3 档案在建立时 (format) 就已经设定好固定的 inode 数与 block 数目了;
? ext2 允许的 block size 为 1024, 2048 及 4096 bytes;
? 一个 partition (filesystem) 所能容许的最大档案数,与 inode 的数量有关, 因为一个档案至少要占用一个 inode 啊!
? 在目录底下的档案数如果太多而导致一个 Block 无法容纳的下所有的关连性数据时,Linux 会给予该目录多一个 Block 来继续记录关连数据;
? 通常 inode 数量的多寡设定为 (partition 的容量) 除以 (一个 inode 预计想要控制的容量)。 举例来说,若我的 block 规划为 4Kbytes,假设我的一个 inode 会控制两个 block ,亦即是假设我的一个档案大致的容量在 8Kbytes 左右时,假设我的这个 partition 容量为 1GBytes, 则 inode 数量共有:( 1G * 1024M/G * 1024K/M ) / (
8K ) = 131072 个。而一个 inode 占用 128 bytes 的空间,因此格式化时就会有 ( 131072个 * 128bytes/个 ) = 16777216 byes = 16384 Kbytes 的 inode table 。也就是说,这一个 1GB 的 partition 在还没有储存任何数据前, 就已经少了 16MBytes 的容量啊!
? 因为一个 inode 只能记录一个档案的属性,所以 inode 数量比 block 多是没有意义的! 举上面的例子来说,我的 Block 规划为 4 Kbytes ,所以 1GB 大概就有 262144 个 4Kbytes 的 block ,如果一个 block 对应一个 inode 的话,那么当我的 inode 数量大于 262144 时,多的 inode
将没有任何用处,徒然浪费硬盘的空间而已!另外一层想法,如果我的档案容量都很大, 那么一个档案占用一个 inode 以及数个 block ,当然 inode 数量就可以规划的少很多啦!
? 当 block 大小越小,而 inode 数量越多,则可利用的空间越多,但是大档案写入的效率较差; 这种情况适合档案数量多,但是档案容量小的系统,例如 BBS 或者是新闻群组( News )这方面服务的系统;
? 当 Block 大小越大,而 inode 数量越少时,大档案写入的效率较佳,但是可能浪费的硬盘空间较多; 这种状况则比较适合档案容量较大的系统!
------------------------------------------------------------------------------------------------------------------------------------
5 Ex2文件系统的存储架构图及原理 //原理
当一个 ext2 的 filesystem 被建立时, 他拥有 superblock / group description / block bitmap / inode bitmap / inode table / data blocks 等等区域。要注意的是,每个 ext2 filesystem 在被建立的时候,会依据 partition 的大小, 给予数个 block
group ,而每个 block group 就有上述的这些部分。整个 filesystem 的架构可以下图展现:
我们将整个 filesystem 简单化, 假设仅有一个 block group ,那么上面的各个部分分别代表什么呢:
?SuperBlock:如前所述, Superblock 是记录整个 filesystem 相关信息的地方, 没有 Superblock ,就没有这个 filesystem 了。他记录的信息主要有:
o block 与 inode 的总量;
o 未使用与已使用的 inode / block 数量;
o 一个 block 与一个 inode 的大小;
o filesystem 的挂载时间、最近一次写入数据的时间、最近一次检验磁盘 (fsck) 的时间等档案系统的相关信息;
o 一个 valid bit 数值,若此档案系统已被挂载,则 valid bit 为 0 ,若未被挂载,则 valid bit 为 1 。
? Group Description:纪录此 block 由由何处开始记录;
? Block bitmap:此处记录那个 block 有没有被使用;
? Inode bitmap:此处记录那个 inode 有没有被使用;
? Inode table:为每个 inode 数据存放区;
? Data Blocks:为每个 block 数据存放区。
当我们新增一个档案(目录)时:
1. 根据 inode bitmap / block bitmap 的信息,找到尚未被使用的 inode 与 block , 进而将档案的属性与数据分别记载进 inode 与 block ;
2. 将刚刚被利用的 inode 与 block 的号码 (number) 告知 superblock、inode bitmap、block bitmap 等,让这些 metadata 更新信息。一般来说,我们将 inode table 与 block area 称为数据存放区域,至于其它的例如 superblock、 block bitmap 与
inode bitmap 等记录就被称为 metadata 啰。经由上面两个动作,我们知道一笔数据写入硬盘时, 会有这两个动作。
------------------------------------------------------------------------------------------------------------------------------------
6 档案系统的运作 //原理
好了,我们知道整个 ext2/ext3 的数据存取是透过 journal(日志) 与 metadata 还有数据存放区在纪录的。 不过,实际上, Linux 档案系统在运作的时候,真的要将数据直接存放到硬盘上面吗?!
为了让 Linux 加快整个系统的存取效率,因此在 Linux 上面通常采取异步处理( asynchronously )的方式。 什么是异步呢?举例来说:『当系统读取了某一个档案, 则该档案所在的区块数据会被加载到内存当中,所以该磁盘区块就会被放置在主存储器的缓冲快取区中,
若这些区块的数据被改变时,刚开始数据仅有主存储器的区块数据会被改变, 而且在缓冲区当中的区块数据会被标记为『 Dirty 』,这个时候磁盘实体区块尚未被修正! 所以亦即表示,这些『 Dirty 』区块的数据必需回写到磁盘当中, 以维持磁盘实体区块上的数据与主存储器中的区块数据的一致性。』
为什么要这么做呢?这是因为主存储器的运作速度比起硬盘来实在是快太多了, 万一系统当中有一个档案相当的大,而又持续性的存取,那么由于较慢的硬盘存取速度,将使得整个 Linux 速度被拖垮,所以才会使用异步方式的数据处理啊!
不过, 也由于硬盘与主存储器的数据可能没有同步化,因此,如果 Linux 不正常关机( 例如跳电或者是当机 )时,会导致系统在再次开机时,会花相当多的时间进行磁盘检验, 同时也有可能造成磁盘的损毁啊!
------------------------------------------------------------------------------------------------------------------------------------
7 挂载点的意义
挂载点一定是『目录』而不是档案喔! 也就是说,这个挂载点就是进入该 filesystem 的入口。
-----------------------------------------------------------------------------------------------------------------------------------
8 磁盘与目录容量 // 实践
1) 显示目前磁盘的总容量与剩余可用容量的指令
df [参数] 目录或文件名
2) 列出目录下各个档案所占的容量
du [参数] 目录或文件名
------------------------------------------------------------------------------------------------------------------------------------
9 文档链接——超链接
1) hard link
Hard Link 只是在某个目录下新增一个该档案的关连数据而已!
举个例子来说,假设我的 /root/crontab 为一个 hard link 的档案,他连结到 /etc/crontab 这个档案,也就是说,其实 /root/crontab 与 /etc/crontab 是同一个档案,只是有两个目录( /etc 与 /root )记录了 crontab 这个档案的关连数据罢了!也就是说,我由 /etc 这个目录所记录的关连数据可知道 crontab 的 inode 放置在 A 处,而由
/root 这个目录下的关连数据, crontab 同样也指到 A 处的 inode !所以啰, crontab 这个档案的 inode 与 block 都没有改变, 有的只是有两个目录记录了关连数据。 那这样有什么好处呢?最大的好处就是『安全!』如同上面提到的 /root/crontab 与 /etc/crontab 中, 不管哪一个档案被删除了,其实仅是移除一笔目录底下的档案关连性数据,并没有更动到原本档案的 inode 与 block 数据呢!而且,不论由那个目录连结到正确的 crontab 的 inode
与 block , 都可以正确无误的进行数据的修改喔!
一般来说,使用 hard link 设定连结文件时,磁盘的空间与 inode 的数目都不会改变! 由上面的说明来看,我们可以知道, hard link 只是在某个目录下的 block 多写入一个关连数据,所以当然不会用掉 inode 与磁盘空间啰!
Tips: 其实可能会改变的,那就是当目录的 Block 被用完时,就可能会新加一个 block 来记录,而导致磁盘空间的变化!不过,一般hard link 所用掉的关连数据量很小,所以通常不会改变 inode 与磁盘空间的大小喔!
由于 hard link 是在同一个 partition 上面进行数据关连的建立,所以 hard link 是有限制的:
? 不能跨 Filesystem;
? 不能 link 目录。
不能跨 Filesystem 还好理解,因为 hard link 本来就是在一个 partition 内建立关连性的, 那不能 hard link 到目录又是怎么回事呢?这是因为如果使用 hard link 连结到目录时, 连结的数据被需要连同被连结目录底下的所有数据都建立连结,因此造成环境相当大的复杂度。目前 hard link 对于目录暂时还是不支持.
2) symbol link
相对于 hard link , Symbolic link 可就好理解多了,基本上,Symbolic link 就是在建立一个独立的档案, 而这个档案会让数据的读取指向他 link 的那个档案内容!由于只是利用档案来做为指向的动作, 所以,当来源档被删除之后,symbolic link 的档案会『开不了』,
会一直说『无法开启某档案!』。这里还是得特别留意,这个 Symbolic Link 与 Windows 的快捷方式可以给他划上等号,由 Symbolic link 所建立的档案为一个独立的新的档案,所以会占用掉 inode 与block 喔!
由上面的说明来看,似乎 hard link 比较安全,因为即使某一个目录下的关连数据被杀掉了, 也没有关系,只要有任何一个目录下存在着关连数据,那么该档案就不会不见!举上面的例子来说,我的 /etc/crontab 与 /root/crontab 指向同一个档案,如果我删除了 /etc/crontab 这个档案,该删除的动作其实只是将 /etc 目录下关于 crontab 的关连数据拿掉而已, crontab 所在的 inode
与 block 其实都没有被变动喔!
不过,不幸的是,由于 Hard Link 的限制太多了,包括无法做『目录』的 link , 所以在用途上面是比较受限的!反而是 Symbolic Link 的使用方面较广喔!好了, 说的天花乱坠,看您也差不多快要昏倒了!没关系,实作一下就知道怎么回事了!要制作连结档就必须要使用 ln 这个指令(具体用法参见help)呢!
关于目录的 link 数量:
或许您已经发现了,那就是,当我们以 hard link 进行『档案的连结』时,可以发现,在 ls -l 所显示的第二字段会增加一才对,
那么如果建立目录时,他预设的 link 数量会是多少? 让我们来想一想,一个『空目录』里面至少会存在些什么?呵呵!就是存在 . 与 .. 这两个目录啊! 那么,当我们建立一个新目录名称为
/tmp/testing 时,基本上会有三个东西,那就是:
• /tmp/testing
• /tmp/testing/.
• /tmp/testing/..
而其中 /tmp/testing 与 /tmp/testing/. 其实是一样的!都代表该目录啊~而 /tmp/testing/.. 则代表/tmp 这个目录,所以说,当我们建立一个新的目录时,
『新的目录的 link 数为 2 ,而上层目录的 link数则会增加 1 』
鸟哥的私房菜:Linux磁盘与文件系统原理的更多相关文章
- [Linux]《鸟哥的私房菜》笔记 (缓慢更新)
暂时不更新了..这几天一看起书来发现内容很多,这样写blog太慢,也没意义.所以现在是每天看书,在笔记本上记笔记,再配合着<操作系统>和 linux内核 加深理解.往后会以心得体会为主写一 ...
- linux: 鸟哥的私房菜
鸟哥的私房菜 http://vbird.dic.ksu.edu.tw/linux_basic/0320bash.php
- 鸟哥的私房菜:Bash shell(二)-变量的丰富功能
一 Shell变量的取用与设定,变量规则 由于系统需要一些变量来提供他数据的存取,所以就有一些所谓的『环境变量』 需要来读入系统中了!这些环境变量例如 PATH.HOME.MAIL.SHELL.为了 ...
- 鸟哥的私房菜:Linux文件与目录管理
1. 目录与路径 1.1 相对路径与绝对路径 绝对路径:路径的写法『一定由根目录 / 写起』,如:/usr/share/doc 这个目录. 相对路径:路径的写法『不是由 / ...
- 41个linux命令大全(鸟哥的私房菜)
转http://www.xmws.cn/show-87-419-1.html 41个linux命令大全 发布作者:微思网络 发布时间:2017-01-10 浏览量:709次 学过linux的人 ...
- (整理)ubuntu 的 相关知识(来自 鸟哥的私房菜)
1. Linux 文件权限概念 $ ls 察看文件的指令 $ ls -al 出所有的文件详细的权限与属性 (包含隐藏档,就是文件名第一个字符为『 . 』的文件) 在你第一次以root身份登入Linux ...
- 鸟哥的私房菜上 xpenguins 设备(ubuntu 12.04)
看了一个暑假linux,我觉得很辛苦啊,要很好地利用linux并不是的easy... 今天装了一下鸟哥课后给的xpenguins软件,就是桌面特性软件.会有非常多企鹅下落,本以为能够非常轻松的搞定.没 ...
- 鸟哥的私房菜:Bash shell(六)-管道命令
就如同前面所说的, bash 命令执行的时候有输出的数据会出现! 那么如果这群数据必需要经过几道手续之后才能得到我们所想要的格式,应该如何来设定? 这就牵涉到管线命令的问题了 (pipe) ,管线命令 ...
- 鸟哥的私房菜:Bash shell(四)-Bash shell的使用环境
Bash shell(四)-Bash shell的使用环境 是否记得我们登入主机的时候,屏幕上头会有一些说明文字,告知我们的 Linux 版本啊什么的, 还有,登入的时候,我们还可以给予使用者一些 ...
- Linux鸟哥的私房菜(3)— 总体规划和磁盘分区 读书笔记
1.每个硬件设备Linux中的文件名称 在Linux系统中.每一个设备都被当成一个文件来对待.而且差点儿全部的硬件设备文件都在/dev文件夹下 常见设备与其对于文件名称 2.磁盘连接的方式与设备文件名 ...
随机推荐
- springboot集成mybatis环境搭建以及实现快速开发微服务商品模块基本的增删改查!
之前学习了springboot和mybatis3的一些新特性,初步体会了springboot的强大(真的好快,,,,,),最近趁着复习,参考着以前学习的教程,动手写了一个springboot实战的小例 ...
- NOIP 2016 迟来的满贯
17-03-22,雨 17-03-22,一个特别重要的日子 在这一天,本蒻攻克了NOIP 2016最难的一题,D1T2——天天爱跑步 实现了NOIP 2016的AK! YAYAYAYAYAYAY 自然 ...
- 【网页开发学习】Coursera课程《面向 Web 开发者的 HTML、CSS 与 Javascript》Week1课堂笔记
Coursera课程<面向 Web 开发者的 HTML.CSS 与 Javascript> Johns Hopkins University Yaakov Chaikin Week1 In ...
- Java不为人知的小秘密
Java中的main方法必须有一个外壳类,而且必须是静态的! Java中的所有函数都属于某个类的方法,所以main方法也不例外,必须放在一个类中才能编译运行. 例如: public class tex ...
- ifdef等宏的妙用
条件编译 一般情况下,源程序中所有的行都参加编译.但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是"条件编译". 条件编译命令最常见 ...
- Python_oldboy_自动化运维之路_函数,装饰器,模块,包(六)
本节内容 上节内容回顾(函数) 装饰器 模块 包 1.上节内容回顾(函数) 函数 1.为什么要用函数? 使用函数之模块化程序设计,定义一个函数就相当于定义了一个工具,需要用的话直接拿过来调用.不使用模 ...
- MFC的定时函数 SetTimer和结束killTimer
什么时候我们需要用到SetTimer函数呢?当你需要每个一段时间执行一件事的的时候就需要使用SetTimer函数了. 使用定时器的方法比较简单,通常告诉WINDOWS一个时间间隔,然后WINDOWS以 ...
- arp命令 清arp表
平常删除arp都用arp-d.大量存在的时候 arp -n|awk '/^[1-9]/ {print arp -d $1}' | sh 清除所有arp表,以前用这个来清arp表貌会清空,没注意到存在i ...
- 生成Insert语句的存储过程
) drop procedure [dbo].[spGenInsertSQL] GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO )) as b ...
- CCF CSP 201612-2 工资计算
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201612-2 工资计算 问题描述 小明的公司每个月给小明发工资,而小明拿到的工资为交完个人所 ...