ITPub博客

首页 > 数据库 > Oracle > Fine Grained Dependencies

Fine Grained Dependencies

原创 Oracle 作者:talio 时间:2014-03-26 16:14:24 0 删除 编辑

Fine Grained Dependencies是oracle 11g引入的一个新特性.  数据库中的某些对象之间会存在依赖关系,这些依赖关系可通过视图all/dba/user_dependencies查询得到. 在11g之前的版本中, 当记录这种依赖关系时只能具体到对象级别, 这样当某个被依赖的对象发生metadata的变化时,依赖于该对象的其他对象就会被置为invalid, 随后应用在访问这些失效的对象时就需要重新编译他们.比如,  视图V 依赖于表T的列C1, C2和C3 , 如果我们在表V上添加一个新列C4, 则视图 V就会由于基表T的结构变化而被置为invalidate. 但实际上我们知道,视图V其实只是依赖于表T的C1,C2和C3列,而表T的新增列并不对视图的使用构成影响. 11g引入了Fine Grained Dependencies, 数据库对对象间的依赖关系的描述可以具体到column级, 这样, 前面例子中的视图V就不用再被置为invalid了.
如下例:

  1. create table TEST_DEPENDENCY ( text varchar2(20));
  1. create view DEPENDENCY_VW as select text from TEST_DEPENDENCY;
  1. alter table TEST_DEPENDENCY add (doc clob);
  1. select owner,object_type,status from dba_objects where object_name=\'DEPENDENCY_VW\';
  1. OWNER OBJECT_TYPE STATUS
  1. ------------------------------ ------------------- -------
  1. LT_TEST VIEW VALID

关于Fine Grained Dependencies特性的更多介绍和实例可参考metalink文档430725.1.

这个新特性看起来是很好的,但在实际中我们会注意到,还是有些对象会在基表结构发生改变时被置为invalidate, 在我们检查这些被置为invalid对象的代码时并没有发现会受这种基表操作影响的证据.这是什么原因造成的呢?

首先,看看11g是如何实现Fine Grained Dependencies这个新特性的:

既然oracle能针对column级的依赖关系来判断是否需要invalidate一个对象,那么就必然在数据库中记录了这些依赖列信息. dba_denpendencies视图的底层表是dependency$:

  1. desc dependency$
  2. Name Null? Type
  3. ---------------------- -------- ----------------------------
  4. D_OBJ# NOT NULL NUMBER
  5. D_TIMESTAMP NOT NULL DATE
  6. ORDER# NOT NULL NUMBER
  7. P_OBJ# NOT NULL NUMBER
  8. P_TIMESTAMP NOT NULL DATE
  9. D_OWNER# NUMBER
  10. PROPERTY NOT NULL NUMBER
  11. D_ATTRS RAW(2000)
  12. D_REASON RAW(2000)

从dependency$表的结构可能,列依赖信息最有可能记录在列D_ATTRS或者D_REASON中.

  1. select o.owner#, o.name,p.NAME ref_obj,d.d_timestamp, d.d_attrs,d.d_reason
  2. from dependency$ d, obj$ o, obj$ p
  3. where d.d_obj#=o.obj# and d.p_obj#=p.obj# and p.name=\'TEST_DEPENDENCY\'
  4.     OWNER# NAME              REF_OBJ        D_TIMEST   D_ATTRS                          D_REASON
  5. ---------- --------------- --------------- --------    ------------------------------ ------------------------------
  6.       4030 DEPENDENCY_VW TEST_DEPENDENCY    20140324   0001000002


从查询结果看来,依赖关系应该是记录在列D_ATTRS中.

在该测试案例中, DEPENDENCY_VW视图需要访问TEST_DEPENDENCY表的列text,为第一个列. D_ATTRS列记录的信息为0001000002,该信息该如何解读呢?

在以下link中,

http://rwijk.blogspot.co.uk/2008/10/dbadependencycolumns.html

Rob Van Wijk通过测试说明了D_ATTRS列是如何来记录列reference关系的,大致对应关系如下:

