经过前面的介绍,我们已经能够对Oracle的存储结构有了深入的了解,总结一下前面的内容:Oracle最小的数据存储单位是数据块(Block),如果以单个数据块进行对象空间分配,那么显然分配将过于频繁,所以Oracle使用多个数据块组成了区间(Extent),区间是Oracle数据库对象的最小空间分配单位,对象的空间分配和扩展只能以区间为单位进行,多个区间组成了段(Segment),根据用途的不同,Oracle数据库又存在不同的段类型。段存储在表空间中,一个数据库最终由一系列的表空间构成。
将以上的描述通过图5-6来表示(图中的数据块大小为2kB)。
图5-6 存储的物理结构示意图
Oracle对于Block的空间管理使用手工段空间管理和自动段空间管理技术,对于Extent的管理则通过字典管理和本地管理两种技术实现。Oracle的存储信息可以通过不同的数据字典查询得到,接下来将介绍一些主要的数据字典视图。
表空间信息记录(DBA_TABLESPACES)
DBA_TABLESPACES视图记录了数据库的表空间信息,表空间是数据库的一个逻辑概念,一个表空间可以由多个物理的数据文件组成。这个视图中记录了表空间的数据块大小、Segment、Extent管理方式等重要信息:SQL> select tablespace_name,block_size,extent_management,
2 segment_space_management,contents,retention,bigfile
3 from dba_tablespaces;
TABLESPACE_NAME BLOCK_SIZE EXTENT_MAN SEGMEN CONTENTS RETENTION BIG
--------------- ---------- ---------- ------ --------- ----------- ---
SYSTEM 32768 LOCAL MANUAL PERMANENT NOT APPLY NO
UNDOTBS1 32768 LOCAL MANUAL UNDO NOGUARANTEE NO
SYSAUX 32768 LOCAL AUTO PERMANENT NOT APPLY NO
TEMP 32768 LOCAL MANUAL TEMPORARY NOT APPLY NO
USERS 32768 LOCAL AUTO PERMANENT NOT APPLY NO
BOSSMGR 32768 LOCAL AUTO PERMANENT NOT APPLY YES
DBMON 32768 LOCAL AUTO PERMANENT NOT APPLY NO
TEMP1 32768 LOCAL MANUAL TEMPORARY NOT APPLY NO
8 rows selected.
注意这个视图中的retention、bigfile信息都是Oracle 10g中增加的,BIGFILE指示一个表空间是否是大文件表空间,在本章后面的小节中将会详细介绍大文件表空间;而Retention则和UNDO表空间的数据保留策略有关。
在AUM(Auto Undo Management)模式下,UNDO_RETENTION参数用以控制事务提交以后UNDO信息保留的时间,UNDO信息可以用于减少ORA-01555错误及一系列的闪回操作(Flashback)。该参数以秒为单位,在Oracle 9iR1中初始值为900秒,在Oracle 9iR2增加为10800秒。但是这是一个非担保性(NO Guaranteed)限制,也就是说,如果有其他事务需要回滚空间,而空间出现不足时,这些信息仍然会被覆盖,很多时候这是不希望被看到的。
从Oracle 10g开始,默认Oracle会启用自动调整以满足最长运行查询的需要,而不管UNDO_RETENTION的值是多少。SQL> select * from v$version where rownum <2;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
SQL> show parameter undo_retention;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 900
SQL> select begin_time,end_time,undotsn,undoblks,tuned_undoretention from v$undostat
2 where rownum<5 order by begin_time desc;
BEGIN_TIME END_TIME UNDOTSN UNDOBLKS TUNED_UNDORETENTION
-------------------- -------------------- ---------- ---------- -------------------
2011-1-4 18:21:56 2011-1-4 18:29:04 2 23 1896067
2011-1-4 18:11:56 2011-1-4 18:21:56 2 20 1894612
2011-1-4 18:01:56 2011-1-4 18:11:56 2 26 1891101
2011-1-4 17:51:56 2011-1-4 18:01:56 2 146 1887939
从结果里可以看到,尽管当前的undo_retention的值是900,但是在2011-1-4 18:21:56至2011-1-4 18:29:04这段时间内,oracle自动将undo_retention的值调整成了1896067。
但这并不代表着默认的undo_retention的值(Oracle 10gR2开始,这个默认值是900)没有作用,实际上,即使undo_retention的自动调整默认已被oracle采用,但由于oracle并不支持对lob字段的undo retention的自动调整,所以undo_retention的值依然对lob字段有效。同时Oracle增加了Guarantee控制,也就是说,你可以指定UNDO表空间必须严格满足UNDO_RETENTION的限制,即使UNDO空间不足,Oracle也不会回收未过期的UNDO空间,这样如果有用户请求UNDO空间得不到满足,则会报错退出。Oracle通过这种机制使得用户的期望可以被确保。
可以通过如下命令修改UNDO表空间的保证机制:SQL> alter tablespace undotbs1 retention guarantee;
Tablespace altered
SQL> alter tablespace undotbs1 retention noguarantee;
Tablespace altered
这个属性有3个选项:GUARANTEE、NOGUARANTEE和NOT APPLY。对于其他表空间这个属性不适用,显示为NOT APPLY。