缥缈游侠-logzgh
===========================================================
在obj$基表中大量的non-existant类型对象是咋回事?
===========================================================

今天hoterran跟我说obj$中怎么会有那么多type#=10的对象存在。即select obj#,name,type# from obj$ where type#=10;

其type#为10表示的是什么类型呢?


对obj$基表字段的解释可以从sql.bsq文件中获得,关于type#的解释,我们可以从中得到:
type# number not null, /* object type (see KQD.H): */
/* 1 = INDEX, 2 = TABLE, 3 = CLUSTER, 4 = VIEW, 5 = SYNONYM, 6 = SEQUENCE, */
/* 7 = PROCEDURE, 8 = FUNCTION, 9 = PACKAGE, 10 = NON-EXISTENT, */
/* 11 = PACKAGE BODY, 12 = TRIGGER, 13 = TYPE, 14 = TYPE BODY, */
/* 19 = TABLE PARTITION, 20 = INDEX PARTITION, 21 = LOB, 22 = LIBRARY, */
/* 23 = DIRECTORY , 24 = QUEUE, */
/* 25 = IOT, 26 = REPLICATION OBJECT GROUP, 27 = REPLICATION PROPAGATOR, */
/* 28 = JAVA SOURCE, 29 = JAVA CLASS, 30 = JAVA RESOURCE, 31 = JAVA JAR, */
/* 32 = INDEXTYPE, 33 = OPERATOR , 34 = TABLE SUBPARTITION, */
/* 35 = INDEX SUBPARTITION */
/* 57 = SECURITY PROFILE */

即type#=10表示的是non-existant类型的对象。

随便找个db来看一下:
select">sys@alisoft_std3>select count(*) from obj$ where type#=10;

COUNT(*)
----------
111
有111个non-existant类型的对象,并且这些对象的创建时间(ctime)都很早,不可能是最近12个小时内产生的。

首先说说什么情况下会产生non-existant类型的对象。
有两大类情况会生成non-existant类型的对象:
1.删除,重命名之类的操作,也就是说原来的对象不存在了,oracle会将这些对象的type#改成10。
这种情况相信大家都好理解。

2.第二种情况相对来说就不太好理解了,用oracle的话来说"object entries created for negative dependency reasons"
即为了negative依赖关系而创建的。这种主要表现为系统包、视图和dual表。后面会找个例子来说明。

我们都知道smon进程有一大功能就是理清obj$中不存在的对象,其实就是清理type#为10的对象。
即然smon进程会清理,那为什么还会有这么多non-existant的对象呢?

其实smon只清理那些没有任何依赖关系的non-existant的对象,如果那些没有被任何其他对象使用的non-existant对象没有
被smon进程清理掉的话,都可以认为是oracle的bug.
其实前面所说的第一种情况正常情况下都会被smon清理掉的(当然也可以通过event来禁止smon这种功能),
而那些不会被smon进程清理掉的non-existant对象正常情况下都是属于前面所说的第二种情况。


select">sys@alisoft_std3>select obj#,name from obj$ where type#=10 and obj# not in (select p_obj# from dependency$);

no rows selected
可以发现所有type#=10的对象都是被别人使用的。

还有有个存过,里面有这段代码:
SELECT substr(child_id, 9, length(child_id) - 8), b.aw
FROM rry_im_child_user a,
(SELECT '201' aw
FROM dual
UNION
SELECT '202' aw
FROM dual
UNION
SELECT '203' aw
FROM dual
UNION
SELECT '301' aw
FROM dual
UNION
SELECT '302' aw
FROM dual
UNION
SELECT '305' aw FROM dual) b
WHERE a.login_id = x.login_id
AND a.gmt_expire >= v_gmt_online;
END IF;
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('no data found by : ' || x.login_id);
END;

当创建这个存过(object_id为21300)的时候,由于第二种原因,会产生两个non-existant的对象。

select">sys@alisoft_std3>select obj#,name,type# from obj$ where obj# in (select p_obj# from dependency$ where d_obj#=21300) and type#=10;

OBJ# NAME TYPE#
---------- ------------------------------ ----------
6614 DUAL 10
6616 DBMS_OUTPUT 10

不过有一点还没弄明白的是,oracle这么做会带来什么好处。

logzgh 发表于:2007.09.27 15:11 ::分类: ( Oracle技术 ) ::阅读:(503次) :: 评论 (2)
re: 在obj$基表中大量的non-existant类型对象是咋回事? [回复]

负依赖应该是因为公共同义词引起的,你引用了一个公共同义词对象,在当前schema中没有该对象,则会产生一个负依赖,这样当你在当前schema中创建一个同名对象的时候,会导致原来依赖该负依赖的对象失效

在library cache中也有负依赖和non existant对象的概念,作用也是相似的。

NinGoo 评论于: 2007.09.27 21:03
re: 在obj$基表中大量的non-existant类型对象是咋回事? [回复]

正解!
这的确是negative dependency的作用。

可以参见http://www.ixora.com.au/q+a/library.htm。

logzgh 评论于: 2007.09.27 22:15

发表评论
标题

在此添加评论
表情符号: smile laughing tongue angry crying sad wassat wink

称呼

邮箱地址(可选)

个人主页(可选)




自我介绍
切换风格
新闻聚合
博客日历
文章归档...
最新发表...
最新评论...
最多阅读文章...
最多评论文章...
博客统计...
网站链接...