object_id与data_object_id浅析(二)

 

接下来使用truncate命令

 

 

SQL> alter session set events '10046 trace name context forever, level 4';

 

Session altered

 

SQL> truncate table t;

 

Table truncated

 

SQL> select f_get_trace_name from dual;

 

F_GET_TRACE_NAME

--------------------------------

D:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\orcl_ora_2052.trc

 

 

观察数据表段情况。

 

 

SQL> select object_id,data_object_id from user_objects where object_name='T';

 

 OBJECT_ID DATA_OBJECT_ID

---------- --------------

     54038          54044

 

SQL> select segment_name, header_file, header_block from dba_segments where segment_name='T' and wner='SCOTT';

 

SEGMENT_NAME         HEADER_FILE HEADER_BLOCK

-------------------- ----------- ------------

T                              4         4203

 

 

注意:此处发生了变化。object_id没有变化,而data_object_id引入了一个新值。但是,进行truncate操作的时候,文件和文件头块的信息没有发生变化。

 

此时,我们检查跟踪文件,发现存在对数据字典表obj$,seg$等的更新内容。新的data_object_id想必也就是在此时被写入。

 

 

update obj$ set obj#=:6,type#=:7,ctime=:8,mtime=:9,stime=:10,status=:11,dataobj#=:13,flags=:14,oid$=:15,spare1=:16, spare2=:17 where owner#=:1 and name=:2 and namespace=:3 and(remoteowner=:4 or remoteowner is null and :4 is null)and(linkname=:5 or linkname is null and :5 is null)and(subname=:12 or subname is null and :12 is null)

END OF STMT

PARSE #6:c=0,e=46,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=11607801963

BINDS #6:

kkscoacd

 Bind#0

  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00

  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 ff=0

  kxsbbbfp=07eaf764  bln=24  avl=04  flg=05

  value=54038

 (篇幅原因,有省略

 Bind#6

  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00

  oacflg=08 fl2=0001 frm=00 csi=00 siz=24 ff=0

  kxsbbbfp=07eaf6f8  bln=24  avl=04  flg=05

  value=54044

 (篇幅原因,有省略

=====================

 

 

查找对应的seg$数据字典表,对应的段头信息是存在的。相当于对应的原始段信息存在。

 

 

SQL> select * from seg$ where file#=4 and block#=4203;

 

     FILE#     BLOCK#      TYPE#        TS#     BLOCKS    EXTENTS    INIEXTS    MINEXTS    MAXEXTS    EXTSIZE     EXTPCT      USER#      LISTS     GROUPS BITMAPRANGES  CACHEHINT   SCANHINT    HWMINCR     SPARE1     SPARE2

---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ------------ ---------- ---------- ---------- ---------- ----------

         4       4203          5          4          8          1          8          1 2147483645        128          0         54          0          0            0          0          0      54044     131329

 

 

注意,虽然文件和头块的位置没有发生变化,但是每行数据中对对象编号data_object_id的变化是落实的。

 

SQL> insert into t select * from dba_objects;

 

50358 rows inserted

 

SQL> commit;

 

Commit complete

 

SQL> select dbms_rowid.rowid_object(t.rowid) from t where rownum<5;

 

DBMS_ROWID.ROWID_OBJECT(T.ROWI

------------------------------

                         54044

                         54044

                         54044

                         54044

//此时,rowid对应的是物理data_object_id

 

结论:我们可以得到这样的结论。

 

首先,data_object_id是类似于段对象编号的作用。当一个段出现的时候,系统按照分配原则进行分配。如果段结构因为某种原因删除破坏,这个编号就消失,好像从未出现过一样。

 

其次,object_id是逻辑层面上的编号,针对一个逻辑对象。稳定性相对于物理段要稳定得多。

 

最后,truncate本质上是一种ddl语句。方式是基于对数据表segment结构的重构,实验中我们可以清晰看到原有segment对象的破坏和重构。但是,从我们的案例上看,新segment结构是可能会重用旧segment的空间和位置信息的,但是对Oracle和我们来说,他已经是一个新的segment对象了。

 

 

那么,有没有可能出现新segment的构建,并且物理位置变化呢?答案是肯定的。我们进行move操作,就可以实现这个目标。简单的下面实验。

 

 

SQL> select segment_name, header_file, header_block from dba_segments where segment_name='T' and wner='SCOTT';

 

SEGMENT_NAME         HEADER_FILE HEADER_BLOCK

-------------------- ----------- ------------

T                              4         4203

 

SQL> delete t where wner='PUBLIC';

 

19989 rows deleted

 

SQL> commit;

 

Commit complete

 

SQL> alter table t move;

 

Table altered

 

SQL> select segment_name, header_file, header_block from dba_segments where segment_name='T' and wner='SCOTT';

 

SEGMENT_NAME         HEADER_FILE HEADER_BLOCK

-------------------- ----------- ------------

T                              4         6651

 

SQL> select object_id,data_object_id from user_objects where object_name='T';

 

 OBJECT_ID DATA_OBJECT_ID

---------- --------------

     54038          54045

 

 

Move操作是从物理上直接对对象进行操作整理。经过对数据表的move操作,我们实现了我们的猜想。进行move操作时,数据行要进行重新的rowid排列,其中就包括新的segment对象设置。从原来的头块4203,转移到了6651。Data_object_id也被分配了一个新的编号54045。

 

 

综合来说,对Oracle来说,逻辑object_id是稳定的,而对应的物理位置和段对象是多变的。这点在我们进行字典分析的时候,需要额外注意。

 

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

转载于:http://blog.itpub.net/17203031/viewspace-690631/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值