從檢視看Oracle物件依賴機制
在Oracle中,很多物件之間是存在著依賴關係的。比如:檢視view與其包括的資料表、儲存過程與其內部使用的方法等。Oracle對於物件的依賴關係,是有專門的管理機制流程的。在本篇中,我們一起來探討這種依賴關係。
本篇實驗我們選擇“view+table”的簡單依賴模式進行研究。
1、 實驗環境
我們選擇Oracle 10gR2進行試驗。
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 – Production
建立實驗資料表,以及依賴資料表的檢視。
SQL> create table t as select * from dba_objects where wner='SCOTT';
Table created
SQL> create view v_t as select * from t;
View created
SQL> select text_length, text from dba_views where view_name='V_T' and wner='SCOTT';
TEXT_LENGTH TEXT
----------- ---------------------------------------------------------
180 select "OWNER","OBJECT_NAME","SUBOBJECT_NAME","OBJECT_ID","DATA_OBJECT_ID","OBJE
2、依賴關係判斷規則
資料表T和檢視V_T之間存在物件依賴關係。如果資料表T被刪除,那麼檢視V_T就不能是存在的。
首先,我們從dba_objects檢視中,可以看到v_t是valid狀態。
SQL> col object_name for a10;
SQL> select object_name, object_type, status from dba_objects where wner='SCOTT' and object_name='V_T';
OBJECT_NAM OBJECT_TYPE STATUS
---------- ------------------- -------
V_T VIEW VALID
如果我們刪除資料表T,那麼檢視v_t的狀態是如何變化呢?
SQL> drop table t;
Table dropped
SQL> select object_name, object_type, status from dba_objects where wner='SCOTT' and object_name='V_T';
OBJECT_NAM OBJECT_TYPE STATUS
---------- ------------------- -------
V_T VIEW INVALID
注意:當我們刪除一個底層被依賴物件的時候,會發現依賴物件(如檢視V_T)就聯動的狀態變化為失效。
如果我們此時使用v_t,系統報錯。
SQL> select count(*) from v_t;
select count(*) from v_t
ORA-04063: view "SCOTT.V_T" 有錯誤
這個時候,我們恢復底層的物件T,即使物件已經不是原來的T(object_id變化)。
SQL> create table t as select * from dba_objects where wner='SCOTT';
Table created
SQL> select object_name, object_type, status from dba_objects where wner='SCOTT' and object_name='V_T';
OBJECT_NAM OBJECT_TYPE STATUS
---------- ------------------- -------
V_T VIEW INVALID
我們從底層恢復了資料表T,發現檢視v_t並沒有聯動的變化為valid,而是保持了invalid狀態。那麼,這個時候,如果我們呼叫v_t,是否報錯呢?
SQL> select count(*) from v_t;
COUNT(*)
----------
49
SQL> select object_name, object_type, status from dba_objects where wner='SCOTT' and object_name='V_T';
OBJECT_NAM OBJECT_TYPE STATUS
---------- ------------------- -------
V_T VIEW VALID
當我們使用檢視的時候,檢視可以正常工作。而且當使用之後檢查dba_objects檢視,狀態已經修復為valid。
透過上面的實驗,我們可以猜測:當我們修改、刪除一個物件的時候,依賴該物件的物件狀態會以遞迴的方式變化(依賴鏈超過兩層時,效果相同)。當我們恢復這個物件狀態時候,連帶的被依賴物件是不會連帶的恢復狀態的。
進一步說,如果物件狀態是invalid,Oracle在使用的時候,會首先嚐試的編譯一下物件,看看是否狀態真的是invalid。如果確定是invalid,就報錯。如果不是invalid狀態,就重置狀態,並且返回結果。
3、 深層分析物件刪除操作
那麼,我們假定猜測,是建立在Oracle內部有儲存物件以來關係的資料字典。這個檢視字典就是dba_dependencies,我們可以從這個檢視中找到所有物件的依賴關係。這個依賴關係是物件在建立的時候就已經確立的。
SQL> select owner, name ,type, referenced_owner, referenced_name, referenced_type from dba_dependencies where wner='SCOTT' and name='V_T';
OWNER NAME TYPE REFERENCED REFERENCED REFERENCED
---------- ---------- ---------- ---------- ---------- ----------
SCOTT V_T VIEW SCOTT T TABLE
那麼,我們猜想,在drop一個資料庫物件的時候,連帶內部會去檢查依賴關係,並且更新obj$基礎表。
為了驗證我們的想法,使用10046事件跟蹤動作。
SQL> alter session set events '10046 trace name context forever, level 12';
會話已更改。
SQL> drop table t;
表已刪除。
SQL> alter session set events '10046 trace name context off';
會話已更改。
SQL> select f_get_trace_name from dual;
F_GET_TRACE_NAME
------------------------------------------------------------------------
C:\TOOL\ORACLE\ORACLE\PRODUCT\10.2.0\ADMIN\OTS\UDUMP\ots_ora_5764.trc
我們首先使用tkprof分析跟蹤檔案raw格式檔案。
D:\>tkprof ots_ora_5764.trc testres.txt
TKPROF: Release 10.2.0.1.0 - Production on 星期三 3月 14 15:39:08 2012
Copyright (c) 1982, 2005, Oracle. All rights reserved.
在生成的格式化檔案中,我們看到兩個遞迴SQL值得注意。
***************************************************************************
select o.owner#, u.name, o.name, o.namespace, o.obj#,
d.d_timestamp, nvl(d.property,0), o.type#, o.subname, d.d_attrs
from
dependency$ d, obj$ o, user$ u where d.p_obj#=:1 and (d.p_timestamp=:2
or d.property=2) and d.d_obj#=o.obj# and o.owner#=u.user# order by
o.obj#
*************************************************************************
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)
兩句SQL中,一個是對dependency$原資料表進行查詢,另一個是更新obj$資料表。Dependency$是檢視dba_dependencies的底層依賴檢視,而obj$又是dba_objects的基礎資料表。
我們猜測,正是這兩個SQL來實現的dba_objects中狀態變數的變化。首先從依賴關係中找到對應物件的依賴物件資訊,之後進行更新obj$操作。
要最後確定這一點,還要從raw中進行分析,找到對應bind value的取值。
PARSING IN CURSOR #7 len=331 dep=2 uid=0 ct=6 lid=0 tim=1751712040001 hv=2997034431 ad='288ce494'
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 #7:c=0,e=10730,p=0,cr=0,cu=0,mis=1,r=0,dep=2,og=4,tim=1751712039992
BINDS #7:
其中繫結變數
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=0868872c bln=24 avl=04 flg=05
value=115068
Bind#12
oacdty=01 mxl=32(03) mxlc=00 mal=00 scl=00 pre=00
oacflg=18 fl2=0001 frm=01 csi=852 siz=32 ff=0
kxsbbbfp=1fe33c4e bln=32 avl=03 flg=09
value="V_T"
顯然是要求修改v_t資訊,而修改的最終取值status為:
Bind#5
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=086886e4 bln=24 avl=02 flg=05
value=5
object_id為115068恰恰為檢視v_t的統一物件編號。目前他的狀態被修改為5,對應的含義取值為invalid。
SQL> select owner, object_name, object_id from dba_objects where object_id=115068;
OWNER OBJECT_NAM OBJECT_ID
---------- ---------- ----------
SCOTT V_T 115068
SQL> select namespace, status from obj$ where obj#=115068;
NAMESPACE STATUS
---------- ----------
1 5
另一個select SQL語句中,我們可以看到端倪。
PARSING IN CURSOR #1 len=302 dep=2 uid=0 ct=3 lid=0 tim=1751712024277 hv=444865451 ad='288cdfd4'
select o.owner#, u.name, o.name, o.namespace, o.obj#, d.d_timestamp, nvl(d.property,0), o.type#, o.subname, d.d_attrs from dependency$ d, obj$ o, user$ u where d.p_obj#=:1 and (d.p_timestamp=:2 or d.property=2) and d.d_obj#=o.obj# and o.owner#=u.user# order by o.obj#
END OF STMT
Bind#0
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=00 fl2=0001 frm=00 csi=00 siz=32 ff=0
kxsbbbfp=0868b3a8 bln=22 avl=04 flg=05
value=115069
這個115069是何許人也呢?
SQL> select owner, object_name, object_id from dba_objects where object_id=115069;
OWNER OBJECT_NAM OBJECT_ID
---------- ---------- ----------
SCOTT BIN$s/c/tF 115069
QdQG28enjy
QCtSdQ==$0
就是那個已經被刪除的資料表t,這裡我們還可以查到他是因為Oracle的flashback drop機制存在。
4、結論
Oracle資料庫物件之間是存在著有組織的依賴關係的。這種關係維護是透過內部的資料字典來進行。當我們讓一個底層物件失效,依賴它的所有物件都會設定為invalid。而且這個連帶變化是單向多層次進行的,通常不會出現底層物件失效,而上層物件保持為valid的場景。
但是,物件狀態恢復卻不是這樣。一個物件變為valid之後,依賴它的物件狀態不會連帶的更新為valid。只是當物件被使用的時候,Oracle內部會對invalid物件有一個compile的動作。
Oracle這樣做的原因,個人臆測是這樣的:物件的失效過程,需要將物件依賴鏈上級的所有物件直接設定為invalid就可以了。這個操作遞迴過程相當簡單,融合在delete操作或者其他中不會有很大的影響。
但是物件valid過程卻絕不簡單。一個底層物件恢復了valid,上層是不一定恢復的。因為上層物件可能依賴多個invalid物件,要確定所有的物件都是valid的。這樣就由一個遍歷鏈變成了深度遍歷樹的過程。從效能上,潛在壓力是巨大的。
所以,之所以有這樣的機制,恐怕還是oracle基於效能的一種這種考量。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-718906/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Maven依賴機制Maven
- idea檢視依賴樹Idea
- 我看依賴注入依賴注入
- .Net DI(Dependency Injection)依賴注入機制依賴注入
- ASP.NET的快取依賴機制-SQL快取依賴篇ASP.NET快取SQL
- 2.3 Spring的核心機制:依賴注入Spring依賴注入
- SpringIOC容器-物件依賴Spring物件
- 利用反射機制實現依賴注入的原理反射依賴注入
- Spring的核心機制依賴注入簡介Spring依賴注入
- 在WPF中使用依賴注入的方式建立檢視依賴注入
- 【工具】IDEA怎麼檢視maven依賴鏈路?IdeaMaven
- 從Hessian RPC 註解方式看Spring依賴注入RPCSpring依賴注入
- 從[] == ![] 看隱式強制轉換機制
- Android下檢視SO庫被依賴的情況Android
- Oracle中查詢依賴的無效物件(invalid object)Oracle物件Object
- Angular 依賴注入機制實現原理的深入介紹Angular依賴注入
- 檢視ORACLE中鎖定物件Oracle物件
- 如何檢視 SpringBoot 是否依賴了 logf42Spring Boot
- Oracle檢視物件佔用空間Oracle物件
- 【物件導向依賴關係概念總結】物件導向程式設計的五種依賴關係物件程式設計
- 從原始碼解析vue的響應式原理-依賴收集、依賴觸發原始碼Vue
- 從 Chrome 看瀏覽器的渲染機制Chrome瀏覽器
- Oracle 12.2使用手動建立與註冊依賴物件來執行聯機重定義Oracle物件
- 依賴管理和依賴範圍
- oracle 歷史檢視檢視,看這一篇就夠了Oracle
- 使用Gradle檢視Android專案中庫的依賴關係GradleAndroid
- 物件導向~如何解除具體依賴物件
- 依賴
- oracle檢視建立物件的DDL語句Oracle物件
- 依賴倒置(DIP)與依賴注入(DI)依賴注入
- Sql server 檢視錶引用、依賴項,刪除表及約束 指令碼SQLServer指令碼
- rimraf 命令強制刪除依賴庫檔案
- Maven依賴管理:控制依賴的傳遞Maven
- Maven依賴範圍及依賴傳遞Maven
- PG物件檢視物件
- 檢視處理Oracle中被鎖物件的SQLOracle物件SQL
- Oracle檢視被鎖物件及解鎖方法Oracle物件
- PostgreSQL/MogDB/openGauss怎樣獲取表上依賴於該表的檢視SQL