Skip to Main Content
  • Questions
  • Meaning of object_id and data_object_id in dba_objects.

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Sai.

Asked: September 09, 2004 - 12:55 am UTC

Last updated: October 17, 2018 - 4:47 am UTC

Version: 8.1.7.4

Viewed 10K+ times! This question is

You Asked

Hi Tom,

For some objects in dba_objects, I see object_id is not matching with data_object_id even when that object is not part of the cluster.

21:35:49 SQL> select count(*) from dba_objects where
data_object_id is not null and
object_name not in (
select distinct table_name from dba_clu_columns)
/

COUNT(*)
----------
5930

Can you please explain why they are different and what could cause that.

Thanks.

and Tom said...

The object_id is the primary key, the data_object_id is the foreign key to the data segment.

Initially they are "the same"

But any operation that radically changes the data segment - eg: truncate, alter table exchange partition, etc -- will change the data_object_id -- the data segment the object points to.


consider:

ops$tkyte@ORA9IR2> create table t ( x int );

Table created.

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> select object_name, object_id, data_object_id
2 from user_objects
3 where object_name = 'T';

OBJECT_NAME OBJECT_ID DATA_OBJECT_ID
------------------------------ ---------- --------------
T 29413 29413

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> truncate table t;

Table truncated.

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> select object_name, object_id, data_object_id
2 from user_objects
3 where object_name = 'T';

OBJECT_NAME OBJECT_ID DATA_OBJECT_ID
------------------------------ ---------- --------------
T 29413 29414

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> alter table t move;

Table altered.

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> select object_name, object_id, data_object_id
2 from user_objects
3 where object_name = 'T';

OBJECT_NAME OBJECT_ID DATA_OBJECT_ID
------------------------------ ---------- --------------
T 29413 29415





Rating

  (5 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Thanks

Pravesh Karthik from Chennai, September 09, 2004 - 10:11 am UTC


What is it used for.

saibabu_d@yahoo.com, September 09, 2004 - 10:17 pm UTC

Tom,

That was a great explanation. Metalink note# 45888.1 says, "DATA_OBJECT_ID was introduced in 8.0 to track versions of the same segment (certain operations change the version). It is used to discover stale ROWIDs and stale undo records. ".

When does undo records become stale?

Thanks

Tom Kyte
September 10, 2004 - 7:58 am UTC

it is not used to "discover" those things -- it is used so we can just repoint a segment to a new segment. not really sure what they meant there

Very Well Explained

A reader, April 11, 2006 - 5:05 pm UTC


A reader, May 04, 2014 - 1:27 pm UTC

very useful and nice explanation

blast from the past

Racer I., October 16, 2018 - 8:58 am UTC

Hi,

Strangely this reference to "stale ROWIDs" sounds like a dead ringer for the new deferred global index maintenance feature on partitioned tables. In 2004.
Just out of curiosity :
https://richardfoote.wordpress.com/2018/10/09/hidden-efficiencies-of-non-partitioned-indexes-on-partitioned-tables-part-ii-aladdin-sane/
mentions :
We notice that the ROWID for each index entry is now the extended 10 bytes in size as it includes the Data Object Id.
https://blog.toadworld.com/2017/04/07/oracle-database-12c-deferred-global-index
mentions :
filter(TBL$OR$IDX$PART$NUM("DGOMEZ"."TABLE1",0,8,0,"TABLE1".ROWID)=1)
presumably that returns 1, as long as the given ROWIDs data_object_id (still) belongs to the given object.
sidenote : That (undocumented) function is probably a grab bag of functionality. In this case it doesn't seem to return the partition number or partition position but a Y/N answer. I also don't think we can write our own PL/SQL-functions that take actual objects (tables, (pseudo-)columns) rather than VARCHARS with those objects' names as parameters.

That explains how you can presumably truncate a partition and insert new rows into it and Oracle can still tell the old ROWIDs from the new ones even though they still point to the same object_id (just not data_object_id). Although :
> it is used so we can just repoint a segment to a new segment.
Why would truncate need a new segment?

There'se also this mentioned :
sys.index_orphaned_entry$;
select index_name, status,orphaned_entries from dba_indexes where owner='DGOMEZ' and index_name='INDEX1'

I assume that if during PMO_DEFERRED_GIDX_MAINT_JOB another drop/truncate occurs that should stop the cleaning of the orphaned_flag at the end.
Also unknown is if the cleaning continues (now removing the new dropped partitions entries too or leaving those alone?) or stops and restarts?

There seems to be some ironing out to do too :
http://mvelikikh.blogspot.com/2017/04/asynchronous-global-index-maintenance.html
job SYS.PMO_DEFERRED_GIDX_MAINT_JOB did not ignore objects in the Recycle Bin
the automatic maintenance job PMO_DEFERRED_GIDX_MAINT_JOB may fail and does not process all of the indexes that require cleanup.

An alternative to the job is
ALTER INDEX COALESCE CLEANUP
The docu (11 and 12) say :
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sqlrf/ALTER-INDEX.html#GUID-D8F648E7-8C07-4C89-BB71-862512536558

Use this clause to compact the index segments. Specifying ALTER INDEX ... SHRINK SPACE COMPACT is equivalent to specifying ALTER INDEX ... COALESCE
but :
SHRINK : Restriction on Shrinking Index Segments : You cannot specify this clause for a bitmap join index or for a function-based index.
COALESCE : Restrictions on Coalescing Index Blocks : no BMI or FBI mentioned

This also finds differences :
https://blog.dbi-services.com/what-about-alter-index-shrink-space/

regards,

Connor McDonald
October 17, 2018 - 4:47 am UTC

Nice input. I should note that we didnt extend the rowid to 10byte for deferred index maint, we did it way back in 8.0 when we came up with the new rowid structure to allow for larger databases.