赞
踩
表空间管理是DBA的工作重点之一,所以本节也会用较大的篇幅来阐述数据库表空间相关的重要知识点和注意事项。
区管理和段管理
在日常维护中和表空间管理相关的主要视图如下所示。
视图 描述 V$TABLESPACE Name and number of all tablespaces from the control file. DBA_TABLESPACES, USER_TABLESPACES Descriptions of all (or user accessible) tablespaces. DBA_TABLESPACE_GROUPS Displays the tablespace groups and the tablespaces that belong to them. DBA_SEGMENTS, USER_SEGMENTS Information about segments within all (or user accessible) tablespaces. DBA_EXTENTS, USER_EXTENTS Information about data extents within all (or user accessible) tablespaces. DBA_FREE_SPACE, USER_FREE_SPACE Information about free extents within all (or user accessible) tablespaces. V$DATAFILE Information about all datafiles, including tablespace number of owning tablespace. V$TEMPFILE Information about all tempfiles, including tablespace number of owning tablespace. DBA_DATA_FILES Shows files (datafiles) belonging to tablespaces. DBA_TEMP_FILES Shows files (tempfiles) belonging to temporary tablespaces. V$TEMP_EXTENT_MAP Information for all extents in all locally managed temporary tablespaces. V$TEMP_EXTENT_POOL For locally managed temporary tablespaces: the state of temporary space cached and used for by each instance. V$TEMP_SPACE_HEADER Shows space used/free for each tempfile. DBA_USERS Default and temporary tablespaces for all users. DBA_TS_QUOTAS Lists tablespace quotas for all users. V$SORT_SEGMENT Information about every sort segment in a given instance. The view is only updated when the tablespace is of the TEMPORARY type. V$TEMPSEG_USAGE Describes temporary (sort) segment usage by user for temporary or permanent tablespaces.
最重要的一张视图是DBA_TABLESPACE,其结构如下:
SQL> desc dba_tablespaces Name Null? Type ----------------------------------------- -------- ---------------------------- TABLESPACE_NAME NOT NULL VARCHAR2(30) BLOCK_SIZE NOT NULL NUMBER INITIAL_EXTENT NUMBER NEXT_EXTENT NUMBER MIN_EXTENTS NOT NULL NUMBER MAX_EXTENTS NUMBER PCT_INCREASE NUMBER MIN_EXTLEN NUMBER STATUS VARCHAR2(9) CONTENTS VARCHAR2(9) LOGGING VARCHAR2(9) FORCE_LOGGING VARCHAR2(3) EXTENT_MANAGEMENT VARCHAR2(10) ALLOCATION_TYPE VARCHAR2(9) PLUGGED_IN VARCHAR2(3) SEGMENT_SPACE_MANAGEMENT VARCHAR2(6) DEF_TAB_COMPRESSION VARCHAR2(8) RETENTION VARCHAR2(11) BIGFILE VARCHAR2(3)
这张视图中包含了表空间管理中的几个重要知识点:
1.区(EXTENT)的管理方式
区(EXTENT)管理主要有数据字典管理方式(DMT)和本地管理方式(LMT)两种。在Oracle 8i之前,区管理均采用数据字典管理方式,其原理就是在Oracle基表SYS.FET
和
S
Y
S
.
U
S
E
T
和SYS.USET
和SYS.USET中记录区的使用情况。FET
用于管理已使用的区,
U
E
T
用于管理已使用的区,UET
用于管理已使用的区,UET用于管理可用(或空闲)的区。当数据库中区分配(如DROP/TRUNCATE一张大表或者INSERT操作)频繁时非常容易引起FET
和
U
S
E
T
和USET
和USET的争用,从而会导致数据库的性能问题。以下为基表FET
和
U
E
T
和UET
和UET的创建脚本(来自$ORACLE_HOME/rdbms/admin/sql.bsq):
create table fet$ /* free extent table */ ( ts# number not null, /* tablespace containing free extent */ file# number not null, /* file containing free extent */ block# number not null, /* starting dba of free extent */ length number not null /* length in blocks of free extent */ ) cluster c_ts#(ts#) / create table uet$ /* used extent table */ ( segfile# number not null, /* segment header file number */ segblock# number not null, /* segment header block number */ ext# number not null, /* extent number within the segment */ ts# number not null, /* tablespace containing this extent */ file# number not null, /* file containing this extent */ block# number not null, /* starting dba of this extent */ length number not null /* length in blocks of this extent */ ) cluster c_file#_block#(ts#, segfile#, segblock#) /
在基于数据字典的管理方式下,如果删除一个包含2个5MB区大小的表,在FET$基表中会存在2行记录,尽管这2个区互相紧挨着,在SMON进程将它们合并之前,Oracle并不会认为有10MB的空闲空间可用。如果此时进程请求10MB的空间,将会失败。所以使用数据字典管理方式时,应该控制频繁删除的表格的区数量和区大小,否则表空间下会出现很多碎片。
在Oracle 8i中,推出了一种全新的区管理方式:本地化管理的表空间。所谓本地化管理,是指Oracle不再利用数据字典表来记录Oracle表空间里面区的使用状况,而是在每个数据文件中加入了位图区,并用符号0/1表示每个区的使用状况。位图中一组相邻的0表示所有的这些空间都是可用而且邻接的。每当一个区被使用或者被释放以供重新使用时,Oracle都会更新数据文件位图区来反映这个变化。以下为本地化或者数据字典管理表空间的创建语法:
创建表空间时指定关键字EXTENT MANAGEMENT LOCAL 表示这是一个本地化管理的表空间。对于系统表空间,只能在创建数据库时指定EXTENT MANGEMENT LOCAL,因为它是数据库创建时建立的第一个表空间,如下所示:
SQL> show parameter compatible
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
compatible string 10.2.0
SQL> CREATE DATABASE mynewdb DATAFILE '/oradata/mynewdb/system01.dbf'
2 SIZE 325M REUSE EXTENT MANAGEMENT DICTIONARY
3 DEFAULT TEMPORARY TABLESPACE temp
4 TEMPFILE '/oradata/mynewdb/temp01.dbf' SIZE 100M;
SIZE 325M REUSE EXTENT MANAGEMENT DICTIONARY
*
ERROR at line 2:
ORA-25141: invalid EXTENT MANAGEMENT clause
由于本地管理表空间不需要操作FET
和
U
E
T
和UET
和UET基表,从而减少了对数据字典的依赖。所以本地管理表空间支持在一个表空间里面进行更多的并发操作。在选择了本地管理的表空间之后,还可以继续选择更细的区管理方式,如下所示:
若为AUTOALLOCATE,则表明让Oracle来决定每个段的区大小,同一个段中的区大小可以不同。所以段删除(DROP/TRUCATE TABLE等操作)之后可能会在表空间中留下若干大小不一的空洞(但大小有规律,如64KB、128KB、1MB不等)。当创建段对象时,Oracle会再次利用这些空间。所以从严格意义上来讲,使用本地管理的表空间不会存在碎片。
若为UNIFORM,则可以详细指定每个区的大小,若不加指定,则为每个区默认使用1MB的大小。过大的UNIFORM SIZE对于小表来说会浪费一定的空间(因为其数据量不足以填充1个UNIFORM SIZE),如果是大表,较大的UNIFORM SIZE(比如16MB)可以极大地减少区的数量,从而降低区的管理成本。
提示 TEMP表空间的区管理方式为UNIFORM统一区大小,区大小可以指定。
刚开始推出本地表空间管理时,还存在诸多BUG,但在Oracle 10g/11g中已经相当完美了,读者可以放心使用。Oracle提供了存储过程DBMS_SPACE_ADMIN.TABLESPACE_MIGRATE_TO_LOCAL用于将数据字典管理转换为本地表空间管理。
可以通过DBA_EXTENTS视图来观察段(SEGMENT)中区的分布情况,如下所示:
SQL> select FILE_ID,EXTENT_ID,BLOCK_ID,BLOCKS from dba_extents 2 where OWNER='ZHOU1' and SEGMENT_NAME='T1' 3 order by 2; FILE_ID EXTENT_ID BLOCK_ID BLOCKS ---------- ---------- ---------- ---------- 4 0 1289 8 4 1 1297 8 4 2 1305 8 4 3 1313 8 4 4 1321 8 4 5 1329 8 4 6 1337 8 4 7 1345 8 4 8 1353 8 4 9 1361 8 4 10 1369 8 4 11 1377 8 4 12 1385 8 4 13 1393 8 4 14 1401 8 4 15 1409 8 2 16 9 128 4 17 1417 128 2 18 137 128 4 19 1545 128 20 rows selected.
其实DBA_EXTENTS视图的数据取自段头(SEGMENT HEADER),如下所示:
Extent Map ----------------------------------------------------------------- 0x01000509 length: 8 0x01000511 length: 8 0x01000519 length: 8 0x01000521 length: 8 0x01000529 length: 8 0x01000531 length: 8 0x01000539 length: 8 0x01000541 length: 8 0x01000549 length: 8 0x01000551 length: 8 0x01000559 length: 8 0x01000561 length: 8 0x01000569 length: 8 0x01000571 length: 8 0x01000579 length: 8 0x01000581 length: 8 0x00800009 length: 128 0x01000589 length: 128 0x00800089 length: 128 0x01000609 length: 128 Auxillary Map -------------------------------------------------------- Extent 0 : L1 dba: 0x01000509 Data dba: 0x0100050c Extent 1 : L1 dba: 0x01000509 Data dba: 0x01000511 Extent 2 : L1 dba: 0x01000519 Data dba: 0x0100051a Extent 3 : L1 dba: 0x01000519 Data dba: 0x01000521 Extent 4 : L1 dba: 0x01000529 Data dba: 0x0100052a Extent 5 : L1 dba: 0x01000529 Data dba: 0x01000531 Extent 6 : L1 dba: 0x01000539 Data dba: 0x0100053a Extent 7 : L1 dba: 0x01000539 Data dba: 0x01000541 Extent 8 : L1 dba: 0x01000549 Data dba: 0x0100054a Extent 9 : L1 dba: 0x01000549 Data dba: 0x01000551 Extent 10 : L1 dba: 0x01000559 Data dba: 0x0100055a Extent 11 : L1 dba: 0x01000559 Data dba: 0x01000561 Extent 12 : L1 dba: 0x01000569 Data dba: 0x0100056a Extent 13 : L1 dba: 0x01000569 Data dba: 0x01000571 Extent 14 : L1 dba: 0x01000579 Data dba: 0x0100057a Extent 15 : L1 dba: 0x01000579 Data dba: 0x01000581 Extent 16 : L1 dba: 0x00800009 Data dba: 0x0080000b Extent 17 : L1 dba: 0x01000589 Data dba: 0x0100058b Extent 18 : L1 dba: 0x00800089 Data dba: 0x0080008b Extent 19 : L1 dba: 0x01000609 Data dba: 0x0100060b
当数据库中的段对象很多时,由于要扫描段头,查询DBA_EXTENTS视图需要较长的时间。
下面来总结一下本地表空间管理的优点:
本地管理的表空间避免了数据字典管理的递归空间操作。本地化管理的表空间使用标记位来管理空闲区信息,也避免了产生回滚信息(以数据字典管理空间时,更新UET
和
F
E
T
和FET
和FET基表时需要使用系统表空间中的回滚段)。
本地管理的表空间避免了在基表FET
、
U
E
T
、UET
、UET中写入区信息,从而减少了数据字典表的竞争,提高了空间管理的并发性。
表空间里区的大小可以选择由系统来决定,或者由数据库管理员指定一个统一的大小,避免了字典表空间中一直让人头疼的碎片问题。
段的区数量对性能影响不大,因此不必去关注具有很多个区的段。而在数据字典管理的时代,当段中有很多区时会导致DROP/TRUNCATE性能很慢。
段管理时不需要去考虑最佳的INITIAL、NEXT、PACTINCREATE和MAXEXTENTS等STORAGE参数。
2.段(SEGMENT)的管理方式
段(SEGMENT)的管理方式主要分手动段管理和自动段管理2种,其创建语法如下:
手动段管理方式(Manual Segemt Space Management)主要用FREE LIST、FREELIST GROUPS、PCTUSED和其他参数来控制如何分配、使用和重用段中的数据块。FREE LIST存储于段头中,默认情况下每个段的FREE LIST为1。读取Oracle的数据时,其读取单位是数据块(BLOCK),而一个BLOCK是否允许被写入数据,是基于其所属段的存储参数PCTFREE和PCTUSED来控制的。假设某张表的PCTFREE为20,PCTUSED为40,这就表示当一个BLOCK的空间使用率达到80%(100-PCTFREE)时,这个BLOCK就不再被允许INSERT新的数据了,而保留下来的这20%(PCTFREE)空间将会被预留为UPDATE可能发生的空间扩展,同时该BLOCK从FREE LIST中移除。如果该BLOCK上有数据行被DELETE,只有当该BLOCK的数据被删除到40%(PCTUSED)以下时,该BLOCK才会重新被加入到FREE LIST中。FREE LIST用于管理高水位以下的数据块(隐含参数_bump_highwater_mark_count控制着高水位的移动程度)。当并发进程需要从FREE LIST中频繁分配空闲块或者有大量的数据块重新加入到FREE LIST时容易引起段头的争用,也就会导致BUFFER BUSY WAITS等待事件。增大FREE LIST数量或使用FREELIST GROUP可以在一定程度缓减这个问题。FREE LIST已经逐渐成为一项过时的技术(截止到Oracle 11.2.0.3为止,SYSTEM、UNDO、TEMP表空间还是使用手动段管理方式),详细资料可以参考MOS文章1029850.6。
自动段管理方式(Automatic Manual Segemt Space Management,ASSM)使用位图块管理段中的数据块状态。L3 BMB称之为根节点,L2 BMB称之为枝节点,L1 BMB称之为叶节点。L3位于段头块中,对于L2 BMB来说,它起着指针的作用。而各L2 BMB又对L1 BMB起着指针作用。L1 BMB则管理具体的数据块可用空间。根据区大小,一个L1 BMB可以管理16个至1024个数据块的状态。在自动段管理方式中是使用位图数组来跟踪和管理每个分配到SEGMENT的BLOCK的,每个BLOCK有多少剩余空间将根据位图的状态来划分,如FULL、UNFORMATED、75%-100% FREE、50%-75% FREE、25%-50% FREE和0-25% FREE,也就是说位图实际上是采用了6个状态位来代替以前的PCTUSED参数。
由于L1 BMB直接管理数据块,当数据块空间变化频繁时,L1 BMB的状态位也会进行相应的变化。当L1 BMB、L2 BMB、L3 BMB的块数不能反映数据块的状态时,则会相应地增加位图块数量。虽然使用自动段管理方式可增加数据库的并发DML处理能力,但在极端情况下,过量的DML操作还是可能会引起位图块的争用。当出现这种情况时,一个解决办法是将表格插入大量的数据,提升表格的高水位。通过增加表格包含的数据块数量,间接增加位图块的数量。
自动段管理的本地管理表空间会忽略掉任何为存储参数PCTUSED、NEXT、FREELISTS和FREELIST GROUPS指定的值,因此创建段时只需要设置PCTFREE参数。从Oracle 10g开始,MAXTRANS参数也会被忽略,即所有段的MAXTRANS都是255。所以在进行EXP或者IMP逻辑导出时,Oracle警告日志可能有如下提示:
The value (30) of MAXTRANS parameter ignored.
kupprdp: master process DM00 started with pid=40, OS id=28000
to execute - SYS.KUPM$MCP.MAIN('SYS_EXPORT_FULL_01', 'BKUPUSER',
'KUPC$C_1_20070810163730', 'KUPC$S_1_20070810163730', 0);
kupprdp: worker process DW01 started with worker id=1, pid=43, OS id=28002
to execute - SYS.KUPW$WORKER.MAIN('SYS_EXPORT_FULL_01', 'BKUPUSER');
需要注意的是,Oracle 9i创建表空间时默认使用手动段管理方式,Oracle 9i及之前的低版本中自动段管理方式还有较多BUG,所以不推荐使用。Oracle 10g则默认使用自动段管理方式。此外只有本地管理的表空间才能使用自动段管理方式。
注意 增加FREE LIST数量或者使用自动段管理方式的根本目的是为了避免段头争用,但增加FREE LIST数量或者使用自动段管理方式后会使索引的块数量分布得较为分散,从而引起较大的CLUSTER FACTOR,较大的CLUSTER FACTOR会对索引范围读(RANGE SCAN)不利。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。