NAME             COLUMN_ID        ATTRS            
--------------- -------------- --------------------
MYPROC1               1        0001000002          
MYPROC2               2        0001000004          
MYPROC3               3        0001000008          
MYPROC4               4        0001000010          
MYPROC5               5        0001000020          
MYPROC6               6        0001000040          
MYPROC7               7        0001000080          
MYPROC8               8        000100000001        
MYPROC9               9        000100000002        
MYPROC10              10       000100000004        
MYPROC11              11       000100000008        
MYPROC12              12       000100000010        
MYPROC13              13       000100000020        
MYPROC14              14       000100000040        
MYPROC15              15       000100000080        
MYPROC16              16       00010000000001      
MYPROC17              17       00010000000002      
MYPROC18              18       00010000000004      
MYPROC19              19       00010000000008      
MYPROC20              20       00010000000010      

前8位字符统一为"00010000",代表的含义不清楚,后面的16进制格式数字是一种二进制位表示法,采用逆序排列,对应的位为1时,表示对应的列被引用. 同时,为了方便查看, Rob还创建了视图dba_dependency_columns,用于记录引用列的详细信息.

到这里,仍没有之前问题的答案:"有些对象会在基表结构发生改变时被置为invalid,而检查这些被置为invalid对象的代码时并没有发现会受这种基表操作影响的证据".

比如,在我们的系统中, package ROO_API_PKG依赖于表XXX.root的: 


  1. select OWNER,NAME,TYPE from dba_dependencies where REFERENCED_OWNER=\'CORECAT\' and REFERENCED_NAME=\'ROOT\' and owner=\'XXX\';
  2. OWNER NAME TYPE
  3. ------------------------------ ------------------------------ ------------------
  4. XXX ROO_API_PKG PACKAGE BODY
  5. XXX ROO_API_PKG PACKAGE

  6. select o.owner#, o.name,p.NAME ref_obj,d.d_timestamp, d.d_attrs,decode(o.type#,9,\'PACKAGE\',11, \'PACKAGE BODY\')
  7. from dependency$ d, obj$ o, obj$ p
  8. where d.d_obj#=o.obj# and d.p_obj#=p.obj# and p.name=\'ROOT\' and o.name=\'ROO_API_PKG\';
  9.     OWNER# NAME REF_OBJ D_TIMEST
  10. ---------- ------------------------------ ------------------------------ --------
  11. D_ATTRS
  12. ------------------------------------------------------------------------------------------------------------------------
  13. DECODE(O.TYP
  14. ------------
  15.         56 ROO_API_PKG ROOT 20120122
  16. 000100001E0E
  17. PACKAGE
  18.  
  19.         56 ROO_API_PKG ROOT 20140324
  20. 000300001E0E
  21. PACKAGE BODY

D_ATTRS列从第9位开始的值为1E0E,表明第1,2,3,4,9,10,11列被ROO_API_PKG引用。当我们给root表添加新列时,从Fine

Grained Dependencies的信息和package body的定义来看,是不影响package ROO_API_PKG的访问的。

  1. alter table XXX.root add (test number);
  2. SQL> select owner,object_type,status from dba_objects where object_name=\\\'ROO_API_PKG\\\';
  3. OWNER OBJECT_TYPE STATUS
  4. ------------------------------ ------------------- -------
  5. XXX PACKAGE VALID
  6. XXX PACKAGE BODY INVALID

但从上面的测试结果来看,package body ROO_API_PKG还是被置为了INVALID。这是为什么呢?这似乎与fine grained dependencies这个新特性是矛盾的。回头看看dependency$表中D_ATTRS列的信息来看,惟一可疑的是这里package body前8位的值是00030000。而从之前的测试结果来看,这前8位的值一般为00010000,而不是00030000,从现有的资料我们也无从考证00010000代表的含义。考虑到该值的差异,我怀疑当基表发生结构变化时,即使不改变被依赖的列,但若D_ATTRS列的前8位为00030000,则该依赖对象也会被置为INVALID.按照该假设,我又查询了系统中其他的对象,当D_ATTRS列的前8位为00030000时,也会由于其基表看似无关的结构变化而被置为INVALID。

也就是说,从oracle 11g开始,随着fine grained dependencies特性的引入,当我们对被依赖对象作metadata改变时,只有被依赖对象具体的列发生了变化,oracle才会将依赖对象置为INVALID,从而提高了可用性。但这一结论也存在例外,那就是若dependency$表D_ATTRS列的前8 位值不是00010000,而是00030000,则很可能意味着oracle对这个对象作了特殊处理,基表的变化还是会引起该对象的invalid。

(以上结论是基于观察得到的,可能不准确,但在发现违反该结论的案例前,暂且认为它是正确的)。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/27243841/viewspace-1130034/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2013-05-14

  • 博文量
    17
  • 访问量
    273188