1. 程式人生 > >【轉】錯誤: ORA-01591: 鎖被未決分布式事務處理 7.2.428982 持有--解決方案

【轉】錯誤: ORA-01591: 鎖被未決分布式事務處理 7.2.428982 持有--解決方案

link trying 清除 fault locked fail 自動 針對 阻止

SQL 錯誤: ORA-01591: 鎖被未決分布式事務處理 7.2.428982 持有

01591. 00000 - "lock held by in-doubt distributed transaction %s"

*Cause: Trying to access resource that is locked by a dead two-phase commit

transaction that is in prepared state.

*Action: DBA should query the pending_trans$ and related tables, and attempt

to repair network connection(s) to coordinator and commit point.

If timely repair is not possible, DBA should contact DBA at commit

point if known or end user for correct outcome, or use heuristic

default if given to issue a heuristic commit or abort command to

finalize the local portion of the distributed transaction.

處理辦法:

rollback force ‘7.2.428982‘;--執行可能會比較慢

--執行完成後,查詢DBA_2PC_PENDING,

select * from DBA_2PC_PENDING s where s.local_tran_id=‘7.2.428982‘;

select * from DBA_2PC_PENDING;

或者

delete from sys.pending_trans$ where local_tran_id = ‘7.2.428982‘;

delete from sys.pending_sessions$ where local_tran_id = ‘7.2.428982‘;

delete from sys.pending_sub_sessions$ where local_tran_id =‘7.2.428982‘;

commit;

commit force ‘657.7.39336‘

exec dbms_transaction.purge_lost_db_entry(‘657.7.39336‘);

select sess.sid, sess.serial#, lo.oracle_username, lo.os_user_name, ao.object_name, lo.locked_mode

from v$locked_object lo, dba_objects ao, v$session sess

where ao.object_id = lo.object_id and lo.session_id = sess.sid;

select * from v$session t1, v$locked_object t2 where t1.sid = t2.SESSION_ID;

select s.sid,s.machine,o.object_name,l.oracle_username,l.locked_mode, ‘ALTER SYSTEM KILL SESSION ‘‘‘||s.sid||‘, ‘||s.serial#||‘‘‘;‘ Command from v$locked_object l,v$session s,all_objects o where l.session_id=s.sid and l.object_id=o.object_id

SELECT A.OBJECT_ID, B.OBJECT_NAME, A.SESSION_ID, A.ORACLE_USERNAME, A.OS_USER_NAME, A.PROCESS, A.LOCKED_MODE FROM V$LOCKED_OBJECT A, DBA_OBJECTS B WHERE A.OBJECT_ID = B.OBJECT_ID;

SELECT T2.USERNAME, T2.SID, T2.SERIAL#, T2.LOGON_TIME FROM V$LOCKED_OBJECT T1, V$SESSION T2 WHERE T1.SESSION_ID = T2.SID ORDER BY T2.LOGON_TIME;

ALTER SYSTEM KILL SESSION ‘sid, serial#‘;

DBA_2PC_PENDING describes distributed transactions awaiting recovery.描述等待恢復的分布式事務。

LOCAL_TRAN_ID String of form: n.n.n; n is a number

GLOBAL_TRAN_ID Globally unique transaction ID

STATE Collecting, prepared, committed, forced commit, or forced rollback

MIXED YES indicates part of the transaction committed and part rolled back

ADVICE C for commit, R for rollback, else NULL

TRAN_COMMENT Text for commit work comment text

FAIL_TIME Value of SYSDATE when the row was inserted (transaction or system recovery)

FORCE_TIME Time of manual force decision (null if not forced locally)

RETRY_TIME Time automatic recovery (RECO) last tried to recover the transaction

OS_USER Operating system-specific name for the end-user

OS_TERMINAL Operating system-specific name for the end-user terminal

HOST Name of the host machine for the end-user

DB_USER Oracle user name of the end-user at the topmost database

