在Oracle中,分佈式事務ORA-01591錯誤如何解決?數據庫
一、故障環境介紹網絡
項目分佈式 |
數據庫ide |
DB類型工具 |
RAC對象 |
DB版本blog |
11.2.0.3事務 |
DB存儲it |
ASMio |
OS版本及kernel版本 |
AIX 64位 6.1.0.0 |
二、故障發生現象及報錯信息
有同事發來錯誤,截圖以下:
執行一個UPDATE語句的時候報ORA-01591的錯誤。
三、故障分析及解決過程
這個錯誤是因爲分佈式事務引發,而不是普通的鎖引發的。若檢查通常對象數據表鎖定,則只須要檢查V$LOCKED_OBJECT和V$TRANSACTION視圖,就能夠定位到具體的SQL語句和操做人等信息,可是檢查以後的結果以下:
1SYS@oraLHR12> SELECT * FROM GV$LOCKED_OBJECT; 2no rows selected 3SYS@oraLHR12> SELECT * FROM GV$TRANSACTION; 4no rows selected
兩個關鍵視圖中,沒有鎖定的對象,也沒有正在進行未提交的事務。那是否是沒有鎖定呢?或者鎖已經釋放了,從新嘗試對數據表加鎖,以下所示:
1SYS@oraLHR12> SELECT * FROM LHR.LHRBOKBAL FOR UPDATE; 2select * from LHR.LHRBOKBAL for update 3 * 4ERROR at line 1: 5ORA-01591: lock held by in-doubt distributed transaction 20.13.14721 6SYS@oraLHR12> SELECT COUNT(1) FROM LHR.LHRBOKBAL; 7 COUNT(1) 8---------- 9 30998411
系統沒有像通常阻塞那樣等待,而是報錯ORA-01591的錯誤,而且提示鎖被一個分佈式事務持有,不能實現加鎖操做。那麼ORA-01591錯誤到底是什麼錯誤呢?可使用Oracle提供的oerr工具查看該錯誤編號,以下所示:
1root@ZFLHRRSP:/# oerr ora 1591 201591, 00000, "lock held by in-doubt distributed transaction %s" 3// *Cause: Trying to access resource that is locked by a dead two-phase commit 4// transaction that is in prepared state. 5// *Action: DBA should query the pending_trans$ and related tables, and attempt 6// to repair network connection(s) to coordinator and commit point. 7// If timely repair is not possible, DBA should contact DBA at commit 8// point if known or end user for correct outcome, or use heuristic 9// default if given to issue a heuristic commit or abort command to 10// finalize the local portion of the distributed transaction. 11
簡單的說,01591錯誤的緣由是該對象被一個處在「IN-DOUBT」狀態的分佈式事務鎖定。分佈式事務使用的是「two-phase commit」二階段提交技術。解決該問題的方法就是查看內部表PENDING_TRANS$,肯定分佈式事務信息。這種狀態的事務主要是因爲在進行分佈式事務時候,發生網絡突發中斷的狀況,引發分佈式事務沒法正常結束,等待中斷節點的事務響應。因而,各節點的事務所鎖定的表就不會被釋放掉。
此時,檢查視圖DBA_2PC_PENDING(或者基表PENDING_TRANS$),查看是否存在這種狀況。
果真,當前存在一個阻塞分佈式事務,處在prepared狀態。當前問題,主要是源於在進入prepared階段以後,發生了網絡中斷的現象,引發COMMIT的階段不能等待到事務信息。因此,纔會一直處在Prepared狀態,數據表也就不會進行釋放。
對於這個事務,只能經過鏈接網絡或者強制提交回退事務來結束。可使用COMMIT FORCE或者ROLLBACK FORCE來進行處理,在這裏,進行回滾操做,以下所示:
1SYS@oraLHR12> ROLLBACK FORCE '20.13.14721'; 2Rollback complete.
ROLLBACK FORCE的參數是DBA_2PC_PENDING中記錄本地事務信息的編號即LOCAL_TRAN_ID。
此時,再次查看數據。
此時,該事務狀態已經變化爲forced rollback表示已經強制回退,此時再次嘗試鎖定表操做:
116:25:31 SQL> SELECT * FROM LHR.LHRBOKBAL FOR UPDATE; 2CURRENCY 3-------- 4001
能夠看出已經不報錯了,能夠正常執行。