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之间。如果参数的值较大,那么发生数据块间迁移的机会将减少,数据库的性能比较高,但是数据块空间的浪费比较严重。如果将参数值设置得较小,数据块存储空间的利用率较高,但是发生数据块间迁移的机会将增加,数据库的性能将受到较大影响。

figure_0243_0079

图 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时的情况。

figure_0243_0080

图 7.5 PCTUSED参数的用法

PCTFREE和PCTUSED参数的用法可以通过现实中的一个例子来说明。假设有一个水池,我们可以向水池中放水,也可以从水池排水。一方面,如果向水池中不断放水,当注入80%的水时即停止放水,这时水池中剩余20%的空间。另一方面,我们可以从水池中排水,当剩余60%或更少的水时,可以再次向水池中放水。如果水池中的水保持在60%~80%,不能向水池中放水。

figure_0244_0081

图 7.6 数据块空间的控制

如果一个段位于本地管理表空间中,并且段空间管理方式为MANUAL,或者位于字典管理表空间中,表空间将为每个段维护一个空闲列表。在空闲列表中记录所有完全空闲的数据块,或者已经使用的,但是可以继续写入数据的数据块。如果一个数据块中的空闲空间一直减少,当达到PCTFREE参数指定的数值时,这个数据块将被从空闲列表中删除。在这两种类型的表空间中,我们可以通过PCTFREE和PCTUSED参数控制数据块存储空间的使用。

例如,以下语句用于创建表tab5,并为段tab5指定PCTFREE和PCTUSED参数:


SQL>CREATE TABLE tab5(col int)

TABLESPACE ts10

PCTFREE 20

PCTUSED 40;