第9章:磁盘存储器管理
0 学完本章 你会:
在此之前,我们需要知道几个关键概念:
- 盘块(物理块)
是操作系统对外存(如硬盘、U盘)进行读写和管理的最小逻辑单位。一个盘块通常对应一个或多个连续的物理扇区(扇区是硬件层面的最小读写单元,传统硬盘一个扇区512字节,现在也有4KB的)。
🗺️ 本章知识地图
| 章节 | 核心内容 | 一句话总结 |
|---|---|---|
| 1.1 外存组织 | 连续/链接/索引三种方式 | 文件怎么存到磁盘上 |
| 1.2 空间管理 | 空闲表/链表/位示图/成组链接 | 怎么知道哪些块是空的 |
| 1.3 提高I/O速度 | 磁盘缓存/提前读/延迟写/RAID | 怎么让磁盘读写更快 |
| 1.4 可靠性 | SFT-I/II/III 容错技术 | 磁盘坏了怎么办 |
| 1.5 存储新技术 | DAS/NAS/SAN/SSD | 现代存储长什么样 |
| 1.6 数据一致性 | 事务/检查点/并发控制 | 怎么保证数据不出错 |
1.1 外存的组织方式
1.1.1 连续组织方式
原理:就像数组在内存中占用连续空间一样,文件被存放在磁盘上一组连续的物理块中。文件目录项中只需要记录该文件的起始块号和总块数即可。
优点:
- 实现简单,目录项信息极少。
- 顺序访问速度非常快,磁头不需要大幅度移动。
- 既支持顺序存取,也支持直接存取(随机访问),你可以通过起始块号加上偏移量直接计算出目标物理地址。
缺点:
- 会产生外部碎片。随着文件的不断创建和删除,磁盘上会出现许多零散的小空闲区,虽然总和很大,但无法分配给需要连续空间的大文件。
- 文件长度难以动态增长。创建文件时必须预先知道并声明文件最大长度,否则后续没有相邻空间就无法扩展。
- 和数组类似,不能灵活地删除和插入记录。
对于外部碎片,这个概念还是有些抽象,换一个更形象的例子:想象有一个非常大的自助储物柜,你在存很多东西时,系统会给你连续的几个柜子(比如10~15号)。取放东西时,走到那片柜子区域就能快速存取。但如果你后来多了一个小包想塞进去,相邻的16号柜子可能已经被别人占了,你就没法扩展。而且,如果大家存的大小不一,退租后会出现很多零散空位,后来的大行李箱放不进去。
从图片我们可以得知,为了定位一个文件的位置我们需要知道它的起始盘块号和它的长度,类似于数组的定义,我们要知道它在内存中的起始位置和长度。
1.1.2 链接组织方式
类似于链表,一个盘块里有着数据和指向下一个盘块的指针,文件目录项记录着头指针或尾指针。
隐式链接
指针直接存放在每个数据块的末尾或开头,对用户透明。要访问第N块,必须从第一块开始逐个沿着指针链查找。
缺点是只能顺序访问,随机访问效率极低,而且任何一个中间的指针损坏都会导致文件后续数据全部丢失。显式链接
- 把所有的链接指针从数据块中提取出来,集中存放在内存的一张表里面,这张表叫做文件分配表(FAT,File Allocation Table)。
- 磁盘上每个物理块在FAT中对应一个表项,记录了下一块的块号。文件目录项只需记录文件的首块号。
- 访问时先在内存中查FAT表,确定物理块号后再去磁盘读取数据。
- 优点:查找速度快,不需要读磁盘就能确定块的链接关系;
- 缺点:FAT表需要占用内存空间,磁盘容量越大,FAT表越大。
FAT文件系统
FAT引入了”卷”的概念,这也是我们Windows上C盘、D盘等磁盘的雏形。一个物理磁盘被分成若干个逻辑磁盘(卷),每个卷都是一个能够被单独格式化和使用的逻辑单元。在我们现代OS上,一个物理磁盘不仅可以被划分为多个卷,一个卷也可以由多个物理磁盘组成。
核心思想:用一张全局的FAT,来记录每个文件占用了哪些盘块,以及它们之间的链接关系。
簇:一组连续扇区组成的分配单位。引入簇是为了缩小FAT表大小、提高I/O性能,代价是可能产生内部碎片。为什么引入簇?
假设一个20MB的磁盘,扇区大小512字节,总扇区数 ≈ 20MB / 512B = 40960个。每个FAT表项需要16位(2字节)来记录下一个扇区号(因为2^16=65536,足够)。那么一张FAT表的大小 = 40960 × 2B = 80KB。两张就是160KB。对于当时只有640KB内存的DOS系统,这个开销还能接受。
但如果磁盘容量增加到1GB(1990年代),扇区数 = 1GB / 512B ≈ 2百万个。每个表项至少需要4字节(32位)才能表示2百万个号,一张FAT表 = 2M × 4B = 8MB,两张就是16MB。而当时用户内存可能只有4-8MB,根本装不下整个FAT表。FAT表太大,无法全部加载到内存,严重降低性能。引入簇的好处:
- 显著减小FAT表大小
例如,1GB的磁盘,如果簇大小为8KB(即16个扇区),那么总簇数 = 1GB / 8KB = 131072个。每个表项仍用4字节(FAT32),FAT表大小 = 131072 × 4B = 512KB。两张表也只占1MB,可以轻松放入内存。 - 减少文件碎片,提高I/O性能
因为一次读写一个簇,相当于一次传输多个连续扇区,减少了磁头移动次数。对于大文件,顺序读取的吞吐量更高。
下面我们来直观的感受一下过程:
- 文件存储过程(假设簇大小为4KB)
- 创建一个文件a.txt,内容占用12KB。
- 文件系统从FAT表中查找空闲簇,假设找到簇#100、#150、#200。
- 目录项中记录:文件名为a.txt,起始簇号为100。
- 在FAT表中:
- 第100项的值设为150(表示下一簇是150)
- 第150项的值设为200
- 第200项的值设为0x0FFFFFFF(FAT32的结束标志)
- 读取文件时,从目录拿到起始簇100,然后查FAT表依次得到150、200,再到数据区读取这些簇的内容。
版本 簇号位数 最大分区容量 主要应用场景 FAT12 12-bit 最大约 32 MB 早期软盘 FAT16 16-bit 最大 2 GB MS-DOS、早期Windows、老旧U盘 FAT32 32-bit(实际使用28-bit,因为首四位不用) 理论 8 TB,Windows系统限制格式化最大 32 GB U盘、SD卡、绝大多数移动设备 - 显著减小FAT表大小