COMMIT# Global commit number for committed transactions

這個錯誤是什麽意思呢?

[[email protected] ~]$ oerr ora 01591

01591, 00000, "lock held by in-doubt distributed transaction %s"

// *Cause: Trying to access resource that is locked by a dead two-phase commit

// transaction that is in prepared state.

// *Action: DBA should query the pending_trans$ and related tables, and attempt

// to repair network connection(s) to coordinator and commit point.

// If timely repair is not possible, DBA should contact DBA at commit

// point if known or end user for correct outcome, or use heuristic

// default if given to issue a heuristic commit or abort command to

// finalize the local portion of the distributed transaction.

兩階段提交(2PC)

兩階段提交協議可以保證數據的強一致性,許多分布式關系型數據管理系統采用此協議來完成分布式事務。它是協調所有分布式原子事務參與者,並決定提交或取消(回滾)的分布式算法。同時也是解決一致性問題的算法。該算法能夠解決很多的臨時性系統故障(包括進程、網絡節點、通信等故障),被廣泛地使用。但是,它並不能夠通過配置來解決所有的故障,在某些情況下它還需要人為的參與才能解決問題。

顧名思義,兩階段提交分為以下兩個階段:

1)Prepare Phase (準備節點)

2)Commit Phase (提交階段)

1)Prepare Phase

在請求階段,協調者將通知事務參與者準備提交或取消事務,然後進入表決過程。在表決過程中,參與者將告知協調者自己的決策:同意(事務參與者本地作業執行成功)或取消(本地作業執行故障)。

為了完成準準備階段,除了commit point site外,其它的數據庫節點按照以下步驟執行:

每個節點檢查自己是否被其它節點所引用,如果有,就通知這些節點準備提交(進入 Prepare階段)。

每個節點檢查自己運行的事務,如果發現本地運行的事務沒有修改數據的操作(只讀),則跳過後面的步驟,直接返回一個read only給全局協調器。

如果事務需要修改數據,則為事務分配相應的資源用於保證修改的正常進行。

當上面的工作都成功後,給全局協調器返回準備就緒的信息,反之,則返回失敗的信息。

2) Commit Phase

在該階段,協調者將基於第一個階段的投票結果進行決策:提交或取消。當且僅當所有的參與者同意提交事務協調者才通知所有的參與者提交事務,否則協調者將通知所有的參與者取消事務。參與者在接收到協調者發來的消息後將執行響應的操作。

提交階段按下面的步驟進行:

全局協調器通知 commit point site 進行提交。

commit point site 提交,完成後通知全局協調器。

全局協調器通知其它節點進行提交。

其它節點各自提交本地事務,完成後釋放鎖和資源。

其它節點通知全局協調器提交完成。

3)結束階段

全局協調器通知commit point site說所有節點提交完成。

commit point site數據庫釋放和事務相關的所有資源,然後通知全局協調器。

全局協調器釋放自己持有的資源。

分布式事務結束

一般情況下,兩階段提交機制都能較好的運行,當在事務進行過程中,有參與者宕機時,重啟以後,可以通過詢問其他參與者或者協調者,從而知道這個事務到底提交了沒有。當然,這一切的前提都是各個參與者在進行每一步操作時,都會事先寫入日誌。

唯一一個兩階段提交不能解決的困境是:當協調者在發出commit 消息後宕機,而唯一收到這條命令的一個參與者也宕機了,這個時候這個事務就處於一個未知的狀態,沒有人知道這個事務到底是提交了還是未提交,從而需要數據庫管理員的介入,防止數據庫進入一個不一致的狀態。當然,如果有一個前提是:所有節點或者網絡的異常最終都會恢復,那麽這個問題就不存在了,協調者和參與者最終會重啟,其他節點也最終會收到commit 的信息。這也符合CAP理論。

http://blog.itpub.net/48010/viewspace-1016050/

