第3章 VSAM文件处理
虚拟存储存取方式(Virtual Storage Access Method——VSAM)是IBM在1970 年作为OS/VS1 和OS/VS2操作系统的一部分引进的一种数据管理系统。虽然仍然有数据集被其他(非VSAM)的数据管理方式进行最好的管理,但VSAM是当代IBM操作系统的主要组成部分。在MVS 3.8成为这些操作系统之一以后,它有效地帮助其他用户设定VSAM的一些基本信息。以下分两个章节来介绍VSAM。
● 概念和设备
在此章节里简单描述了VSAM的组成部分,以及使用方法。
● 存取方式服务设施
此章节里介绍存取方式服务的功能,存取方式服务是单一的、多用途的设施,系统和应用程序员用存取方式服务去控制VSAM的组成部分。
3.1 概念和设备
VSAM是用来取代IBM操作系统所有早期使用的数据管理系统的,传统的(非VSAM)存取方式一般只提供单一的数据集结构类型,而VSAM提供3种。
● 键顺序数据集(Key Sequenced Data Set (KSDS)):通过指定每个记录的键值去访问数据记录,记录的键值是一系列的字符串,这些字符串在数据集的每个记录里嵌入,且是唯一的。KSDS数据集与索引顺序存取方式(Indexed Sequential Access Method (ISAM))数据集相似,有许多相同的特征,当然也有比ISAM明显的优点。
● 输入顺序数据集(Entry Sequenced Data Set (ESDS)):通过指定记录的物理位置去访问数据记录,此物理位置是与数据集开始位置有关的每一个记录的第1个字节的字节地址。ESDS数据集与基本顺序存取方式(Basic Sequential Access Methid (BSAM))或队列顺序存取方式(Queued Sequential Access Method (QSAM))数据集相似。
● 相对记录数据集(Relative Record Data Set (RRDS)):通过指定记录号去访问每一个记录,顺序记录号与数据集里的第1 个记录有关。RRDS数据集与基本直接存取方式(Basic Direct Access Method (BDAM))数据集相似。
VSAM数据集经常作为一个文件进行处理,KSDS组由两个物理部分组成:索引部分和数据部分;ESDS和RRDS组织只有一个组成部分:数据部分。
3.1.1 KSDS组成部分
在KSDS数据结构的每一个记录里包含一个键值字段,每一个记录的键值字段必须具有相同个数的字符并出现在同一个相对位置上,记录以它们的键值为基础,按照逻辑顺序存储在数据结构里。KSDS的索引部分包含数据集里每一个记录的键值列表,对应地指向数据结构中的相应记录。KSDS中的记录可以按照它们键值的次序顺序存取,或者按指定键值直接存取,KSDS记录可以是定长的,也可以是变长的,记录可以在任何位置上做增加或删除处理,周边受影响的记录需进行重新分配,以维持正确的逻辑顺序。
图3.1显示了键顺序文件KSDS的文件特性。
图3.1 键顺序文件KSDS的文件特性
KSDS文件的特性如下。
● 记录长度:定长或变长。
● 记录地址:可改变记录的相对位移RBA(Relative Byte Address)。
● 记录位置:通过键字段而排序。
● 替换索引:一个或多个。
● 跨越记录:可以。
● 存取方式:顺序、直接、键或RBA存取。
● 空间回收:可插入或删除记录并回收重用。
● 自由空间:通过文件的自由空间增加记录或改变记录的长度。
3.1.2 ESDS组成部分
ESDS里的记录按照它们输入到数据集里的顺序进行存储,每一个记录都有一个相对字节地址(Relative Byte Address(RBA)),在100个字节记录的ESDS数据集里,首记录的RBA为0,第2个记录的RBA是100,第3个是200,依此类推。ESDS记录可以按照RBA值的次序顺序存取,或指定RBA的值直接存取,记录可以是定长或变长的,记录不能从ESDS数据集里删除,记录只能插入到数据集的尾端。
图3.2显示了进入顺序文件ESDS的文件特性。
图3.2 进入顺序文件ESDS的文件特性
ESDS文件的特性如下。
● 记录长度:定长或变长。
● 记录地址:不可改变记录的相对位移RBA(Relative Byte Address)。
● 记录位置:按进入的物理顺序排序。
● 替换索引:一个或多个。
● 跨越记录:可以。
● 存取方式:顺序、直接、RBA存取(除非建立了替换索引)。
● 空间回收:不可插入或删除记录,但可用同等长度的记录置换重用该空间。
● 自由空间:文件的末端可增加记录,但不能改变记录的长度。
3.1.3 RRDS组成部分
RRDS记录存储在固定长度的槽中,每个记录都有属于它的槽记录号,记录号由1到数据集所允许的最大记录数排列,RRDS里的记录可以按照记录号的次序顺序存取,或按指定记录号直接存取,RRDS的记录可以是定长记录,也可以是变长记录,要增加新的记录数据需插入在空的槽中,记录允许从数据集里删除,被删除的记录的槽就空闲出来了。
图3.3显示了相对记录文件RRDS的文件特性。
图3.3 相对记录文件RRDS的文件特性
RRDS文件的特性如下。
● 记录长度:定长或变长。
● 记录地址:不可改变Slot的相对记录号(Relative Record Number——RRN)。
● 记录位置:按相对记录号排序。
● 替换索引:没有。
● 跨越记录:不可以。
● 存取方式:顺序、直接、RRN(视为键处理时当做KSDS)存取。
● 空间回收:可删除记录,可插入同一相对记录号的新记录重用该空间。
● 自由空间:文件的空置的Slot可增加记录,但不能改变记录的长度。
3.1.4 控制间隔
在非VSAM数据管理方式里,数据单元在存储器和定义为块(Block)的存储设备之间移动。在VSAM里,数据单元在每一个定义为控制间隔(Control Intervals(CI))的物理I/O运作里调动,一个控制间隔包含记录、控制信息和(对KSDS数据集)以后用来插入记录的自由空间(Free Space)。
当装载VSAM数据集时,就建立了控制间隔,并写入记录。在KSDS数据集里通常整个控制间隔没有被填满,一部分的自由空间留做扩展用。在ESDS数据集里,在记录按顺序被写入到下一个控制间隔内之前,每一个控制间隔是被填满的。在RRDS数据集里,控制间隔按照定长的槽填满,每一个都包含着活动的记录或空记录,含有空记录的槽可以用做新记录的插入。
控制间隔(CI)是VSAM文件一次物理I/O的单位,即从磁盘设备到虚存中的一次输入输出传送的单位。VSAM将文件记录组合在一起存放在较大的存储单位及CI中。对于一个VSAM数据集而言,每个CI的大小是一样的,但是,CI内的记录长度却是可以不同的。
控制间隔(CI)的格式可以用图3.4来表示。
图3.4 控制间隔(CI)的格式
图3.5是一个长度为2KB(2048字节)的控制间隔(CI)的示意图。
图3.5 长度为2KB的控制间隔(CI)的示意图
3.1.5 控制区域
控制间隔集中在一起成为控制区域(Control Areas(CA)),填充或写入到控制区域的规则类似于控制间隔。在ESDS和RRDS数据集里,控制区域用包含记录的控制间隔来填充。在KSDS数据集里,每一个控制区域内的某些控制间隔可能完全由用于数据集扩展的自由空间(Free Space)构成。
控制区域(CA)的格式可以用图3.6来表示。
图3.7是一个装有控制间隔(CI)的控制区域(CA)的示意图。
图3.6 控制区域(CA)的格式
图3.7 装有控制间隔(CI)的控制区域(CA)的示意图
理想的情况下,记录在插入、增加和扩充时,控制区间(CI)中存在着足够的自由空间足以容纳这些记录。但是,如果要插入的记录并不能全都放在一个CI内,就会出现控制区间分裂(CI Split)。这时,VSAM会将这些数据记录连同它们的控制信息从已写满的控制区间移至同一控制区域CA中空的控制区间CI中,并以适当的键顺序插入新的记录。
在指定的CA里,当CI中的自由空间不能容纳新记录时,就要出现控制区域的分裂(CA Split),VSAM会在文件的末尾处建立新的CA。它可通过使用原来已经分配的空间来实现,也可以通过扩充文件来实现。
一般而言,直接插入所引起的分裂,出现在CI和CA的中点位置,顺序插入引起的分裂,则出现在CI和CA的插入位置上。对于有足够自由空间分布的文件,不应经常出现分裂。
3.1.6 跨越记录(Spanned)
键顺序数据记录和进入顺序数据记录的长度如果超出CI,但又不能把它们分为几部分,或者为了使这些记录适合于CI的大小而又不重新格式化,那么,这些记录可以跨越或扩充至一个或多个CI边界,但在跨越之前,程序员应在定义文件时指定选择项SPANNED,这一类记录就被称为“跨越记录”。
跨越记录从其CI边界开始,并写满CA中的一个或多个CI,包含跨越记录的最后部分的CI,可以存到还没有使用的空间,但是这个空间只能用于扩充跨越记录,而不能包含其他记录。
图3.8是跨越记录的示意图。
图3.8 跨越记录的示意图
3.1.7 KSDS文件的物理实现
VSAM文件或数据集被分成控制区域和控制区间(CA),控制区间是连续的辅助存储区,控制区域包括一个或多个控制区间(CI)。控制区间是独立于存储它的物理设备的(也就是占据给定存储设备正好一磁道的控制区间,如果文件被传送到别的类型的设备上的话,可以要求多于或少于一个磁道),这种情形是用户不关心的。
控制区间的长度是固定的,由VSAM或用户规定。VSAM将根据记录长度、设备类型、I/O缓冲区所要求空间的数据决定最佳的长度。给定文件的所有控制区间具有相同的长度,新建立的数据集,可以是关键字顺序排列的和进入顺序排列的。这一讨论只关心前者,进入顺序的数据集没有进一步提及。索引中的项目称为索引记录。最低级的索引称做顺序集。所有较高及上层的记录统称为索引集。
顺序集中的项目包括控制区间中最高的关键字和指向该区间的垂直指针。索引集中的项目包括较低级的索引记录的最高关键字和指向该索引记录的垂直指针。
图3.9更清楚地说明了KSDS文件物理实现的相关概念。
图3.9 KSDS文件的物理实现
图3.9显示在VSAM数据集中水平地分配28个记录。整个文件包括3个控制区域,每个区域本身又包括3个控制区间。每个控制区间末尾所示的阴影部分包含VSAM所要求的控制信息。索引集只有一级索引,索引集中有3个项目,每个对应一个控制区域。索引集中的每个项目包括对应控制区域的最高关键字,因此,368、668和868分别是第1、第2和第3控制区域的最高关键字。每一控制区域有它自己的顺序集。第1顺序集中的项目说明第1控制区域中各控制区间的最高关键字分别是288、328和368。注意,第3控制区间的最高项目,368,对应于索引集第1控制区域的最高项目。
图3.9提到了两种类型的指针,水平指针和垂直指针,垂直指针用于直接存取单个记录。例如,如果要检索关键字为448的记录,VSAM从最高级索引(即索引集)开始,它得出结论,关键字为448的记录,如果存在的话,在第2个控制区域内(368是第1控制区域的最高关键字,而668是第2个控制区域的关键字)。VSAM根据指向第2个控制区域顺序集的垂直指针,得出它的最终结论:关键字为448的记录,如果存在的话,将在第2个控制区域的第1个控制区间中。
水平指针只用于顺序存取。在这种情形下,VSAM从第1顺序集开始,并使用水平指针从顺序集记录中得到包含下一级最高关键字的指针。换句话说,顺序集记录中的垂直指针指向数据,水平指针说明包含下一级最高记录的顺序集。
图3.9包含几种自由空间的分配,分配自由空间的方法有两种:按控制区间中的自由空间分配或按控制区域内的自由控制区间分配。换句话说,当VSAM装入文件时,整个文件有意留下空地方,这样做有利于随后插入新的记录。通过使用这个技术,VSAM就不必考虑IBM ISAM实现中的溢出区(记录检索一般在VSAM下较快,因为不必像ISAM那样需要通向溢出区的链)。
图3.10说明由于增加两个新记录,记录关键字418和768到图3.9的文件中去而产生的修改。第1个记录,关键字为418的增加,没有任何问题,因为记录所属的控制区间是够用的。记录418被插入到适当的位置,而在该控制区间中其他记录则向下移动。
记录键为768的记录的增加,要求不同的动作。在图3.9中,应当包含这一记录的控制区间满了。结果是,VSAM使控制区间分裂,在这种情形下,以前放在控制区间中的某些记录被移动到同一控制区域的其他控制区间中。第3个控制区域的顺序集中的项目也将改变,如图3.10所示。当我们认识到顺序集中的每个记录包含对应控制区间中的最高记录键时,这就非常有意义了。因此,顺序集中的记录必须反映控制区间的分裂。注意,控制区间分裂有利于随后的增加,因为自由空间又是随时可利用的。
图3.10 增加两个新记录后的VSAM文件结构
3.1.8 VSAM文件共享选项(SHARE OPTIONS)
VSAM共享选项(SHARE OPTIONS)在保证VSAM文件的完整性方面扮演着重要的角色。它指定VSAM文件的数据是否要或在多个程序之间共享及共享到什么程度。当你定义VSAM数据集时,在DEFINE命令的SHAREOPTIONS参数中定义数据集的共享属性。
共享属性的格式为SHAREOPTIONS(x,y)。不是太合适的说法是,x和y分别代表跨区域(Cross-Region)和跨系统(Cross-System)的共享选项。但是,共享属性对整个系统丛(SYSPLEX)都是有效的。我们继续使用跨区域和跨系统,是为了避免混淆。共享是通过VSAM控制块结构(Control Block Structures)控制的。VSAM使用SHAREOPTIONS的值来决定建立一个新的控制块结构是否合法,如果合法,OPEN文件就是成功的,否则,OPEN文件就会失败。
VSAM使用排队(Enqueue)方法实现共享选项(SHARE OPTIONS)所要求的共享级别。当打开文件时,系统建立一个新的控制块结构,这时,VSAM发出对名字SYSVSAM的排队(Enqueues)命令,如果排队成功,OPEN文件就是成功的,否则,OPEN就会出错。
当VSAM文件有次索引的时候,如果要OPEN路径(PATH)或整个CLUSTER,VSAM就会为CLUSTER部分建立一个控制块结构。比如,如果数据集是KSDS,即索引文件,VSAM就会为它的数据部分和索引部分建立控制块结构。当打开的是次索引时,VSAM只对次索引部分排队。
每次建立VSAM控制块结构时,VSAM就会申请排队以达到共享选项的要求。当VSAM数据集是空文件而且是作为OUTPUT打开时,无论共享选项SHAREOPTIONS是多少,在整个系统中只能有一个VSAM OUTPUT控制块结构存在。这时,VSAM将该文件作为共享选项SHAREOPTIONS(1,x)处理。
当VSAM数据集使用DISP=OLD处置选项时,VSAM将其当成共享选项SHAREOPTIONS(1,x)处理。
3.1.8.1 跨区域(Cross-Region)选项
跨区域选项的取值及其含义如下。
● (1)
该共享选项表示整个系统中只能有一个VSAM输出(OUTPUT)控制块结构或任意多个VSAM输入(INPUT)控制块结构。除了那些使用同一个控制块结构的OPENs操作外,VSAM确保整个系统中只有一个输出OPEN或只有多个输入OPEN控制块结构。任何其他的OPEN操作都会失败并从ACB得到出错的返回码。
这就意味着,如果数据集是按照输入(Input)打开的,其他程序如果是OPEN相同的数据集作为输入,就是成功的。如果有人想将文件作为输出(Output)打开,就会失败。换句话说,VSAM既确保了文件的读完整性,也确保了文件的写完整性。
对于输出处理来说,VSAM对文件的每一个部分做排他控制,确保整个系统中只有一个控制块结构存在。如果另外有一个不是使用同一个控制块结构的OPEN来了,VSAM就会拒绝它,即返回出错信息并使OPEN失败。
对于输入处理来说,VSAM对文件的每个部分执行共享排队,作为输入的OPEN是容许的。如果对同一个数据集不是使用同一个控制块结构作为输出打开,VSAM也会拒绝它。
● (2)
VSAM确保整个系统中只有一个VSAM输出控制块结构和多个输入控制块结构。换句话说,VSAM只保证写的完整性。如果你要求读完整性,你就要在你的程序中使用ENQ或DEQ宏命令来获得。对同一个VSAM数据集来说,如果整个系统中已经有一个OPEN作为输出(OUTPUT)的控制块结构,再申请输出控制块则结果就会失败。
● (3)
VSAM允许多个输入和输出控制块结构,换句话说,系统既不保证读完整性,也不保证写完整性。用户程序必须使用适当的ENQ和DEQ宏命令来保证文件的完整性。
● (4)
VSAM允许多个输入和输出控制块结构,换句话说,系统既不保证读完整性,也不保证写完整性。用户程序必须使用适当的ENQ和DEQ宏命令来保证文件的完整性。
对于直接存取处理,VSAM刷新数据和索引部分的缓冲区,以保证缓冲区数据的一致性。这里的一致性指的是,程序总是获得最新的记录数据。
3.1.8.2 跨系统(Cross-System)选项
正如我们前面所说的那样,名字跨系统是不合适的,因为SHAREOPTIONS是整个系统范围内有效的。跨系统选项提供的功能与跨区域选项3和4功能的一样。所以,它们只是一个使跨区域选项1和2的数据集达到选项3和4相同功能的方式。这就意味着,你可以让跨系统选项1和2具备缓冲区刷新(4)的功能。
跨系统选项的值可以是:
● (3)
对于使用该选项的VSAM文件,具有完全的共享特性,用户程序负责确保数据集的完整性。对于直接存取操作,VSAM不刷新缓冲区中的内容。
● (4)
对于使用该选项的VSAM文件,具有完全的共享特性,用户程序负责确保数据集的完整性。每次直接存取操作后,VSAM都会刷新缓冲区中的内容。
3.1.9 VSAM目录(VSAM Catalogs)
当建立一个非VSAM数据集时,用户可以通过JCL内的DISP=(,CATLG)选项为所建立的数据集在VSAM目录中登记一个记录。此目录保存该数据集所在的设备和卷标有关的信息,以便于以后通过此目录查找所需的数据集。VSAM数据集里,建立保存设备和卷标及许多其他数据集特性的目录项是必需的。
在VSAM之前, 非VSAM数据集的目录项包含在OS CVOLS(操作系统之卷标)内。VSAM维护自己的目录,本身也是KSDS数据集,该目录项目描述了VSAM数据集。同样的VSAM目录也可以用来控制非VSAM数据集的目录。
OS/390后期的版本(从MVS演化过来的)和当前的z/OS(MVS-OS/390具体化)操作系统,仍然使用另一个目录系统,即综合目录设备。在OS/390和z/OS最新版本里,ICF目录是系统唯一支持的目录类型。对MVS而言,相关的目录系统是VSAM目录,那里记录了VSAM和非VSAM数据集的信息。
在VSAM目录中,有两种目录:主目录(Master Catalog)和用户目录(User Catalog)。VSAM需要一个主目录,却可以有任意多个用户目录。用户目录由主目录指向并且具有和主目录相同的功能与结构。
引入主目录和用户目录的主要目的是提高数据的完整性、卷的可移植性。每个VSAM目录都存放于单个卷上并占有所驻的卷。当然,目录也可以占有几个卷,但是一个卷只能为一个目录所占有。
所有VSAM文件,若存在于卷中,则必须编目到目录中。VSAM目录包含了所有VSAM文件的集中信息、所在卷的有关信息,如VSAM文件分配的数据空间等。
由图3.11可见:VSAM主目录是用来指引各个用户目录的。当VSAM要用一个用户目录时,首先查找VSAM主目录。而VSAM提供了多个用户目录,每个用户目录都是独立的,控制了它的数据空间与文件,即这个用户所定义的每个VSAM文件与数据空间都要在这个用户目录上有一个进入点。
图3.11 VSAM目录结构
一个VSAM文件在其用户目录进入点有如下信息:文件的位置及其属性(如记录长度、键位置)、文件的一些动态信息(如文件建立后插入的记录数、控制区间分裂的个数等)。
在VSAM基本组成部分之间,首先可能看到一些复杂的难以理解的相互关联,下图将帮助理解它们之间的关系和相关的规则。
3.1.9.1 主目录
使用VSAM的每个系统都有一个且只有一个主目录(Master Catalog),这个主目录包含有关系统数据集和用于管理VSAM运作的VSAM结构的项目,在主目录里任何数据集(VSAM或非VSAM)可以登记到主目录中,但对一个好的管理系统来说,通常都不允许这样做。大多数的计算机系统里,系统管理人员在主目录里建立用户目录,计算机系统所有其他的用户只允许在用户目录里编目数据集。在上图中,灰色阴影中的目标是在主目录里编目的实体。在典型的系统里,这些实体都将是系统数据集,像系统库(非VSAM数据集)和页数据集。
主目录是在系统生成处理期间建立的,通常常居在系统卷上。主目录拥有计算机系统内的所有其他VSAM资源,这通过图中主目录(#1)的位置可以看出。在1970s描述VSAM组成部分的相互关系中,把主目录称为“VSAM君王”。
3.1.9.2 用户目录
用户目录(User Catalogs)建立起来用于保存应用指定数据集的目录信息,用户目录定义的目录信息存储在主目录的目录项目内。一个生产系统可以有任意个用户目录,它们用来保存与应用类型有关的数据集的信息,上图中显示了两个用户目录(#2和#3)。
当给定一个包含VSAM目录(无论是主目录或用户目录)直接存取存储器卷时,目录必须是存储在卷内的第1个VSAM实体。一个VSAM目录拥有它自己定居的卷,所有定义在包含VSAM目录的卷内的VSAM实体,必须在卷内进行编目,一个目录可以有其他卷,可是,这些卷不能包含其他的VSAM目录。当还没有包含VSAM目录的卷上定义了第1个VSAM实体时,卷就成为包含目录项目的目录的所有者。
3.1.9.3 VSAM数据空间
在卷上建立VSAM文件之前,必须建立一个或多个数据空间(VSAM Data Space)。数据空间是一个直接存取存储器的区域,专用于VSAM的分配。也就是说,数据空间占有的区域记录在分配给数据集的卷标目录(Volume Table of Contents (VTOC))内,此空间不能再分配做其他用途,无论是VSAM还是非VSAM,上图显示了3个数据空间(#4、#5和#6)。
事实上,当无论定义主目录还是用户目录时,VSAM建立数据空间去控制用户目录的入口,分配用户目录所需的空间数量,使卷上的数据空间完全地分配给目录。
记录在VTOC上的用于目录和数据空间的空间分配的文件名由VSAM生成。无论如何,它们极容易验证到那些包含生成名的高层验证符,目录(主目录和用户目录)的高层验证符是Z9999992,数据空间的是Z9999994。
3.1.9.4 VSAM族
在VSAM方法中,族(CLUSTER)是由一组有关的部分而组成的结构,如数据部分及其索引部分所组成的整体结构。VSAM把所有的文件都当做族来处理。因此,族是VSAM实施管理的基本单位。
在直接存取存储器上还未分配空间的状态下,就可以建立VSAM文件,这个文件需设定UNIQUE选项,必须由独立的数据空间构成,独立的数据空间完全由文件建立和使用。从数据管理者的观点来看,建立唯一的VSAM文件并不是一个好的建议,虽然有些情况下,有一些系统的数据集是按照此方式建立的。上图中这种文件分配的类型为图中的#9。
建立VSAM文件经常使用的方式是,在之前定义的数据空间里为文件记录子分配空间。上图中为系统和用户子分配的文件是#7、#8和#10。
除子分配文件之外所有VSAM实体,在实体所在的直接存取存储器卷上的VTOC里都有一个入口,入口名由VSAM产生,这些实体的记载通常不足以显示VSAM实体的内容。
3.1.9.5 非VSAM数据集(Non-VSAM Datasets)
除VSAM之外,非VSAM数据集(存储在磁带或直接存储区上的)可以在主目录和用户目录上保存入口,对VSAM实体而言,最好只要系统数据集在主目录上编目,因为编目非VSAM数据集的主要目的是保留设备和卷系列的信息,因此,存储非VSAM数据集的信息与存储VSAM实体的大量信息相比是很小的。上图中非VSAM实体是#11、#12和#13。