这张表打重点,万一考你画表了呢?
共同优点:
- 没有外部碎片,磁盘空间利用率高。
- 文件可以很方便地动态增长。
- 能够灵活的进行插入和删除操作
共同缺点:
- 随机访问能力差
- 两者都需要额外的内存开销存放指针或FAT
- 可靠性差,链接指针出现问题会造成数据丢失
1.1.3 索引组织方式
为每个文件建立一张索引表,索引表中记录了该文件所有数据块对应的物理块号。文件目录项中记录的是索引表所在的物理块号(称为索引块)。
访问文件时,先读出索引块,根据其中的地址映射表再读取具体的数据块。
- 单级索引组织方式:一个索引块直接指向所有数据块。适合小型文件。
- 多级索引组织方式:用第一层索引块指向第二层索引块,第二层再指向数据块,以此类推。比如两级索引、三级索引。适合大型文件,但访问需要多次读磁盘。
优点:
既支持顺序访问,也支持高效的随机访问(通过索引表直接计算目标块号)。
没有外部碎片,文件可以动态增长(只需在索引表中增加新记录)。
能够灵活地进行插入、修改和删除等操作
缺点:需要额外空间存储索引块(对于小文件,索引块开销相对较大)。
增加了寻道次数和寻道时间。
增量式索引组织方式:
实际操作系统往往综合使用上述方式
以UNIX系统为例:
- 文件控制块(inode)中有13个地址项。
- 前10项是直接索引(直接指向数据块),适合小文件。
- 第11项是一级间接索引(指向一个索引块,该块再指向数据块)。
- 第12项是二级间接索引。
- 第13项是三级间接索引。
这样,小文件访问效率高,大文件又能通过多级索引扩展,兼顾了性能与灵活性。
思考题:假设有一个含有 100 万条记录的文本文件,每条记录均包括:姓名(长度为 2~64 个汉字,平均长度为 4 个汉字)、年龄、性别、家庭地址和身份证号码。对该文件的操作主要是根据姓名进行记录查询,请思考为该文件设计哪种组织方式可使其具有访问效率高和所需存储空间少的优点。
💡 已掌握 1.1? 三种组织方式搞定了”怎么存”,接下来解决”哪些块空着”的问题。
1.2 文件存储空间的管理
1.2.1 空闲区表法和空闲链表法
1. 空闲区表法
原理:系统维护一张空闲表,表中每一项记录一组连续空闲块的起始块号和块数。类似于内存管理中的“可变分区”方式。
分配与回收:
- 分配时,扫描空闲表,找到第一组足够大的连续空闲块,从中分割所需块数(剩余部分仍作为一项)。
- 回收时,检查回收块与前后空闲块是否相邻,若相邻则合并为一项。
优点:简单,适合连续分配方式的文件系统(如早期的FAT之前的一些系统)。
缺点:会产生外部碎片;空闲表本身可能较大(如果磁盘很零碎,表项很多);分配时需要扫描表。
2. 空闲链表法
原理:把所有空闲盘块(或簇)用链表串起来。系统保存一个头指针指向第一个空闲块。每个空闲块里存放指向下一个空闲块的指针。
分配与回收:
- 分配时,从链表头取下一个空闲块,头指针后移。
- 回收时,将回收块插入链表头部(或尾部)。
优点:简单,无需额外表格,只需一个头指针。
缺点:无法获得连续的空闲块(每次只能取一个块),容易造成文件碎片(文件被分散到不连续的块中);分配/回收效率低(如果一次需要多个块,就需要多次操作链表;链表遍历较慢,但通常只操作头部)。
1.2.2 位示图法
原理:用一张二进制位图(Bitmap)来表示每个盘块(或簇)的状态。每个盘块对应一个位(bit):0表示空闲,1表示已分配。位示图可以存放在内存中,也可以存放在磁盘上(定期保存)。
分配与回收:
- 分配时,扫描位图找到连续的0位(如果要求连续块),或将多个0位逐个分配。通常从第一个空闲位开始。
- 回收时,将对应位清零。
优点:
- 简单高效,位图可完全放入内存(例如1TB硬盘,4KB块,共2.5亿个块,位图大小≈30MB),内存可接受。
- 容易找到连续的空闲块(只需在内存中扫描连续0位)。
- 位图操作可以通过位运算加速。
缺点:
- 位图本身需要占用存储空间(但比空闲表小很多)。
- 如果磁盘很大,扫描整个位图找连续块可能耗时(但可用“前导零”优化或分组)。
实际应用:很多现代文件系统(如ext2/3/4、NTFS)都使用位示图来管理空闲块。例如ext4中的块位图(block bitmap)。
1.2.3 成组链接法
原理:此方法主要用于Unix系统的空闲块管理(如早期的FFS)。它结合了空闲表和空闲链表的优点,把空闲块分成若干组,每组内的块号存放在一个“组描述块”中,组间再用链接方式串起来。
具体做法(以Unix为例):
- 系统启动时,将磁盘中第一个空闲管理块读入内存(称为空闲块栈)。
- 该管理块中包含:一个计数器(记录本组内还有多少空闲块号),以及这些空闲块号(最多100个)。
- 当这些空闲块被分配完毕后,把下一个组的管理块读入内存(通过最后一项记录的指针)。
- 回收时,若当前组的空闲块栈未满,直接将回收块号压入栈;若已满,则将当前栈内容写入磁盘,再以回收块为新组的第一个块,并建立新栈。
优点:
- 既支持分配连续块(组内可以是任意块号,不一定连续,但分配时可以一次取多个块)。
- 效率高,因为内存中有一个栈,分配/回收主要操作内存,只有组切换时才读写磁盘。
- 节省磁盘空间(不需要像位示图那样单独保存大位图,而是借用空闲块本身来存储管理信息)。
生活例子:
学校图书管理员有多个“取书卡柜”。每个卡柜里放100张卡片,每张卡片上写着一本书的编号(空闲书)。取书时,从第一个卡柜里拿卡片;这个卡柜的卡片用完,就打开第二个卡柜,把里面100张卡片倒入第一个卡柜(即换组)。还书时,把书编号写回卡片,放回当前卡柜;如果当前卡柜已满,就把整个卡柜封存,换一个空卡柜(新组)来放新卡片。
| 方法 | 核心数据结构 | 连续分配支持 | 内存开销 | 磁盘I/O频率 | 实现复杂度 | 典型应用 |
|---|---|---|---|---|---|---|
| 空闲表法 | 表(起始块号,长度) | 强 | 较大(表项多) | 分配/回收时读写表 | 简单 | 早期系统,连续文件 |
| 空闲链表法 | 链表(每个空闲块存指针) | 弱 | 很小(仅头指针) | 每次分配/回收都读写块 | 简单 | 某些嵌入式系统 |
| 位示图法 | 二进制位数组 | 较强(可扫描连续位) | 固定,约磁盘容量/8K | 分配/回收时改位图(可缓存) | 中等 | ext、NTFS 等主流系统 |
| 成组链接法 | 多级组 + 内存栈 | 中等(组内块可不连续,但可一次取多块) | 小(内存栈) | 组切换时才写盘 | 复杂 | 传统 Unix、System V |
⚡ 前面搞定了”存”和”管”,但磁盘比内存慢 4~6 个数量级——这一节教你如何把慢速磁盘”伪装”成高速设备。
1.3 提高磁盘 I/O 速度的途径
磁盘的 I/O 速度远低于对内存的访问速度,通常要低上 4~6 个数量级,已成为计算机系统的瓶颈。提高磁盘 I/O 速度可从三方面着手:① 改进文件目录结构及检索方法;② 选取好的文件存储结构;③ 提高磁盘 I/O 速度本身。前两方面已在第 8 章和 9.1 节阐述,本节重点介绍第三种途径,最主要的技术就是——磁盘高速缓存。
生活类比:你去图书馆借书,每次都要走到书架上翻找,非常耗时。如果图书馆在前台备了一个”热门书目展示架”(缓存),常借的书直接在前台拿,就快多了。
1.3.1 磁盘高速缓存(Disk Cache)
定义:磁盘高速缓存是指在内存中为磁盘盘块设置的一个缓冲区,保存某些盘块的副本。它不同于 CPU 与内存之间的硬件高速缓存(Cache),它是利用内存空间来暂存磁盘数据,属于软件层面的缓存机制。
工作流程:
- 当出现磁盘访问请求时,内核先去查看所请求的盘块内容是否已在磁盘高速缓存中。
- 命中:直接从磁盘高速缓存获取,省去启动磁盘的操作,速度提高几个数量级。
- 缺失:启动磁盘将所需盘块内容读入,并送到磁盘高速缓存中,以便后续再次访问时直接命中。
设计磁盘高速缓存需要考虑三个问题:① 如何将数据传送给请求进程(数据交付方式);② 采用何种置换算法;③ 已修改的盘块数据何时写回磁盘。
1. 数据交付方式
数据交付(Data Delivery)是指将磁盘高速缓存中的数据传送给请求进程。系统有两种方式:
| 方式 | 做法 | 特点 |
|---|---|---|
| 数据交付 | 直接将磁盘高速缓存中的数据复制到请求进程的内存工作区 | 安全性好,但需额外复制开销 |
| 指针交付 | 只将指向磁盘高速缓存中某区域的指针传给请求进程 | 传送数据量少、速度快,但存在安全隐患 |
生活例子:你想借一本书。数据交付 = 管理员复印一本给你(安全,但费纸);指针交付 = 管理员告诉你书在哪排哪列,你自己去看(快,但书可能被别人拿走)。
2. 置换算法
当磁盘高速缓存已满、需要腾出空间时,须决定将哪些盘块数据换出。常用置换算法有 LRU(最近最久未使用)、Clock(时钟算法)、LFU(最少使用)等。
但磁盘高速缓存与请求调页中的联想存储器工作特性不同,在设计置换算法时还需额外考虑以下因素:
- 访问频率:对联想存储器的访问频率基本与指令执行频率相当(极高),而对磁盘高速缓存的访问频率仅与磁盘 I/O 频率相当(低得多)。
- 可预见性:磁盘高速缓存中的某些盘块数据,可预知其访问模式。例如,二次间址块、目录块被访问一次后,可能很久不再被访问;而正在写入数据的未满盘块,可能很快又会被访问。
- 数据一致性:磁盘高速缓存在内存中,内存是易失性存储器,一旦系统故障,其中已被修改但尚未写回磁盘的数据就会丢失。
基于上述考虑,有的系统将磁盘高速缓存中的所有盘块数据拉成一条 LRU 链:
- 将那些会严重影响数据一致性的盘块数据,以及很久都可能不再使用的数据,放在 LRU 链头部,使其被优先写回磁盘,尽早腾出空间。
- 将那些可能不久后要再使用的数据,挂在 LRU 链尾部,以便需要时直接从链中找到。
生活例子:书桌上放常用书,把”借来的图书馆书”(修改后须尽快还)放在最顺手的位置优先归还,自己的书可以放远一点慢慢看。
3. 周期性地写回磁盘
根据 LRU 算法,经常被访问的盘块数据可能一直保留在高速缓存中,长期不被写回磁盘(因为每次被访问就会被挂到链尾)。为解决此问题,UNIX 系统专门增设了一个 修改程序(update) 在后台运行,该程序会周期性地调用 SYNC 系统调用,强制性地将所有在磁盘高速缓存中已修改的盘块数据写回磁盘。一般将两次调用 SYNC 的时间间隔定为 30 秒——这样,即使系统发生故障,最多也只损失 30 秒的工作量。
生活例子:写论文时,Word 每隔几分钟自动保存一次——这就是”周期性写回”。即使电脑突然死机,你也只损失最近几分钟的内容。
1.3.2 提高磁盘 I/O 速度的其他方法
除了磁盘高速缓存外,教材还介绍了四种有效方法:提前读、延迟写、优化物理块的分布、虚拟盘。
1. 提前读(Read-Ahead)
原理:如果采用顺序访问方式,系统可预知下一次要读的盘块。在读取当前盘块时,同时要求将下一个盘块的数据也读入缓冲区。这样,下次需要该盘块时可直接从缓冲区获取,无需再次启动磁盘 I/O。
生活例子:你在连续翻看一本小说,图书馆员工预测你下一页要看,提前帮你翻好。
适用场景:顺序读取的大文件(视频播放、数据库全表扫描等)。”提前读”已被广泛采用。
2. 延迟写(Deferred Write)
原理:缓冲区中的数据本应立即写回磁盘,但考虑到该数据可能很快又会被本进程或其他进程访问,于是并不立即写回,而是将该缓冲区挂在空闲缓冲区队列的末尾。随着空闲缓冲区的使用,缓冲区缓缓前移,当再有进程申请到该缓冲区时,才将其数据写回磁盘并分配给新进程。
只要缓冲区仍在队列中,任何进程都可以直接从中读取数据而不必访问磁盘,进一步减少了磁盘 I/O 时间。
生活例子:快递站不是收到一个包裹就立刻送上楼,而是攒一批再一起送,省时省力。
风险:系统崩溃时,延迟写缓冲区中未写回磁盘的数据会丢失——这也是为什么需要”安全弹出”U 盘的原因。
应用:延迟写同样已被广泛采用。
3. 优化物理块的分布
原理:在链接组织方式和索引组织方式下,文件可分散存储在磁盘的任意位置。但如果过于分散,磁头移动距离就会很大。例如,将文件的第一盘块安排在最里侧磁道、第二盘块安排在最外侧磁道,读完后需要磁头从最里侧移到最外侧。
因此,应将同属一个文件的盘块安排在同一条磁道或相邻磁道上:
- 采用位示图管理空闲空间时,很容易找到相邻接的多个空闲盘块。
- 采用线性表(链)法时,可将同一条磁道上的若干盘块组成一个簇(如一簇含 4 个盘块),以簇为单位分配,保证簇内盘块的物理相邻性。
4. 虚拟盘(RAM Disk)
原理:利用内存空间去仿真磁盘,形成所谓的”虚拟盘”(又称 RAM 盘)。该盘的设备驱动程序接受所有标准的磁盘操作,但这些操作在内存中执行。对用户而言完全透明——用户不会发现这与真正的磁盘操作有何不同,只是更快而已。
虚拟盘与磁盘高速缓存的主要区别:
| 虚拟盘(RAM Disk) | 磁盘高速缓存(Disk Cache) | |
|---|---|---|
| 内容控制 | 完全由用户控制 | 由OS控制 |
| 初始状态 | 空,用户创建文件后才有内容 | OS 自动管理缓存内容 |
主要问题:虚拟盘是易失性存储器,一旦系统或电源发生故障,或系统重启,其中的数据就会丢失。因此,虚拟盘通常用于存放临时文件,如编译程序产生的目标程序等。
生活例子:虚拟盘 = 你在草稿纸上做演算,速度快但纸一扔就没了;磁盘高速缓存 = 图书管理员帮你找书,放前台的是常借书目,管理员决定放什么。
1.3.3 廉价磁盘冗余阵列(RAID)
设计思想:如果仅使用一个组件对系统性能进行改进会受到很大限制,那么通过使用多个相同的组件来获得系统性能的大幅度提升。正是在这种思想的推动下,1987 年开发出了 RAID(Redundant Array of Inexpensive Disks,廉价磁盘冗余阵列,后改称”独立磁盘冗余阵列”)。
RAID 利用一台磁盘阵列控制器统一管理和控制一组磁盘驱动器,组成一个大型磁盘系统。它不仅大幅增加了磁盘容量,而且极大地提高了磁盘 I/O 速度和整个磁盘系统的可靠性。
🎯 RAID 核心思想:用多个普通磁盘并行工作 → 获得单个昂贵磁盘无法达到的性能、容量和可靠性。
并行交叉存取
把在大、中型计算机中用于提高访问内存速度的并行交叉存取技术应用到磁盘存储系统中,以提高磁盘的 I/O 速度:
- 将每一盘块中的数据分为若干子盘块数据,分别存储到不同磁盘中的相同位置上。
- 当需要将盘块数据传送到内存时,采取并行传输方式,将各磁盘中的子盘块数据同时向内存传输,使传输时间大大减少。
- 例如:将文件的第 1 个数据子块放在磁盘 1 上,第 2 个子块放在磁盘 2 上……第 N 个子块放在磁盘 N 上。读取时从第 1~N 个磁盘中并行读出,磁盘 I/O 速度提高了 N−1 倍。
RAID 分级
RAID 刚推出时分为 6 级(RAID 0~5),后来又增加了 RAID 6 和 RAID 7。以下是各级的教材原文详解:
(1)RAID 0 级 —— 仅并行交叉存取
- 仅提供并行交叉存取功能,数据被分成条带交替写入多块磁盘。
- 优点:高效传输、高速 I/O 请求。
- 缺点:无冗余校验功能,只要阵列中有一个磁盘损坏,便会造成不可弥补的数据丢失。较少使用。
生活例子:一张门需要两把钥匙才能打开,如果其中一个钥匙丢失了,那么这张门就打不开了。
(2)RAID 1 级 —— 磁盘镜像
- 具有磁盘镜像功能。例如,阵列有 8 个盘时,可将 4 个作为数据盘,另外 4 个作为镜像盘。
- 每次访问磁盘时,利用并行读/写特性将数据分块同时写入数据盘和镜像盘。
- 优点:可靠性好,从故障中恢复简单。
- 缺点:磁盘容量利用率只有 50%。RAID 1 级的优点是以牺牲磁盘容量为代价换取的。
生活例子:你在两个本子上同时记笔记(镜像),一本丢了还有另一本,但浪费了一半纸。
(3)RAID 2 级 —— 内存方式的差错纠正组织
- 基于内存系统中的奇偶位错误检测思想:内存中每个字节关联一个奇偶位,记录字节中为 1 的个数是偶数还是奇数。如果某一位损坏,奇偶校验位就会改变,与存储的奇偶校验位不匹配,从而检测出单个位的差错。
- 实际应用较少。
(4)RAID 3 级 —— 具有并行传输功能的磁盘阵列
- 只利用一个奇偶校验盘实现数据校验。例如,阵列有 7 个盘时,6 个作为数据盘,1 个作为校验盘。
- 磁盘利用率为 6/7(约 85.7%)。
(5)RAID 4 级 —— 块交错奇偶校验
- 与 RAID 0 一样采用块级分条。
- 在一个单独的磁盘上保存其他 N 个磁盘的块的奇偶校验块。
- 如果有一个磁盘故障,可通过奇偶校验块和其他磁盘的相应块恢复故障磁盘的块。
RAID 3 与 RAID 4 的区别:RAID 3 采用位/字节级分条,RAID 4 采用块级分条。RAID 4 允许独立读操作,但校验盘成为写操作的瓶颈。
(6)RAID 5 级 —— 具有独立传送功能的磁盘阵列
- 每个驱动器都有各自独立的数据通路,独立地进行读/写。
- 无专门的校验盘——用来纠错的校验信息以螺旋(spiral)方式散布在所有数据盘上,避免了校验盘成为瓶颈。
- 容错:允许任意一块磁盘损坏,可通过剩余磁盘上的数据和校验信息重建。
- 空间利用率:(N−1)/N。
生活例子:3 人搬砖,2 人搬数据,1 人拿一个”校验签”(奇偶校验),任何一人出事,可根据其他人的信息恢复数据。关键是:校验签不是固定一个人拿,而是大家轮流拿(分布式校验)。
(7)RAID 6 级和 RAID 7 级
- RAID 6 级:设置了一个专用的、可快速访问的异步校验盘。该盘具有独立数据通路,具有比 RAID 3/5 更好的性能,但性能改进有限且代价较大。
- RAID 7 级:对 RAID 6 的改进,所有磁盘都具有较高的传输速率和优异的性能,是目前最高档次的磁盘阵列,但价格较高。
RAID 的优点
教材总结了 RAID 的三个显著优点:
- 可靠性高:除 RAID 0 级外,其余各级都采用了容错技术。当阵列中某一磁盘损坏时,并不会造成数据丢失,可根据其他未损坏磁盘中的数据来恢复已损坏磁盘中的数据。可靠性比单磁盘高出一个数量级。
- 磁盘 I/O 速度快:由于采取了并行交叉存取方式,磁盘 I/O 速度提高了 N−1 倍。
- 性价比高:RAID 的体积与具有相同容量和速度的大型磁盘系统相比,只是后者的 1/3,价格也只是后者的 1/3,且可靠性高。换言之,它仅以牺牲 1/N 的容量为代价,换取了高可靠性。
🛡 速度快了还要稳——磁盘是机械设备,总有一天会坏。这节讲容错,让你的数据”打不死”。
1.4 提高磁盘可靠性的技术
在实际应用中,经常会在多个文件中包含同一个数据。所谓数据一致性问题,是指保存在多个文件中的同一个数据,在任何情况下都必须保证相同。例如,当我们发现某种商品的进价有错时,我们必须同时修改流水账、付费账、分类账以及总账等一系列文件中关于该商品的价格,如此才能保证数据的一致性。但如果在修改途中系统突然发生故障,则会造成各个账目中该数据的不一致性,进而就会使多个账目不一致。为了保证数据的一致性,在现代 OS 中都配置了能保证数据一致性的软件。
磁盘容错技术可分成三个级别:
- 第一级容错技术(SFT-I):低级磁盘容错技术
- 第二级容错技术(SFT-II):中级磁盘容错技术
- 第三级容错技术(SFT-III):基于集群系统的容错技术,也被称为系统容错(System Fault Tolerant)技术
1.4.1 第一级容错技术(SFT-I)
第一级容错技术(SFT-I)是最基本的一种磁盘容错技术,主要用于防止因磁盘表面缺陷所造成的数据丢失。它包含双份目录、双份 FAT、热修复重定向以及写后读校验等措施。
1. 双份目录和双份 FAT
在磁盘上存放的文件目录和 FAT,是管理文件时所用的重要数据结构。为了防止这些表格被破坏,可以在不同的磁盘上或磁盘的不同区域中分别建立(双份)文件目录和 FAT:
- 一份为主文件目录及主 FAT
- 另一份为备份文件目录及备份 FAT
一旦由于磁盘表面缺陷而造成主文件目录或主 FAT 损坏,系统便会自动启用备份文件目录或备份 FAT,从而保证磁盘上的数据仍可访问。
生活例子:你去办事时随身带了身份证原件+复印件。如果原件丢了,用复印件也能证明身份。双份目录就是给文件管理的关键信息做个”复印件”。
2. 热修复重定向和写后读校验
由于磁盘价格昂贵,当磁盘表面有少量缺陷时,可在采取某种补救措施后继续使用。主要有以下两种补救措施:
(1)热修复重定向(Hot Fix Redirection):
- 系统将磁盘容量的很小一部分(如 2%~3%)划为热修复重定向区。
- 当发现磁盘有缺陷时,将待写数据写入热修复重定向区。
- 对所有写入该区的数据进行登记,以便今后快速访问。
(2)写后读校验(Read-After-Write Verification):
- 每次向磁盘中写入一个数据块后,立即将它读出来,送至另一缓冲区中。
- 将该缓冲区的内容与内存缓冲区中写后仍保留的数据进行比较。
- 若两者一致,则认为此次写入成功。
- 若两者不一致(即写入失败),则重写。
- 若重写后两者仍不一致,则认为该盘块有缺陷,此时将数据写入热修复重定向区。
生活例子:邮递员投递信件后,会打电话确认是否收到(写后读校验)。如果没收到(不一致),就再投一次。如果连续多次都没收到,就送到另一个备用地(热修复重定向区)。
1.4.2 第二级容错技术(SFT-II)
第二级容错技术(SFT-II)主要用于防止系统因磁盘驱动器和磁盘控制器故障而无法正常工作这一情况的发生。此级容错技术具体可分为磁盘镜像和磁盘双工。
1. 磁盘镜像(Disk Mirroring)
为了避免因磁盘驱动器发生故障而丢失数据,系统增设了磁盘镜像功能。为实现该功能,须在同一磁盘控制器下增设一个完全相同的磁盘驱动器。
工作原理:
- 每次向主磁盘写入数据后,都需要将数据再写到备份磁盘上,使两个磁盘上具有完全相同的位像图。
- 备份磁盘就像主磁盘的一面”镜子”。
优点:当主磁盘驱动器发生故障时,由于有备份磁盘的存在,进行切换后主机仍能正常工作。
缺点:
- 磁盘容量利用率降至原来的 50%。
- 未能使服务器的磁盘 I/O 速度得到提高。
生活例子:你在两个本子上同时记笔记——一本丢了还有另一本,但浪费了一半纸。
2. 磁盘双工(Disk Duplexing)
如果控制上述两台磁盘驱动器的磁盘控制器发生故障,或主机到磁盘控制器之间的通道发生故障,则磁盘镜像功能就起不到保护数据的作用了。
因此,在第二级容错技术中又增加了磁盘双工功能:将两台磁盘驱动器分别接到两个磁盘控制器上,同样使这两个磁盘控制器镜像成对。
磁盘双工的优点:
- 文件服务器同时将数据写到两个处于不同控制器下的磁盘上,使两者有完全相同的位像图。
- 如果某个通道或磁盘控制器发生故障,另一通道上的磁盘仍能正常工作,不会造成数据丢失。
- 由于每个磁盘都有自己独立的通道,故可**同时(并行地)**将数据写入磁盘或从磁盘中读出,提高了 I/O 速度。
生活例子(双工 vs 镜像):镜像 = 两个硬盘用同一根数据线(坏控制器全完蛋);双工 = 两个硬盘各自独立的数据线和控制器,坏一个不影响另一个。
1.4.3 基于集群系统的容错技术(SFT-III)
在进入 20 世纪 90 年代后,为了进一步增强服务器的可用性,采用了多台对称多处理机服务器来实现集群系统服务器的功能。所谓集群,是指由一组互连的自主计算机组成统一的计算机系统,给人们的感觉是它们是一台机器。利用集群系统不仅可提高系统的并行处理能力,还可提高系统的可用性。
当前使用最广泛的集群容错功能主要工作模式有三种:双机热备份模式、双机互为备份模式、公用磁盘模式。
1. 双机热备份模式
在双机热备份模式的系统中,备有两台服务器,两者的处理能力通常完全相同:
- 一台作为主服务器,另一台作为备份服务器。
- 平时主服务器运行,备份服务器则时刻监视着主服务器的运行情况。
- 一旦主服务器出现故障,备份服务器便立即接替主服务器的工作而成为系统中新的主服务器。
- 修复后的原来的主服务器会被作为备份服务器。
为使两台服务器之间保持镜像关系,需在各服务器上各装入一块网卡,并通过一条镜像服务器链路(Mirrored Server Link,MSL) 将两台服务器连接起来。若配置 FDDI 单模光纤,两台服务器间的距离可达 20 km。
此外,还须在系统中设置某种机制以检测主服务器中数据的改变——一旦检测到主服务器中有数据变化,便立即通过通信系统将修改后的数据传送到备份服务器的相应数据文件中。
切换过程:一旦主服务器发生故障,系统能自动将主要业务的用户切换到备份服务器上。为保证切换时间足够快(通常为数分钟),要求在系统中配置用于切换硬件的开关设备,在备份服务器上事先建立好通信配置。
优点:提高了系统的可用性,易于实现,主/备份服务器完全独立,可支持远程热备份,能消除由于火灾、爆炸等非计算机因素所造成的隐患。
缺点:备份服务器处于被动等待状态,整个系统的使用效率只有 50%。
生活例子:飞机的正副驾驶员——正驾驶开飞机,副驾驶始终监控。正驾驶出状况,副驾驶立刻接手。这就是”热备份”。
2. 双机互为备份模式
在双机互为备份模式中,两台服务器在平时均为在线服务器(如一台作为数据库服务器,另一台作为电子邮件服务器),它们各自完成自己的任务,同时互为备份。
实现方式:
- 通过某种专线将两台服务器连接起来(远距离可用 FDDI 单模光纤,并最好再通过路由器作为备份通信线路)。
- 最好在每台服务器内都配置两块硬盘:一块用于装载系统/应用程序,另一块用于接收由另一台服务器发来的备份数据(即作为另一台服务器的镜像盘)。正常运行时镜像盘对本地用户锁死。
- 如果仅有一块硬盘,可通过建立虚拟盘或分区方式分别存放系统程序和备份数据。
故障切换:当通过专线链接检查到某台服务器发生故障后,再通过路由器去验证。如果故障被证实,则由正常服务器向故障服务器的客户机发出广播信息,表明要进行切换。切换成功后,客户机无须重新登录便可继续使用网络提供的服务。当故障服务器修复并重新联网后,已被迁移的服务功能将返回到修复后的服务器上。
优点:两台服务器都可用于处理任务,系统效率较高。现已从两台增加到 4 台、8 台、16 台甚至更多,所有服务器都可用于处理任务,当其中一台发生故障时,系统可指定另一台来接替。
生活例子:两位医生各看各的病人,但都知道对方的病例。一位医生请假了,另一位可以临时顶上帮他看病人。两位都在工作——不像热备份那样一个人闲着。
3. 公用磁盘模式
为了减少信息复制的开销,可以将多台计算机连接到一个公用磁盘上:
- 该公用磁盘被划分为若干个卷,每台计算机使用一个卷。
- 如果某台计算机发生故障,系统将重新配置,根据某种调度策略选择另一台机器进行替代。
- 替代者对故障机器的卷拥有所有权,从而接替故障计算机来承担其任务。
优点:消除了信息的复制时间,从而减少了网络和服务器的开销。
1.4.4 后备系统
在一个完整的系统中必须配置后备系统,原因有二:
- 磁盘系统不够大,不可能将系统在运行过程中产生的所有数据都装在磁盘中,应把暂时不需要但仍然有用的数据存放在后备系统中并保存起来。
- 为防止系统发生故障或被计算机病毒感染,进而将系统中的数据弄错或丢失,同时也可以将比较重要的数据存放在后备系统中。
目前常用作后备系统的设备(后备设备)有磁带机、硬盘和光盘驱动器等。
1. 磁带机
磁带机是最早作为计算机系统外部存储器的设备,但由于它只适合存储顺序文件,故现在主要把它作为后备设备。
- 优点:容量大(一般可达数 GB 至数十 GB),价格便宜。在许多大、中型系统中都配置了磁带机。
- 缺点:只能顺序存取且速度比较慢(一般为数百 KB/s 到数 MB/s),因此将一个大容量磁盘上的数据复制到磁带机上需要花费很多时间。
2. 硬盘
(1)移动磁盘:
- 小型系统和个人计算机常将移动磁盘作为后备系统。
- 优点:速度快,脱机保存方便,且保存时间较长,可比磁带机长出 3~5 年。
- 缺点:单位容量的费用较高。
- 近年来移动磁盘的价格已明显下降,且体积也非常小,应用日益广泛。
(2)固定硬盘驱动器:
- 在大、中型系统中可使用大容量硬盘兼作后备系统,需在一个系统中配置两个大容量硬盘。
- 每个硬盘都被划分为两个分区:一个为数据区,另一个为备份区,如图 9-16 所示。
- 可在每天晚上将硬盘 0 中的”数据 0”复制到硬盘 1 中的备份区中保存;同样也将硬盘 1 中的”数据 1”复制到硬盘 0 中的备份区中保存。
- 优点:不仅复制速度非常快,而且还具有容错功能——当其中任何一个硬盘驱动器发生故障时,都不会引起系统瘫痪。
1 | |
3. 光盘驱动器
光盘驱动器是现在最流行的多媒体设备,可分为两类:
(1)只读光盘驱动器:
- 如 CD-ROM 和 DVD-ROM。
- 只能播放(读)而不能刻录(写),故难以用作后备设备。
(2)可读写光盘驱动器(刻录机):
- 既能播放(读)又能刻录(写),可用作后备设备。
- 三类刻录机:
- CD-RW 刻录机:能播放和刻录 CD、VCD 等。
- COMBO 刻录机:能播放 DVD,但只能刻录 CD、VCD 等。
- DVD 刻录机:能播放和刻录 CD、VCD 和 DVD 等。
🚀 跳出单机思维——数据存在网络另一端行不行?SSD 为什么比 HDD 快?这节带你看看存储的未来。
1.5 存储新技术
🔍 DAS vs NAS vs SAN — 快速对比
DAS NAS SAN 连接方式 直连服务器 以太网 光纤通道 访问级别 块级 文件级 块级 共享能力 ❌ 信息孤岛 ✅ 多客户端共享 ✅ 多服务器共享 性能 中 中 高 成本 低 中 高
纵观数据存储技术的发展,从 20 世纪 50 年代发明硬盘、使用直连式存储开始,到 20 世纪 70—80 年代发明网络附加存储、存储区域网络,再到 2006 年发明对象存储,数据存储领域正发生着剧烈变化,而且这种变化具有长期发展下去的趋势。
1.5.1 传统存储系统
传统存储系统的三种主要架构分别是直连式存储(DAS)、网络附加存储(NAS)和存储区域网络(SAN)。
1. 直连式存储(DAS,Direct-Attached Storage)
直连式存储是一种通过总线适配器直接将硬盘等存储介质连接到主机上的存储方式,也称为主机连接存储。在存储设备和主机之间通常没有任何网络设备的参与。
DAS 是最原始、最基本的存储架构,在个人计算机、服务器上最为常见。
连接技术:
- 典型台式计算机采用 I/O 总线架构,如 IDE(ATA)、SATA、SCSI 等。
- 高端工作站和服务器通常采用更复杂的 I/O 总线架构,如光纤通道(FC)等。
DAS 设备:硬盘驱动器、RAID、CD、DVD、磁带驱动器、磁盘簇(JBOD)等。
优点:架构简单、成本低廉、读写效率高。
缺点:容量有限、难以共享,因此容易形成”信息孤岛”(Islands of Information)。
生活例子:普通台式机/笔记本电脑里的内置硬盘,就是典型 DAS——这台电脑的硬盘只能这台电脑用,别人没法直接访问。
2. 网络附加存储(NAS,Network-Attached Storage)
网络附加存储是一种提供文件级别访问接口的网络存储系统架构,通常采用 NFS、SMB/CIFS 等网络文件共享协议进行文件存取。
特点:
- 可以直接连接在计算机网络(如以太网等)上,对不同类型 OS 的使用者提供集中式资料存取服务。
- 支持多客户端同时访问,为服务器提供大容量的集中式存储,方便服务器间的数据共享。
- 使用者可以通过某种方式(如 Linux 系统中的
mount命令)将存储服务挂载到本地进行访问,在本地呈现的就是一个文件目录树。
优点:管理方便,成本较低,多客户端共享。
缺点:存储数据通过普通数据网络进行传输,会消耗数据网络的带宽,加重网络通信的延迟,这对大型客户机-服务器环境可能影响较大。
生活例子:家庭 NAS(如群晖)——连接到家里路由器,电视、手机、电脑都能访问里面的电影和照片。
3. 存储区域网络(SAN,Storage Area Network)
存储区域网络是一种通过光纤交换机等高速网络设备在服务器和磁盘阵列等存储设备间搭设专门的存储网络,从而提供高性能存储系统的架构。
特点:
- SAN 的优势在于灵活性:多个主机和多个存储阵列可以连接到同一个 SAN 上,存储任务可以被动态地分配到各个主机上。
- SAN 与 NAS 的区别:SAN 提供块级别的访问接口,一般不会同时提供一个文件系统级别的访问接口。通常情况下,服务器需要通过 SCSI 等 I/O 总线架构将 SAN 映射到本地磁盘,然后在其上创建文件系统后进行使用。
典型容量:目前主流的企业级 NAS 或 SAN 存储产品一般都可以提供 TB 级的存储容量,高端的存储产品甚至可以提供高达几个 PB(1 PB = 1024 TB)的存储容量。
| 特性 | DAS | NAS | SAN |
|---|---|---|---|
| 连接方式 | 总线直连 | 以太网 | 专用存储网络(FC/iSCSI) |
| 访问单位 | 数据块 | 文件 | 数据块 |
| 共享性 | 无(单机独享) | 多客户端共享 | 多主机共享块设备 |
| 性能 | 高 | 中(受网络带宽影响) | 极高 |
| 成本 | 低 | 低~中 | 高 |
| 缺点 | 信息孤岛 | 加重网络延迟 | 造价昂贵、管理复杂 |
| 典型场景 | 个人 PC | 文件共享/备份 | 数据库/虚拟化 |
1.5.2 新型存储系统
大数据时代的到来,使得数据量呈现出指数级的增长趋势。此时,传统的集中式存储(如 NAS、SAN 等)在容量和性能等各方面都无法较好地满足大数据对存储的需求。在此背景下,具有优秀的可扩展能力的分布式存储系统成了存储大数据的主流存储系统。
1. 分布式存储系统
分布式存储系统多采用普通的硬件设备作为基础设施,因此单位容量的存储成本得以大大降低。另外,分布式存储系统在性能、维护性和容灾性等方面,相比传统存储系统也具有不同程度的优势。
需要解决的关键技术问题:可扩展性、数据冗余、数据一致性、全局命名空间缓存等。
两种架构:
(1)C/S(Client/Server)架构:
- 传统客户端-服务器模式:中心元数据服务器管理所有文件的元数据信息,存储节点负责实际数据的存储和读取。
- 代表:HDFS(Hadoop 分布式文件系统)、GFS(Google File System)。
(2)P2P(Peer-to-Peer)架构:
- 无中心节点,所有节点平等,通过分布式哈希表(DHT)等技术实现数据定位。
- 代表:GlusterFS、Ceph(CRUSH 算法)。
分布式存储系统面临的一个共性问题是,如何组织和管理成员节点,以及如何建立数据与节点之间的映射关系。成员节点的动态增加或删除,在分布式存储系统中基本上可以算是一种常态。
生活例子:百度网盘的底层——你上传的 1GB 文件可能被分成很多小块,分散存在数百台服务器上,读取时从多台服务器并行汇聚,速度极快。即使某台服务器宕机也不影响。
2. 云存储系统
云存储系统是由第三方运营商提供的在线存储系统,例如面向个人用户的在线网盘,面向企业的文件、块或对象存储系统等。
特点:
- 运营商负责数据中心的部署、运营和维护等工作,将数据存储包装成服务的形式提供给用户。
- 作为云计算的延伸和重要组件之一,为云计算的实现提供了”按需分配、按量计费“的数据存储服务。
- 用户不需要搭建自己的数据中心和基础架构,也不需要关心底层存储系统的管理与维护,同时还可以根据业务需求动态地扩大或减少对存储容量的需求。
1.5.3 硬盘新技术
硬盘是计算机中非常重要的存储器之一。近几年来在个人计算机上,除了使用传统的机械硬盘(HDD)外,还会使用固态硬盘(SSD),且固态硬盘的风头正盛,大有赶超机械硬盘之势。这是因为固态硬盘和机械硬盘相比,在速度、功耗、噪声等方面均有优势。不过在存储容量、写入耐久度和价格等方面,机械硬盘仍然有着不可比拟的优势。
1. 机械硬盘(HDD)技术革新
从 1956 年发明第一个机械硬盘开始,存储技术的发展走过了很长的一段路。机械硬盘从 5 MB 发展到现在的 20 TB,容量大幅增加,读/写速度也逐步提升。在固态硬盘大量使用的情况下,机械硬盘也在加快技术革新的步伐。以希捷公司为代表的技术路线如下:
(1)传统磁记录(CMR,Conventional Magnetic Recording)→ 叠瓦式磁记录(SMR,Shingled Magnetic Recording):
- CMR:传统方式,磁道之间有空隙,写入不干扰相邻磁道。
- SMR:磁道像屋瓦一样互相叠加,只露出最上层的写入区域。存储密度更高、容量更大。但随机写性能差——改写一个磁道中的数据会影响到相邻的”瓦片”。
- 适用场景:适合顺序写入、较少改写的场景(如归档存储、冷数据存储)。
(2)热辅助磁记录(HAMR,Heat-Assisted Magnetic Recording):
- 用激光瞬时加热磁性介质至高温(约 400°C),使其暂时失去磁性稳定性,在冷却过程中用磁头写入数据。
- 极大限度地扩大了机械硬盘的容量,是 HDD 未来高容量化的重要方向。
(3)双磁头驱动臂技术:
- 在一个硬盘中使用两个独立的磁头驱动臂,可同时读写不同的盘片区域。
- 大大提升了机械硬盘的读/写速度,接近将 I/O 性能翻倍。
2. 固态硬盘(SSD)
固态硬盘是用固态电子存储芯片阵列所制成的硬盘。固态硬盘在接口的规范与定义、功能以及使用方法上与普通硬盘完全相同,在产品的外形和尺寸上也基本与普通硬盘一致。但是,新兴的 U.2、M.2 等接口形式的固态硬盘,其尺寸与外形与 SATA 架构的机械硬盘完全不同。
固态硬盘被广泛应用于军事、医疗、航空、交通(导航设备)、通信(网络监控)等领域。
根据存储介质的不同,可将固态硬盘分为三类:
(1)基于闪存(Flash)的固态硬盘:
- 将 Flash 芯片作为存储介质,是固态硬盘的主要类别(即通常所说的 SSD)。
- 外观可以被制作成多种样式:笔记本硬盘、微硬盘、存储卡、优盘等。
- 优点:可移动,数据保护不受电源控制,能适应各种环境,适合个人用户使用。
- 可靠性:高品质的家用固态硬盘的故障率可轻松保持在普通家用机械硬盘故障率的十分之一甚至更低。
- 缺点:使用寿命根据不同的闪存介质而有所不同(写入次数有限)。
(2)基于 DRAM 的固态硬盘:
- 将 DRAM 作为存储介质,应用范围较窄。
- 效仿了机械硬盘的设计,可被绝大部分 OS 的文件系统工具进行卷设置和卷管理,能提供 PCI 标准接口和 FC 标准接口。
- 优点:高性能存储器,理论上可以无限写入。
- 缺点:需要独立电源来保护数据安全(DRAM 断电即丢失数据),属于非主流存储设备。
(3)基于 XPoint 类的固态硬盘:
- 采用了英特尔公司提出的 XPoint 颗粒技术(如 Optane,已停产)。
- 原理上接近基于 DRAM 的固态硬盘,但属于非易失性存储器。
- 优点:读取时延极低,可轻松达到现有固态硬盘的百分之一,接近无限的存储寿命。
- 缺点:密度相对于基于闪存的固态硬盘较低,成本极高,多用于发烧级台式计算机和数据中心。
🔐 最后一关:一致性——你的文件写到一半断电了怎么办?事务、检查点、并发控制帮你兜底。
1.6 数据一致性控制
🔄 数据恢复核心流程:事务记录 → 提交/回滚 → 检查点 → 崩溃恢复
在实际应用中,经常会在多个文件中包含同一个数据。所谓数据一致性问题,是指保存在多个文件中的同一个数据,在任何情况下都必须保证相同。例如,当我们发现某种商品的进价有错时,我们必须同时修改流水账、付费账、分类账以及总账等一系列文件中关于该商品的价格,如此才能保证数据的一致性。但如果在修改途中系统突然发生故障,则会造成各个账目中该数据的不一致性,进而就会使多个账目不一致。为了保证数据的一致性,在现代 OS 中都配置了能保证数据一致性的软件。
1.6.1 事务(Transaction)
1. 事务的定义
事务是用于访问和修改各种数据项的一个程序单位。事务也可被看作一系列读/写操作。被访问的数据可以分散地存放在同一文件的不同记录中,也可以存放在多个文件中。
- 只有对分布在不同位置的同一数据进行的读/写操作(含修改)全部完成时,才能通过托付操作(Commit Operation) 来终止事务。
- 只要有一个读/写操作失败,便须执行夭折操作(Abort Operation)。
- 读/写操作的失败可能是由逻辑错误或系统故障导致的。
一个被”夭折”的事务,通常已执行了一些操作,因而可能已对某些数据做了修改。为了使”夭折”的事务不会引起数据的不一致性,须将该事务内刚被修改的数据项恢复成原来的情况,以使系统中各数据项与该事务未执行时系统中各数据项的内容完全相同。此时,可以说该事务”已被退回(Rolled Back)“。
📌 关键特性(原子性):一个事务在对一批数据执行修改操作时,要么全部完成并用修改后的数据代替原来的数据,要么一个也不修改。这就是本书第 1 章中曾讲过的”原子性”。
生活例子(银行转账):
从 A 账户转 100 元到 B 账户,包含两个操作:① A 减 100;② B 加 100。
如果操作 ① 成功但 ② 因系统崩溃失败,100 元就”凭空消失”了。
事务的原子性保证:要么两步都完成,要么 A 账户扣款操作也被撤销,100 元原封不动。
2. 事务记录
为了实现上述”原子性”修改,通常须借助于称为”事务记录(Transaction Record)“的数据结构。
这些数据结构被放在一个非常可靠的存储器(又称稳定存储器)中,用于记录在事务运行过程中与数据项修改相关的全部信息。这些信息又被称为”运行记录(Log)“。
该记录中包含下列字段:
- 事务名:用于标志该事务的唯一名字。
- 数据项名:它是被修改数据项的唯一名字。
- 旧值:修改前数据项的值。
- 新值:修改后数据项将具有的值。
在事务记录表中的每一项记录,都描述了在事务运行过程中的重要事务操作,如修改操作、开始操作、托付操作、夭折操作等。
- 在一个事务 Ti 开始执行时,
〈Ti 开始〉记录被写入事务记录表中。 - 在 Ti 执行期间,在 Ti 的任何写(修改)操作之前,均须先在事务记录表中写一项适当的新记录。
- 当 Ti 进行托付时,要把一个
〈Ti 托付〉记录写入事务记录表中。
3. 恢复算法
由于一组被事务 Ti 修改的数据以及它们被修改前后的值,都能在事务记录表中找到,因此,系统利用事务记录表可以处理任何故障而不会使故障造成非易失性存储器中信息的丢失。
恢复算法可通过以下两个过程实现:
| 过程 | 作用 |
|---|---|
| undo〈Ti〉 | 把所有被事务 Ti 修改过的数据恢复为修改前的值 |
| redo〈Ti〉 | 把所有被事务 Ti 修改过的数据设置为新值 |
故障后的处理:
- 如果系统发生故障,系统应对以前所发生的事务进行清理。
- 通过查找事务记录表,可以把尚未清理的事务分成两类:
- 第一类:所包含的各类操作都已完成的事务(在事务记录表中**既包含
〈Ti 开始〉记录,又包含〈Ti 托付〉记录)。此时系统会利用 redo〈Ti〉 过程把所有已被修改的数据设置成新值。 - 第二类:所包含的各个操作并未全部完成的事务(在事务记录表中只有
〈Ti 开始〉记录而无〈Ti 托付〉记录)。此时系统会利用 undo〈Ti〉 过程将所有已被修改的数据恢复为修改前的值。
- 第一类:所包含的各类操作都已完成的事务(在事务记录表中**既包含
生活例子(undo/redo):
你正在抄写一份重要文件,一边抄一边记”抄写日志”(事务记录)。如果突然停电:
- 如果整份文件已经抄完并记录”已托付”—— redo:确保最终版本已保存。
- 如果抄到一半停电—— undo:把已抄的部分全部擦掉,恢复原文件,等下次重新抄。
1.6.2 检查点(Checkpoint)
1. 检查点的作用
如前所述,当系统发生故障时,必须去检查整个事务记录表,以确定哪些事务需要利用 redo〈Ti〉过程去设置新值,而哪些事务又需要利用 undo〈Ti〉过程去恢复旧值。
由于在系统中可能存在许多并发执行的事务,因而在事务记录表中会有许多事务执行操作的记录。随着时间的推移,记录的数据会越来越多。因此,一旦系统发生故障,事务记录表中的记录清理起来就会非常费时。
引入检查点(Check Point)的主要目的是,使事务记录表中事务记录的清理工作经常化。
检查点执行的工作(每隔一定时间执行一次):
- 将驻留在易失性存储器(内存)中的当前事务记录表中的所有记录输出到稳定存储器中。
- 将驻留在易失性存储器中的所有已修改数据输出到稳定存储器中。
- 将事务记录表中的
〈检查点〉记录输出到稳定存储器中。 - 每当出现一个
〈检查点〉记录,系统便执行一次恢复操作(利用 redo〈Ti〉和 undo〈Ti〉过程实现数据恢复)。
📌 检查点的重要效果:
如果一个事务 Ti 在检查点前就做了托付,则在事务记录表中便会出现一个在检查点记录前的〈Ti 托付〉记录。在这种情况下,所有被 Ti 修改过的数据,都会在检查点前写入稳定存储器(或者是作为检查点记录自身的一部分写入稳定存储器)。因此,以后在系统出现故障时,就不必再执行 redo〈Ti〉过程了。
2. 新的恢复算法
在引入检查点后,大大减少了恢复处理的开销。因为在发生故障后,并不需要对事务记录表中的所有事务记录都进行处理,而只需要对最后一个检查点之后的事务记录进行处理。
具体恢复步骤:
- 恢复例程首先会查找事务记录表,确定最近检查点以前开始执行的最后事务 Ti。
- 在找到这样的事务后,返回去搜索事务记录表,此时便可找到第一个检查点记录。
- 恢复例程从该检查点开始,返回搜索各个事务的记录,并利用 redo〈Ti〉和 undo〈Ti〉过程对它们进行处理。
恢复规则(设将所有在事务 Ti 以后开始执行的事务表示为事务集 T):
- 对所有在 T 中的事务 Tk,如果在事务记录表中出现了
〈Tk 托付〉记录,则执行 redo〈Tk〉 过程。 - 如果在事务记录表中并未出现
〈Tk 托付〉记录,则执行 undo〈Tk〉 过程。
生活例子:
你打游戏不停存档(检查点),如果闯关失败(系统崩溃),不需要从游戏开头重来,只需要从上一个存档点开始重玩即可。检查点之前的已保存进度不需要再做一遍。
1.6.3 并发控制(Concurrent Control)
在多用户系统和计算机网络环境下,可能有多个用户在同时执行事务。由于事务具有原子性,这使各个事务必然会按某种次序依次执行(即各事务对数据项的修改是互斥的)。我们把这种特性称为顺序性,而把用于实现事务顺序性的技术称为并发控制。
并发控制技术在数据库系统中已被广泛应用,现也广泛应用于 OS 中。
虽然可以利用第 4 章所介绍的信号量机制来保证事务顺序性,但在数据库系统和文件服务器中,应用最多的还是较简单、较灵活的同步机制——锁。
1. 利用互斥锁实现顺序性
实现顺序性最简单的方法是,设置一种用于实现互斥的锁,简称互斥锁(Exclusive Lock)。
工作方式:
- 在利用互斥锁实现顺序性时,应为每个共享对象设置一把互斥锁。
- 当某一事务 Ti 要去访问某个对象时,应先获得该对象的互斥锁。
- 若成功,则用该锁将该对象锁住,此时事务 Ti 便可对该对象执行读/写操作。
- 其他事务由于未获得该锁,故不能访问该对象。
若事务 Ti 需要对一批对象进行访问:
- 为了保证事务操作的原子性,Ti 应先获得这一批对象的互斥锁,以将这一批对象全部锁住。
- 若成功,则可对这一批对象执行读/写操作;操作完成后再将所有这些锁释放。
- 但如果这一批对象中的某个对象已被其他事务锁住,则此时事务 Ti 应对此前已被 Ti 锁住的其他对象进行开锁,宣布此次事务运行失败,但这不会引起数据变化。
缺点:互斥锁方法虽然简单易行,但效率不高——因为一个共享文件虽然只允许一个事务去写,但却允许多个事务同时去读;而互斥锁锁住文件后,只允许一个事务去读。
2. 利用互斥锁和共享锁实现顺序性
为了提高运行效率,又引入了另一种形式的锁——共享锁(Shared Lock)。
共享锁与互斥锁的区别:
| 锁类型 | 读操作 | 写操作 | 并发性 |
|---|---|---|---|
| 互斥锁 | 仅一个事务可读 | 仅一个事务可写 | 低 |
| 共享锁 | 多个事务可同时读 | 不允许任何事务写 | 高(读多写少场景) |
工作流程:
- 如果事务 Ti 要对对象 Q 执行读操作,则只须获得对象 Q 的共享锁。
- 如果对象 Q 已被互斥锁锁住 → Ti 必须等待。
- 否则 → 即可获得共享锁而对 Q 执行读操作。
- 如果 Ti 要对 Q 执行写操作,则 Ti 还须获得 Q 的互斥锁。
- 若失败 → 须等待。
- 否则 → 即可获得互斥锁而对 Q 执行写操作。
📌 利用共享锁和互斥锁实现顺序性的方法,非常类似于本书第 4 章中所介绍的读者-写者问题的解法。
1.6.4 重复数据的一致性问题
为了保证数据的安全性,最常见的做法是把关键文件或数据结构复制多份,分别存储在不同的地方,当主文件(数据结构)失效时,还有备份文件(数据结构)可以使用,因此不会造成数据丢失,也不会影响系统工作。
显然,主文件(数据结构)中的数据应与各备份文件中的对应数据相一致。此外,有些数据结构(如空闲盘块表等)在系统运行过程中总是会被不断地修改,因此,同样应保证不同处的同一数据结构中(可能已被修改的)数据的一致性。
1. 重复文件的一致性
这里以 UNIX 类型的文件系统为例,来说明如何保证重复文件的一致性。
UNIX 类型目录结构:
- 每个目录项中均含有一个 ASCII 的文件名和一个索引节点编号,后者指向一个索引节点。
- 当有重复文件时,一个目录项可由一个文件名和若干个索引节点编号组成,每个索引节点编号都会指向各自的索引节点。

保证重复文件一致性的两种方法:
方法一(修改时同步更新):
- 当一个文件被修改后,可查找文件目录以得到其他几个文件复制的索引节点编号。
- 再利用这些索引节点编号找到各文件复制的物理位置。
- 然后对这些文件复制做同样的修改。
方法二(替换法):
- 为新修改的文件建立几个文件复制,并用新文件复制去取代原来的文件复制。
2. 链接数一致性检查
在 UNIX 类型的目录中,每个目录项内都含有一个索引节点编号,用于指向该文件的索引节点。
链接计数的工作原理:
- 对于一个共享文件,其索引节点编号会在目录中出现多次。
- 例如,当有 5 个用户(进程)共享某文件时,该文件的索引节点编号会在目录中出现 5 次。
- 在该共享文件的索引节点中还有一个链接计数值 count,用于指出共享本文件的用户(进程)数。
正常情况下:索引节点中的链接计数值 count 与目录中该索引节点编号出现的次数应该一致。否则就会出现数据不一致性差错。
检查一致性差错的步骤:
- 需要配置一张计数器表,并且应为每个文件建立一个表项,其中含有各文件索引节点编号的计数值。
- 在进行检查时,从根目录开始查找,每当在目录中遇到该索引节点编号时,便在该计数器表中相应文件的表项上加 1。
- 当把所有目录都检查完后,便可将该计数器表中每个表项中的索引节点编号计数值与该文件索引节点中的链接计数值 count 进行比较:
- 如果两者一致 → 数据正确 ✓
- 否则 → 发生了数据不一致性差错 ✗
两种不一致错误及其修复:
| 错误类型 | 现象 | 后果 | 修复方法 |
|---|---|---|---|
| count > 计数器值 | 索引节点中的链接计数值大于实际引用次数 | 即使所有用户都不再使用此文件,其 count 仍不为 0,该文件不会被删除,浪费存储空间(性质不严重) | 用计数器表中正确的计数值去为 count 重新赋值 |
| count < 计数器值 | 索引节点中的链接计数值小于实际引用次数 | 一旦其中一个用户不再需要此文件,count 就会减为 0,系统将此文件删除并释放其索引节点及文件所占用的盘块,导致另一个需要共享此文件的用户无法访问 | 将 count 置为正确值 |
生活例子(链接数一致性):
一间会议室有几把钥匙(count),分给不同的人(目录项中的索引节点引用)。如果钥匙数 > 实际持有人的数量——多出来的钥匙对应的”虚拟持有人”不存在,会议室永远不会被释放(浪费空间)。如果钥匙数 < 实际持有人——有一个人退还钥匙时,系统以为所有人都还了,就把会议室收走了,剩下的人就没会议室用了。
1.7 总结
磁盘驱动器是大多数计算机系统的主要外存 I/O 设备,大多数外存设备均为磁盘或磁带。现代磁盘驱动结构是一个大的一维的逻辑盘块数组,一般来说,这些逻辑盘块的大小为 512 B。磁盘连接到计算机系统的方式有两种:① 通过主机的本地 I/O 接口连接;② 通过网络连接。
磁盘存储器管理的任务主要有三方面:
任务一:有效利用存储空间
- 采用合适的文件组织方式为文件分配存储空间,以改善存储空间的利用率。
- 文件组织方式与外存组织方式密切相关,常用的外存组织方式包括:连续组织方式、链接组织方式和索引组织方式。
- 在现代 OS 中,由于存在多种类型的文件,因此对文件可能会采取多种类型的组织方式。
- 存储空间的管理方法有:空闲区表法、空闲链表法、位示图法、成组链接法等。
任务二:提高磁盘的 I/O 速度
- 通过采用磁盘高速缓存、提前读、延迟写、优化物理块分布、RAID 等途径来显著提高磁盘的 I/O 速度。
- 其中 RAID 技术利用并行交叉存取原理,将多块磁盘组合成磁盘阵列,不仅提高了 I/O 速度,还大幅提升了可靠性。
任务三:提高磁盘的可靠性
- 通过采用各种容错技术(SFT-I、SFT-II、SFT-III/集群系统)和后备系统(磁带机、硬盘、光盘驱动器)来提高磁盘的可靠性。
- 容错技术可防止因系统因素造成的数据不安全,后备系统可防止因自然因素造成的数据丢失。
存储技术的发展趋势
- 磁盘发展至今,已形成多种存储技术且在不断革新中。
- 固态硬盘(SSD)在存储领域的地位也在日渐提升。
- 除了传统的 DAS、NAS、SAN 存储系统外,正在发展的新型存储系统有分布式存储系统、云存储系统等。
本章知识框架梳理
1 | |
核心考点速记
| 考点 | 关键词 / 要点 |
|---|---|
| 连续分配特点 | 顺序访问快、支持直接访问;外部碎片;须事先声明文件最大长度 |
| FAT 文件系统 | 显式链接;内存中存放全局 FAT;引入”簇”减小 FAT 大小 |
| UNIX 混合索引 | 10 个直接地址 + 1 个一次间接 + 1 个二次间接 + 1 个三次间接 |
| 位示图法 | 每 bit 对应一个盘块;适合在内存中操作;ext4/NTFS 使用 |
| 成组链接法 | UNIX 传统方法;内存中存放当前组的 100 个盘块号;组切换才写盘 |
| 磁盘高速缓存 | 数据交付 vs 指针交付;LRU 链;周期性写回(UNIX update/SYNC) |
| 提前读 / 延迟写 | 顺序访问场景有效;延迟写存在系统崩溃时数据丢失风险 |
| 虚拟盘 vs 磁盘高速缓存 | 虚拟盘内容由用户控制;磁盘高速缓存由 OS 控制 |
| RAID 分级 | 0(无冗余)、1(镜像,50%)、3(位级分条)、4(块级分条)、5(分布式校验) |
| SFT-I | 双份目录/FAT;热修复重定向;写后读校验 |
| SFT-II | 磁盘镜像(同一控制器);磁盘双工(独立控制器,可并行 I/O) |
| 集群容错三种模式 | 双机热备(效率50%);双机互为备份(效率高);公用磁盘(无复制开销) |
| 后备系统设备 | 磁带机(顺序、慢);移动硬盘(快、保存时间长);光盘刻录机 |
| 传统存储系统 | DAS(信息孤岛);NAS(文件级、以太网);SAN(块级、专用网) |
| 新型存储系统 | 分布式存储(C/S或P2P架构);云存储(按需分配、按量计费) |
| HDD 新技术 | CMR→SMR(叠瓦式,密度高)→HAMR(热辅助,容量更大);双磁头驱动臂 |
| SSD 分类 | 基于闪存(主流);基于 DRAM(需电源保护);基于 XPoint(低延迟、高寿命) |
| 事务 | 原子性;事务记录表(事务名/数据项名/旧值/新值);undo/redo 恢复 |
| 检查点 | 周期性将事务记录和脏页写稳定存储器;恢复时只需处理最后一个检查点之后的记录 |
| 并发控制 | 互斥锁(效率低);互斥锁+共享锁(类似读者-写者问题) |
| 重复文件一致性 | 方法一:查找目录同步修改;方法二:建立新副本并替换 |
| 链接数一致性 | 从根目录开始统计引用次数;与索引节点中的 count 值比较 |