下面簡單介紹一下分布式事務。

分布式事務,簡單來說,是指一個事務在本地和遠程執行,本地需要等待確認遠程的事務結束後,進行下一步本地的操作。如通過dblink update遠程數據庫的一行記錄,如果在執行過程中網絡異常,或者其他事件導致本地數據庫無法得知遠程數據庫的執行情況,此時就會發生in doublt的報錯。此時需要dba介入,且需要分多種情況進行處理。

分布式事務的Two-Phase Commit機制,會經歷3個階段:

1.PREPARE PHASE:

1.1 決定哪個數據庫為commit point site。(註,參數文件中commit_point_strength值高的那個數據庫為commit point site)

1.2 全局協調者(Global Coordinator)要求所有的點(除commit point site外)做好commit或者rollback的準備。此時,對分布式事務的表加鎖。

1.3 所有分布式事務的節點將它的scn告知全局協調者。

1.4 全局協調者取各個點的最大的scn作為分布式事務的scn。

至此,所有的點都完成了準備工作,我們開始進入COMMIT PHASE階段,此時除commit point site點外所有點的事務均為in doubt狀態,直到COMMIT PHASE階段結束。

2.COMMIT PHASE:

2.1 Global Coordinator將最大scn傳到commit point site,要求其commit。

2.2 commit point嘗試commit或者rollback。分布式事務鎖釋放。

2.3 commit point通知Global Coordinator已經commit。

2.4 Global Coordinator通知分布式事務的所有點進行commit。

3.FORGET PHASE:

3.1 參與的點通知commit point site他們已經完成commit,commit point site就能忘記(forget)這個事務。

3.2 commit point site在遠程數據庫上清除分布式事務信息。

3.3 commit point site通知Global Coordinator可以清除本地的分布式事務信息。

3.4 Global Coordinator清除分布式事務信息

以上3個階段,在任何一個階段的前、中、後發生失敗都會導致two phase commit失敗,一般來說,Oracle後臺進程REC0會自動恢復事務,只有在分布式事務鎖住的對象急需被訪問,鎖住的回滾段阻止了其他事務的使用,網絡故障或CRASH的數據庫的恢復需要很長的時間等情況出現時,才需要使用人工操作的方式來維護分布式事務,而分布式事務失敗的情況也比較復雜,需要針對不同的情形采取相應的措施,Oracle中提供了視圖dba_2pc_pending和dba_2pc_neighbors供用戶查看分布式事務的相關信息,通常two phase commit失敗有如下5種情況:

1.prepare階段沒準備好就失敗了,global coordinator正在等待各個站點返回已準備好的通知,處於collecting狀態,dba_2pc_pending試圖中的state列的值是collecting,各個站點什麽都沒發生,無需執行任何操作,在本地數據庫執行exec dbms_transaction.purge_lost_db_entry(’transaction_id’)清除in_doubt狀態的分布式事務記錄就可以了

2.prepare階段完成時發生失敗,global coordinator處於prepared狀態,已經加上分布鎖,等待提交,遠程commit point site已經自動回滾,此時需要在global coordinator上執行rollback force ‘transaction_id’,然後清除in_doubt狀態的分布式事務記錄

3.commit point site執行commit完成後其他站點尚未commit時發生失敗,這時需要在其他站點執行commit force ‘transaction_id’,‘commit#’,註意後面的commit#使用較高的commit#,可以查詢各個站點的dba_2pc_pending試圖的commit#列得到,然後清除in_doubt狀態的分布式事務記錄

4.所有站點commit成功,進入forget階段時發生失敗,數據已經一致,只需在各站點清除in_doubt狀態的分布式事務記錄就可以了

5.commit point site完成forget階段,其他站點沒完成forget,只需在其他站點清除in_doubt狀態的分布式事務記錄就可以了

【轉】錯誤: ORA-01591: 鎖被未決分布式事務處理 7.2.428982 持有--解決方案