Oracle表空间管理

表空间管理是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)不利。

  • 20
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值