前面写了一篇文章,关于DROP USER过程中,查询DBA_SEGMENTS出现的奇怪的对象信息。而实际上那篇文章介绍的内容是个意外发现,第一次碰到这个现象是当前的问题所引发的,由于当时来不及记录,环境就被删除后。于是在不断尝试重现问题的过程中,引发了昨天问题。
DROP USER过程中出现的奇怪的对象信息:http://yangtingkun.itpub.net/post/468/492422
记得第一次碰到这个现象时,发现表空间存在很多OWNER为SYS的段,这些段的名称很奇怪,都是数字组成的。但是当时没有来得及研究环境就被清除了。唯一可以确定的是,这个问题和当时的DROP USER操作有关。
当然,通过上一篇文章的研究,已经了解这种现象的产生原因了。但是这个由FILE_ID和BLOCK_ID构成的对象名称只是在对象建立或删除的短暂时间内产生,并不会一直存储。而当时碰到的情况是这种数字构成的段名并不会消失,而是一直存在。
其实这时原因已经显而易见了,如果删除的对象处于一个只读表空间中,就会出现这种现象:
SQL> alter tablespace ndmain read only;
表空间已更改。
SQL> drop user ndmain cascade;
用户已删除。
SQL> set pages 100 lines 120
SQL> col segment_name format a30
SQL> select count(*)
2 from dba_segments
3 where tablespace_name = 'NDMAIN';
COUNT(*)
----------
327
SQL> select owner, segment_name
2 from dba_segments
3 where tablespace_name = 'NDMAIN';
OWNER SEGMENT_NAME
------------------------------ ------------------------------
SYS 16.143303
SYS 16.138695
SYS 16.138631
SYS 16.138567
.
.
.
SYS 14.391
SYS 14.327
SYS 14.135
SYS 14.7
已选择327行。
由于DROP USER CASCADE命令删除了用户下的所有对象,因此这些对象信息从数据字典中被清除。但是由于表空间NDMAIN处于只读状态,因此数据库不会真正清除表空间的数据文件上的信息,Oracle通过FILE_ID.BLOCK_ID的这种方式来表示这些被删除的段信息,而这些信息的清除将变成延迟事务,记录在SYS表空间内的系统回滚段中。
SQL> alter tablespace ndmain read write;
表空间已更改。
SQL> select owner, segment_name
2 from dba_segments
3 where tablespace_name = 'NDMAIN';
未选定行
当表空间恢复可写状态后,Oracle自动清除这个表空间上所有的被删除的段信息。