7.3.2 数据块的空间管理
数据块的空间管理主要涉及空闲空间的管理。当数据库服务器为数据库对象分配存储空间时,以区为单位分配几个连续的数据块,数据库对象的数据就存储在这些数据块中。当区中的一个数据块被写完时,数据将继续写入下一个数据块。当区中所有数据块都被写完时,数据将被写入下一个区。
这里以表为例来说明数据块空间的管理。当用户在表上执行INSERT操作时,新数据被写入数据块的空闲空间。当用户执行DELETE操作时,数据块中相应的数据将被删除。为了提高数据库的性能,在每个数据块中都需要保留一定的空间,这段空间是为执行UPDATE操作而保留的。
当用户执行UPDATE操作时,修改后的数据可能占用比原来更多的存储空间。例如,假设员工SMITH原来的奖金(COMM)为NULL,因为NULL是不占用存储空间的,所以当执行语句“UPDATE emp SET comm=5000 WHERE ename='SMITH'”时,该行数据将需要更多的存储空间。如果在当前块中没有预留空间,那么这行数据将被分开存储在两个块中,于是产生了块间的迁移。块间的迁移将降低数据库的性能,因为如果用户要访问这一行数据时,将不得不从两个数据块中读取数据,这样就增加了磁盘I/O。
如果在数据块中设置了保留空间,那么可能会出现这种情况:当用户执行UPDATE语句修改一行数据时,这行数据可能会占用比以前更多的空间,这时就可以使用保留空间,这样就减少了数据块之间的迁移。当然保留空间也可能无法满足UPDATE操作的需要,于是一行数据还是要被分开存储在两个数据块中,在这种情况下也将产生数据块间的迁移,只不过产生迁移现象的机会将大大减少。
如果表空间的区管理方式为本地管理,并且在创建表空间时使用SEGMENT SPACE MANAGEMENT子句指定段空间管理方式为AUTO,那么表空间将为每个段维护一个位图,并以位图的方式管理段中的数据块,这种管理是自动进行的,不需要人为干预。在其他情况下,表空间为每个段指定一个空闲列表,并以空闲列表的方式管理段中的数据块。在后一种情况下用户可以通过PCTFREE和PCTUSED两个参数控制数据块空间的使用。
PCTFREE和PCTUSED两个参数是用在数据库对象上的。在创建表、索引等数据库对象时,可以指定这两个参数,也可以在创建数据库对象之后修改这两个参数。
1.PCTFREE参数
PCTFREE参数用于设置数据块中必须保留的最少空间,参数值是一个百分比,保留的空间是为UPDATE操作使用的。当用户执行UPDATE操作时,修改后的数据可能需要比原来更多的存储空间(当然也可能比原来更少),如果没有保留空间,修改后的数据将不得不因为空间不足而另外使用一个数据块,这样一行数据将存储在两个数据块中,这种现象称为数据块间的迁移。当用户下次再访问这行数据时,将不得不从两个数据块中取出所需的数据,这样就增加了磁盘的I/O,从而降低了数据库的性能。
假设PCTFREE参数的值设置为20,那么在数据块中将有20%的保留空间,其余的80%的空间可用来存储数据。随着数据库服务器的运行,当80%的空间被消耗完时,新的数据将无法再写入这个块,于是需要使用一个新的数据块来存储数据。20%的保留空间是用于UPDATE操作的,如果用户一直没有执行UPDATE操作,或者经过UPDATE操作后数据需要的存储空间比原来反而更少,这部分空间将一直保持空闲。
PCTFREE参数的用法如图7.4所示。
PCTFREE参数的值可以设置在0~99之间。如果参数的值较大,那么发生数据块间迁移的机会将减少,数据库的性能比较高,但是数据块空间的浪费比较严重。如果将参数值设置得较小,数据块存储空间的利用率较高,但是发生数据块间迁移的机会将增加,数据库的性能将受到较大影响。
图 7.4 PCTFREE参数的用法
2.PCTUSED参数
PCTUSED参数用于设置可再次向数据块中写入数据时,已使用空间的百分比。如果将PCTFREE参数的值设置为20,那么最多可以使用数据块80%的存储空间。当可用空间被消耗完时,用户将无法继续向这个块中插入数据。当用户执行DELETE操作删除数据时,将使已使用空间减少,空闲空间增加。执行UPDATE操作也可能使已使用空间减少。随着已使用空间的不断减少,用户可再次写入数据,但是必须满足一定的条件,即已使用空间必须减少到PCTUSED参数指定的百分比。如果将PCTUSED参数值设置为60,那么当数据块中已使用空间减少到60%时,用户才可以再次向这个数据块中插入数据。
PCTUSED参数的用法如图7.5所示。
一般情况下PCTFREE和PCTUSED两个参数配合使用,共同控制数据块存储空间的使用。图7.6显示了PCTFREE和PCTUSED两个参数分别设置为20和60时的情况。
图 7.5 PCTUSED参数的用法
PCTFREE和PCTUSED参数的用法可以通过现实中的一个例子来说明。假设有一个水池,我们可以向水池中放水,也可以从水池排水。一方面,如果向水池中不断放水,当注入80%的水时即停止放水,这时水池中剩余20%的空间。另一方面,我们可以从水池中排水,当剩余60%或更少的水时,可以再次向水池中放水。如果水池中的水保持在60%~80%,不能向水池中放水。
图 7.6 数据块空间的控制
如果一个段位于本地管理表空间中,并且段空间管理方式为MANUAL,或者位于字典管理表空间中,表空间将为每个段维护一个空闲列表。在空闲列表中记录所有完全空闲的数据块,或者已经使用的,但是可以继续写入数据的数据块。如果一个数据块中的空闲空间一直减少,当达到PCTFREE参数指定的数值时,这个数据块将被从空闲列表中删除。在这两种类型的表空间中,我们可以通过PCTFREE和PCTUSED参数控制数据块存储空间的使用。
例如,以下语句用于创建表tab5,并为段tab5指定PCTFREE和PCTUSED参数:
SQL>CREATE TABLE tab5(col int)
TABLESPACE ts10
PCTFREE 20
PCTUSED 40;