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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- NIO(二)淺析IO模型模型
- RXSwift原始碼淺析(二)Swift原始碼
- 淺析setTimeout與PromisePromise
- 淺析代理IP與VPS
- 淺析堆與垃圾回收
- Class與ClassLoader深入淺析
- PHP 與 Swoole 淺析與學習PHP
- 計算機網路淺析(二)計算機網路
- 淺析反向代理的原理與作用
- 淺析Is-a,Has-a與like-a
- 淺析 Node 程式與執行緒執行緒
- Qt繪圖淺析與例項QT繪圖
- 長槍與銃槍:《怪物獵人》武器設計風格淺析(二)
- iOS Block淺淺析iOSBloC
- 淺析容器安全與EDR的異同
- 淺析樂觀鎖與悲觀鎖
- 淺析Vue原始碼(九)——VirtualDOM與pathVue原始碼
- IOS學習之淺析深拷貝與淺拷貝iOS
- 淺析RedisRedis
- Jvm 淺析JVM
- CGLib淺析CGLib
- 淺析XMLXML
- MongoDB淺析MongoDB
- 淺析 JWTJWT
- 淺析 DDD
- RunLoop 淺析OOP
- 淺析 ReentrantLockReentrantLock
- Unstated淺析
- 淺析SharedPreferences
- Nginx淺析Nginx
- 淺析PromisePromise
- ejs 淺析JS
- 淺析KubernetesStatefulSet
- AIDL淺析AI
- ArrayList淺析
- Dubbo原始碼淺析(一)—RPC框架與Dubbo原始碼RPC框架
- 淺析pplx庫的設計與實現。
- 淺析 Flutter 與 iOS 的檢視橋樑FlutteriOS
- kylin streaming原理介紹與特點淺析