oracle解除死鎖
阿新 • • 發佈:2019-01-14
oracle會自動解決思索問題,把響應的死鎖解除。 實驗: create table A(id int); insert into A values(100); insert into A values(100); insert into A values(100); select * from A; >建立死鎖機制 --A使用者 update A set id = 1000 where id = 100; --B使用者 update A set id = 2000 where id = 200; --A使用者去觸碰B使用者正在使用的id=200的資料 update A set id = 1500 where id = 200; --B使用者去觸碰A使用者正在使用的id=100的資料 update A set id = 1100 where id = 100; 這樣就會造成死鎖,oracle會自動解除死鎖。 --------------------- Oracle 10.2.0.1.0 64位 ,作業系統 AIX 6.1 近期在檢視alert日誌時發現如下資訊 Mon Nov 5 16:02:40 2012 ORA-00060: Deadlock detected. More info in file /oradata/admin/$ORACLE_SID/udump/$ORACLE_SID_ora_6554104.trc. Mon Nov 5 16:06:52 2012 ORA-00060: Deadlock detected. More info in file /oradata/admin/$ORACLE_SID/udump/$ORACLE_SID_ora_9961902.trc. Mon Nov 5 16:51:21 2012 提示檢查到死鎖,然後檢視trace檔案 more /oradata/admin/$ORACLE_SID/udump/$ORACLE_SID_ora_6554104.trc 前面無關內容省略 *** 2012-11-05 16:02:40.639 *** SERVICE NAME:(SYS$USERS) 2012-11-05 16:02:40.638 *** SESSION ID:(154.37034) 2012-11-05 16:02:40.638 DEADLOCK DETECTED [Transaction Deadlock] Current SQL statement for this session: UPDATE "RZ_DLOGIN" SET "D_DATA" = :1 WHERE "G_NAME" = :2 AND "D_CODE" = :3 AND "CLASS_ID" = :4 The following deadlock is not an ORACLE error. It is a deadlock due to user error in the design of an application or from issuing incorrect ad-hoc SQL. The following information may aid in determining the deadlock: Deadlock graph: ---------Blocker(s)-------- ---------Waiter(s)--------- Resource Name process session holds waits process session holds waits TX-00080028-0000d238 68 154 X 81 97 X TX-0005001d-0000ac81 81 97 X 68 154 X session 154: DID 0001-0044-00000E1E session 97: DID 0001-0051-00000BDA session 97: DID 0001-0051-00000BDA session 154: DID 0001-0044-00000E1E Rows waited on: Session 97: obj - rowid = 0000D950 - AAANlQAAFAAA/ilABD (dictionary objn - 55632, file - 5, block - 260261, slot - 67) Session 154: obj - rowid = 0000D950 - AAANlQAAFAAA/ilAA7 (dictionary objn - 55632, file - 5, block - 260261, slot - 59) Information on the OTHER waiting sessions: Session 97: pid=81 serial=21773 audsid=600338 user: 55/DB O/S info: user: Administrator, term: name1, ospid: 1408:1296, machine: factory\name1 program: name.exe application name: name.exe, hash value=0 Current SQL Statement: UPDATE "RZ_DLOGIN" SET "D_DATA" = :1 WHERE "G_NAME" = :2 AND "D_CODE" = :3 AND "CLASS_ID" = :4 End of information on OTHER waiting sessions. 經過與開發人員溝通,已確認 UPDATE "RZ_DLOGIN" SET "D_DATA" = :1 WHERE "G_NAME" = :2 AND "D_CODE" = :3 AND "CLASS_ID" = :4 這一語句對應的前端應用A,與程式使用者溝通了解到前端應用A確認執行較慢,一般要等待一段時間才能完成,有時也會遇到等待無反應的情況,此時關閉應用A程式,重新執行就會正常。同時將上述日誌中發現的問題反映給開發人員,開發人員也證實此處程式需要優化。 現在的問題是: 既然Oracle日誌中已經提示檢查到死鎖,為何前端應用A只是等待了一段時間(這段等待時間使用者還能夠接受)就能夠繼續使用了,此時用下列語句查詢資料庫中是否存在死鎖 select username,lockwait,status,machine,program from v$session where sid in (select session_id from v$locked_object) 和 select sql_text from v$sql where hash_value in (select sql_hash_value from v$session where sid in (select session_id from v$locked_object)) 返回為空,說明查詢的時候死鎖已經不存在了,為什麼Oracle檢測到死鎖後,沒有任何人處理,死鎖又自己消失了,難道是Oracle後臺程序可以智慧處理這些死鎖? 另外,在百度查到關於死鎖的處理方法,有這麼一段話: 一般情況下,只要將產生死鎖的語句提交就可以了,但是在實際的執行過程中。使用者可能不知道產生死鎖的語句是哪一句。可以將程式關閉並重新啟動就可以了。 這個說法似乎也與前端應用A的使用者遭遇的情況差不多:有時候如果等待無反應,關閉A程式,然後重新執行就正常了。 請問百度裡的這個說法是不是正確的?是不是以後遇到Oracle資料庫死鎖都可以無視它,因為Oracle可以自己解決? --------------------------------------------------------------- 最近在寫儲存過程的時候,因為要測試儲存過程的執行情況,中途操作失誤,導致儲存過程死鎖,寫了半天的東西編譯不了了,沒辦法只能重新建立一個儲存過程,以前的那個刪也刪不掉,用也用不了,很難受,最後是重啟了資料庫才解決這個問題。不過現在找到一種更簡單的方法解決這個問題。 四步解決: 1、執行語句 select object_name,machine,s.sid,s.serial# from v$locked_object l,dba_objects o ,v$session s where l.object_id = o.object_id and l.session_id=s.sid; 1 2 3 查出來哪些物件被鎖,得到sid 2、還是執行語句 alter system kill session '24,111'; (其中24,111分別是上面查詢出的sid,serial#) kill該session (sid,serial#即為上面查出來的sid和serial#) 注:此語句只是將該儲存過程的狀態由active改為了killed,並沒有徹底的釋放該儲存過程,所以還是編譯不了儲存過程 3、要解決這一問題只能在OS上殺死這一執行緒(程序)了 執行語句獲得執行緒(程序)號 select spid, osuser, s.program from v$session s,v$process p where s.paddr=p.addr and s.sid=24 1 2 3 (24是上面的sid) 4、在伺服器上執行下列命令(資料庫在哪臺機子,就在哪臺機子執行) orakill sid thread 1 orakill是oracle提供的命令,一般裝oracle的時候,已經配上環境變數,這裡可直接執行 其中sid為該儲存過程所在資料庫的例項名我的為orcl thread即為執行緒(程序)號,即第三步查出來的spid。 以上就是解決儲存過程的死鎖問題了,也是從別人那取經回來的東西,寫出來,主要就是為了加強記憶 ---------------------