【问题标题】:Different values reported for ALL_OBJECTS.OBJECT_ID and ALL_ARGUMENTS.OBJECT_ID in Oracle 21cOracle 21c 中为 ALL_OBJECTS.OBJECT_ID 和 ALL_ARGUMENTS.OBJECT_ID 报告的不同值
【发布时间】:2022-06-28 02:31:15
【问题描述】:

我注意到,对于 SYS 架构中的某些对象,以下两列报告了不同的值:

例如:

select object_id
from all_objects
where object_name = 'DBMS_STATS'
and owner = 'SYS';

select distinct object_id
from all_procedures
where object_name = 'DBMS_STATS'
and owner = 'SYS';

select distinct object_id
from all_arguments
where package_name = 'DBMS_STATS'
and owner = 'SYS';

生产

OBJECT_ID
---------
14813

OBJECT_ID
---------
14812

OBJECT_ID
---------
14812

This dbfiddle reproduces it:

  • 在 Oracle 21c 上
  • 在 Oracle 18c 上
  • 但不是在 Oracle 11g 上

好像ALL_OBJECTS中的数据有误?我在OBJECT_ID = 14813 中找不到ALL_PROCEDURES 的任何条目,相反,OBJECT_ID = 14812ALL_OBJECTS 中生成此对象:

select owner, object_name, object_type
from all_objects
where object_id = 14812;

结果:

|OWNER |OBJECT_NAME       |OBJECT_TYPE|
|------|------------------|-----------|
|PUBLIC|XS$ROLE_GRANT_LIST|SYNONYM    |

完全不相关。这是字典视图中的已知错误吗?还是我误解了 OBJECT_ID 的语义,我认为它是字典中唯一的对象标识符?

我正在使用 Oracle Database 21c Express Edition Release 21.0.0.0.0 - 从这里开始生产:https://hub.docker.com/r/gvenzl/oracle-xe,尽管我们的客户也可以在 19c Enterprise Edition 19.5.0.0.0 中复制它

【问题讨论】:

  • fwiw:我无法在我的非 XE 19c 安装中重现该行为。
  • @RenéNyffenegger:这就是我添加该版本的原因。当 gvenzl 删除一些对象以使 docker 图像更小时,可能是该特定构建中的错误。这或许可以解释为什么它可以在 dbfiddle 上复制,因为它可能也使用该图像。
  • 看起来视图已被大幅改写。在 11g 中,它们都引用同一个基础表来获取obj#;在 21c 中只有 all_objects 直接使用它;其他人使用int$dba_proceduresint$dba_arguments。当然,它们似乎仍然应该对齐,但想知道其中是否有问题。虽然在 dbfiddle 上看不到它们。
  • @RenéNyffenegger:我们的一个客户正在使用 19.c (19.15.0.0.0) 有相同的错误,所以它似乎与 XE 无关。
  • 是的,我现在发现了一个 19.15.0.0.0 非 XE 安装,其中我有类似(尽管不完全相同)的现象。

标签: sql oracle


【解决方案1】:

在数据库是否为可插拔数据库的情况下尝试一下,例如

SQL> conn / as sysdba
Connected.
SQL> select object_id, object_type
  2  from all_objects
  3  where object_name = 'DBMS_STATS'
  4  and owner = 'SYS';

 OBJECT_ID OBJECT_TYPE
---------- -----------------------
     13795 PACKAGE
     19194 PACKAGE BODY

SQL>
SQL> select distinct object_id
  2  from all_procedures
  3  where object_name = 'DBMS_STATS'
  4  and owner = 'SYS';

 OBJECT_ID
----------
     13795

SQL> alter session set container = pdb1;

Session altered.

SQL> select object_id, object_type
  2  from all_objects
  3  where object_name = 'DBMS_STATS'
  4  and owner = 'SYS';

 OBJECT_ID OBJECT_TYPE
---------- -----------------------
     13796 PACKAGE
     19191 PACKAGE BODY

SQL>
SQL> select distinct object_id
  2  from all_procedures
  3  where object_name = 'DBMS_STATS'
  4  and owner = 'SYS';

 OBJECT_ID
----------
     13795
    127365

我的假设是 ALL_ARGUMENTS 等人指的是“真正的”拥有对象,即根容器中的对象。

这里有很多奇怪的小指针和东西来支持多租户,例如

SQL> conn / as sysdba
Connected.
SQL> select dbms_metadata.get_ddl('VIEW','DBA_ARGUMENTS') from dual;

