在ORACLE中,為了保證數據的一致性,在對數據庫中的數據進行操作時,系統會進行對數據相應的鎖定。
當程序對所做的修改進行提交(commit)或回滾后(rollback)后,鎖住的資源便會得到釋放,從而允許其它用戶進行操作。
但是,有時,由于程序中的原因,鎖住資源后長時間未對其工作進行提交;或是由于用戶的原因,如調出需要修改的數據后,未及時修改并提交,而是放置于一旁;或是由于客戶服務器方式中客戶端出現"死機",而服務器端卻并未檢測到,從而造成鎖定的資源未被及時釋放,影響到其它用戶的操作。
這時,我們需要迅速地診斷出鎖住資源的用戶并解決其鎖定。
1. 診斷系統中的鎖
為了找出系統中那些用戶鎖住資源以及那些用戶在等待相應的資源,可使用以下語句(其中的/*+ NO_MERGE(..) */千萬不可省略, 否則會很慢):
-- looklock.sql
-- use the NO_MERGE hints can speed up the query
select /*+ NO_MERGE(a) NO_MERGE(b) NO_MERGE(c) */ 'Wait' "Status", a.username, a.machine, a.sid, a.serial#, a.last_call_et "Seconds", b.id1, c.sql_text "SQL"
from v$session a, v$lock b, v$sqltext c
where a.username is not null
and a.lockwait = b.kaddr
and c.hash_value =a.sql_hash_value
union
select /*+ NO_MERGE(a) NO_MERGE(b) NO_MERGE(c) */ 'Lock' "Status", a.username, a.machine, a.sid, a.serial#, a.last_call_et "Seconds", b.id1, c.sql_text "SQL"
from v$session a, v$lock b, v$sqltext c
where b.id1 in
(select /*+ NO_MERGE(d) NO_MERGE(e) */ distinct e.id1
from v$session d, v$lock e
where d.lockwait = e.kaddr)
and a.username is not null
and a.sid = b.sid
and b.request=0
and c.hash_value =a.sql_hash_value;
執行后的結果如下所示:
Stat USERNAME MACHINE SID SERIAL# Seconds ID1
---- ------------------------------ ---------------- --------- --------- --------- ---------
SQL
----------------------------------------------------------------
Lock CIQUSR CIQ\DULMACER 12 966 245 131089
select * from c_trade_mode for update
Wait CIQUSR CIQ\DULMACER 10 735 111 131089
update c_trade_mode set x_name = 'zzz' where x_code='5'
Wait CIQUSR CIQ\DULMACER 15 106 1094 131089
select * from c_trade_mode for update
其中:
Status有兩種狀態,LOCK表明該進程鎖住了某個資源,WAIT表示該進程正在等待某個資源。
Username, Machine分別為ORACLE用戶名及機器名
SID,SERIAL#可用于隨后的解鎖操作
Seconds表示該進程最后一次進行操作至當前的時間(秒)
ID1, 鎖標識。某個LOCK狀態的ID1與某個WAIT狀態的ID1相同,可說明鎖的正是另一個進程等待的。
SQL: 鎖住資源的SQL語句
2. 解除鎖
診斷出鎖的狀態后,若發現該阻塞其它用戶進程的進程是正常操作中,則可通知該用戶對其進行提交,從而達到釋放鎖資源的目的;若為非正常操作,即,其狀態為"inactive",且其Seconds已為較多長時間,則可執行以下語句將該進程進行清除,系統會自動對其進行回滾,從而釋放鎖住的資源。
alter system kill session 'sid, serial#';
例如: 對于上例中顯示的結果, 可用以下語句清除鎖住資源的進程:
alter system kill session '12, 966';
關于你所說:在網絡斷掉(通過拔掉網線)或非正常終止進程(通過task manager強行關閉sql*plus)時,oracle在有限的時間內(我只觀查了5-10分)內,oracle未能對該進程作任何處理。
這個處理與TCP協議有關,因為SQL NET在使用TCP/IP協議進行網絡連接時是一種短連接,當ORACLE連接異常終止時,因為是異常終止,終止信號并沒有通過網絡通知server端,因此只有下次server有結果從服務器端返回需與client通信時,server才會發現此client已經端掉。因此出現你前面所提ORACLE處理異常終止進程延時情況.
死鎖:你可以試驗一條彼此存在依賴關系的update語句,ORACLE處理這種鎖時不是很好。
查鎖語句:查詢產生鎖的用戶鎖sql
select a.username username, a.sid sid, a.serial# serial,b.id1 id1, c.sql_text sqltext
from v$session a, v$lock b, v$sqltext c
where b.id1 in
(select distinct e.id1
from v$session d, v$lock e
where d.lockwait = e.kaddr)
and a.sid = b.sid
and c.hash_value = a.sql_hash_value
and b.request = 0;
死鎖:當兩個事務需要一組有沖突的鎖,而不能將事務繼續下去的話,就 出現死鎖。
如事務1在表A行記錄#3中有一排它鎖,并等待事務2在表A中記錄#4 中排它鎖的釋放,而事務2在表A記錄行#4中有一排它鎖,并等待事務 1在表A中記錄#3中排它鎖的釋放,事務1與事務2彼此等待,因此就造 成了死鎖。死鎖一般是因拙劣的事務設計而產生
版權歸原作者和各發布網站所有,此文章僅供學習參考之用
天天學習,好好向上——
posted on 2008-11-07 14:32
東頭bing阿頭 閱讀(431)
評論(0) 編輯 收藏 所屬分類:
DataBase