当一个数据被分别存储到多个文件中时,便会出现数据一致性问题。大多数OS中都已具有能够确保数据一致性的机制,用于保证文件系统中的数据一致性。这同样需硬件的支持,其中最重要的是要有一个称为稳定存储器(Stable Storage)的存储器系统。
事务
事务的定义
事务是用于访问和修改各种数据项的一个程序单位;被访问的数据可以分散在多个文件中,事务也可以被看作是一系列的读和写操作。当这些操作全部完成时,再以托付操作 (commit operation)来终止事务。只要有一个读或写操作失败,则执行夭折操作(abort operation)。一个事务在对一批数据进行操作时,要么全部完成,并用修改后的数据去代替原来的数据,要么一个也不修改。这特性称“原子性”。
事务记录(Transaction Record)
为了实现上述的原子修改,通常需借助于称为事务记录的数据结构来实现。又称运行记录,该记录包括以下各字段:
事务名----用于标识事务的唯一名字;
数据项名----是被修改数据项的唯一名字;
旧值----修改前数据项的值;
新值----修改后数据项将具有的值。
恢复算法
利用事务记录表,系统能处理任何故障而不使故障造成非易失性存储器中信息的丢失。 恢复算法利用以下两个过程:
undo(Ti)----该过程能把所有被事务Ti修改过的数据,恢复为修改前的值;
redo(Ti)----该过程能把所有被事务Ti修改过的数据,设置为新值。
检查点
检查点(Check Points)的作用
引入检查点的主要目的是使对事务记录表中事务记录的清理工作经常化。
新的恢复算法
如果把所有的事务Ti以后开始执行的事务表示为事务集T,则新的恢复操作要求:
⑴ 所有在T中的事务Tk,如果在事务记录表中出现了 <Tk托付>记录,则执行redo(Tk)操作。
⑵ 所有在T中的事务Tk,如果在事务记录表中未出现 <Tk托付>记录,则执行undo(Tk)操作。
并发控制
在多用户系统中,可能有多个用户在执行事务。由于事务的原子性,各个事务的执行必然是按某种次序依次执行的,即事务对数据项的修改是互斥的,可把这种特性称为顺序性( Serializability)。用于实现事务顺序性的技术称为并发控制(Concurrent Control)。
利用互斥锁来实现“顺序性”
实现顺序性的一种最简单的方法,是为每一个对象(共享文件、记录或数据项)设置 一个用于实现互斥的锁,简称互斥锁(Exclusive Lock)。
利用互斥锁和共享锁实现顺序性
利用互斥锁存在效率不高的问题。为了提高运行效率而又引入了另一种形式的锁---- 共享锁(Shared Lock)。
若干具体的数据一致性问题
重复文件的一致性
为保证文件系统的可用性,在有些系统中为关键文件设置了多个重复拷贝,将它们分别存储在不同的地方。下图示出了UNIX类型的目录和具有重复文件的目录。
在有重复文件时,若一个文件拷贝被修改,则必须同时修改其它几个文件拷贝,以保证该文件中数据的一致性。
盘块号一致性的检查
盘块是用于存储文件的物理空间。用于描述盘块使用情况的数据结构有空闲盘块表( 链),文件分配表FAT。在每次启动机器时应检查这几个数据结构,它们是否保持了数据的一致性。
链接数一致性检查
在UNIX类型的文件目录中,其每个目录项内都含有一个索引结点号,用于指向该文件的索引结点。对于一个共享文件,其索引结点号便会在目录中出现多次。例如,当有5个用 户(进程)共享某文件时,该文件的索引结点号将会在目录中出现5次;另一方面,在共享文件的索引结点中有一个链接计数count,用来指出共享文件的用户(进程)数。在正常情况下这两个数据应该一致,否则就是数据不一致性差错。