DBMS_METADATA.GET_DDL('VIEW','DBA_ARGUMENTS')
------------------------------------------------------------------------------------------------
---

  CREATE OR REPLACE FORCE NONEDITIONABLE VIEW "SYS"."DBA_ARGUMENTS" ("OWNER", "OBJECT_NAME", "PA
LOA
D", "SUBPROGRAM_ID", "ARGUMENT_NAME", "POSITION", "SEQUENCE", "DATA_LEVEL", "DATA_TYPE", "DEFAUL
_LE
NGTH", "IN_OUT", "DATA_LENGTH", "DATA_PRECISION", "DATA_SCALE", "RADIX", "CHARACTER_SET_NAME", "
_SU
BNAME", "TYPE_LINK", "TYPE_OBJECT_TYPE", "PLS_TYPE", "CHAR_LENGTH", "CHAR_USED", "ORIGIN_CON_ID"
  select
   OWNER, OBJECT_NAME, PACKAGE_NAME, OBJECT_ID, OVERLOAD,
   SUBPROGRAM_ID, ARGUMENT_NAME, POSITION, SEQUENCE,
   DATA_LEVEL, DATA_TYPE, DEFAULTED, DEFAULT_VALUE, DEFAULT_LENGTH,
   IN_OUT, DATA_LENGTH, DATA_PRECISION, DATA_SCALE, RADIX,
   CHARACTER_SET_NAME, TYPE_OWNER, TYPE_NAME, TYPE_SUBNAME,
   TYPE_LINK, TYPE_OBJECT_TYPE, PLS_TYPE, CHAR_LENGTH, CHAR_USED, ORIGIN_CON_ID
from INT$DBA_ARGUMENTS


SQL> alter session set container = pdb1;

Session altered.

SQL> select dbms_metadata.get_ddl('VIEW','DBA_ARGUMENTS') from dual;
ERROR:
ORA-31603: object "DBA_ARGUMENTS" of type VIEW not found in schema "SYS"
ORA-06512: at "SYS.DBMS_METADATA", line 6731
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 105
ORA-06512: at "SYS.DBMS_METADATA", line 6718
ORA-06512: at "SYS.DBMS_METADATA", line 9734
ORA-06512: at line 1

SQL> select count(*)
  2  from dba_objects
  3  where object_name = 'DBA_ARGUMENTS'
  4  and object_type = 'VIEW';

  COUNT(*)
----------
         1

【讨论】:

    【解决方案2】:

    您在此处发现的似乎是数据字典中的错误,并报告为错误 34293726 - ALL_OJBECTS 中的错误 object_id 导致错误结果。 请不要被bug本身的标题误导了,all_objects中的object_id是错还是其他视图还有待判断。

    PDB 内all_objects 中报告的object_id 来自CDB 继承的子对象,而其他视图报告object_id 来自CDB 本身。

    在我的数据库中,DBMS_STATS 包在 CDB 本身中有 object_id16334

    SQL> select object_id
    from all_objects
    where object_name = 'DBMS_STATS'
    and owner = 'SYS';
    
     OBJECT_ID
    ----------
         16334
         22401
    
    SQL> select distinct object_id
    from all_procedures
    where object_name = 'DBMS_STATS'
    and owner = 'SYS';
    
     OBJECT_ID
    ----------
         16334
    
    SQL> select distinct object_id
    from all_arguments
    where package_name = 'DBMS_STATS'
    and owner = 'SYS';  2    3    4
    
     OBJECT_ID
    ----------
         16334
    

    然而,在 PDB 中,all_objects 中的 object_id 是 16335

    SQL> alter session set container=cdb1_pdb1;
    
    Session altered.
    
    SQL> select object_id
    from all_objects
    where object_name = 'DBMS_STATS'
    and owner = 'SYS';
    
     OBJECT_ID
    ----------
         16335
         22398
    
    SQL> select distinct object_id
    from all_procedures
    where object_name = 'DBMS_STATS'
    and owner = 'SYS';
    
     OBJECT_ID
    ----------
         16334
    
    SQL> select distinct object_id
    from all_arguments
    where package_name = 'DBMS_STATS'
    and owner = 'SYS';
    
     OBJECT_ID
    ----------
         16334
    

    查看 CDB 中的 cdb_objects(报告 CDB 中的所有对象,或在 PDB 本身中执行时仅报告 PDB 中的所有对象)时,这里发生的事情变得更加清晰。

    SQL> select con_id, owner, object_id, object_name, object_type
     from cdb_objects
     where object_name = 'DBMS_STATS';
    
    CON_ID OWNER  OBJECT_ID OBJECT_NAME  OBJECT_TYPE
    ------ ------ --------- ------------ ---------------
         1 SYS        16334 DBMS_STATS   PACKAGE
         1 SYS        22401 DBMS_STATS   PACKAGE BODY
         1 PUBLIC     16335 DBMS_STATS   SYNONYM
         3 SYS        16335 DBMS_STATS   PACKAGE
         3 SYS        22398 DBMS_STATS   PACKAGE BODY
         3 PUBLIC     16336 DBMS_STATS   SYNONYM
    

    注意 object_id 16335 在 PDB (con_id = 3) 中如何显示为包本身,而在 CDB (con_id = 1) 中相同的 object_id 被报告为公共同义词。同时,object_id16334 指的是存在于 CDB 中的实际对象,在 PDB 之间共享。

    缺少的链接是与 PDB 中的其他 ALL_* 视图,它们指的是 CDB 中的对象,object_id 16334 恰好是 PDB 中 all_objects 中完全不同的对象:

    SQL> select con_id,owner, object_id, object_name, object_type
     from cdb_objects
     where object_id = 16334;
    
    CON_ID OWNER  OBJECT_ID OBJECT_NAME        OBJECT_TYPE
    ------ ------ --------- ------------------ -----------
         3 PUBLIC     16334 XS$ROLE_GRANT_LIST SYNONYM
    

    这是字典视图中的已知错误吗?还是我误解了 OBJECT_ID 的语义,我认为它是字典中唯一的对象标识符?

    您确实正确理解了object_id 的语义,这似乎是一个错误并已报告。

    还值得向该线程的其他读者指出,随着 CDB 架构的引入而发生的变化是现在有多个分层字典在使用。最多可以有三个字典:CDB --> (Application Root) --> PDB。 Application Root 容器不是强制性的,在上面的层次结构中只是 CDB --> PDB。

    在任何一种情况下,子级都会继承父级中存在的对象,即 CDB 中的对象对所有应用程序根容器可用,而对应用程序根容器可用的对象(包括来自 CDB 的对象)对 PDB 可用. 这正是你在上面看到的不一致。对象16334是CDB中的对象,实际的DBMS_STATS包和对象16335是PDB中继承的包链接回CDB。

    【讨论】:

      猜你喜欢
      • 2023-01-12
      • 2020-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多