ORA-01591: 锁被未决分布式事务处理解决方案
現(xiàn)場(chǎng)報(bào)有一個(gè)功能走不下去,后臺(tái)日志報(bào)錯(cuò):java.sql.SQLException: ORA-01591: 鎖被未決分布式事務(wù)處理 657.7.39336 持有。
解決方案:
rollback force '657.7.39336';--執(zhí)行可能會(huì)比較慢
執(zhí)行完成后,查詢DBA_2PC_PENDING,
select * from DBA_2PC_PENDING s where s.local_tran_id='657.7.39336';
657.7.39336 SP4GD.a6dfea73.657.7.39336forced rollback no 2015-6-17 5:28:05 2015-6-17 10:44:33 2015-6-17 5:28:05 oracle UNKNOWN SCDB02 LCA_ZC 14456764049772
或者
delete from sys.pending_trans$ where local_tran_id = '657.7.39336';
delete from sys.pending_sessions$ where local_tran_id = '657.7.39336';
delete from sys.pending_sub_sessions$ where local_tran_id ='657.7.39336';
commit;
Commit force '657.7.39336'
exec dbms_transaction.purge_lost_db_entry('657.7.39336');
DBA_2PC_PENDING describes distributed transactions awaiting recovery.描述等待恢復(fù)的分布式事務(wù)。
這個(gè)錯(cuò)誤是什么意思呢?
[oracle@standby ~]$ 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)
兩階段提交協(xié)議可以保證數(shù)據(jù)的強(qiáng)一致性,許多分布式關(guān)系型數(shù)據(jù)管理系統(tǒng)采用此協(xié)議來完成分布式事務(wù)。它是協(xié)調(diào)所有分布式原子事務(wù)參與者,并決定提交或取消(回滾)的分布式算法。同時(shí)也是解決一致性問題的算法。該算法能夠解決很多的臨時(shí)性系統(tǒng)故障(包括進(jìn)程、網(wǎng)絡(luò)節(jié)點(diǎn)、通信等故障),被廣泛地使用。但是,它并不能夠通過配置來解決所有的故障,在某些情況下它還需要人為的參與才能解決問題。
顧名思義,兩階段提交分為以下兩個(gè)階段:
1)Prepare Phase (準(zhǔn)備節(jié)點(diǎn))
2)Commit Phase (提交階段)
1)Prepare Phase
在請(qǐng)求階段,協(xié)調(diào)者將通知事務(wù)參與者準(zhǔn)備提交或取消事務(wù),然后進(jìn)入表決過程。在表決過程中,參與者將告知協(xié)調(diào)者自己的決策:同意(事務(wù)參與者本地作業(yè)執(zhí)行成功)或取消(本地作業(yè)執(zhí)行故障)。
為了完成準(zhǔn)準(zhǔn)備階段,除了commit point site外,其它的數(shù)據(jù)庫節(jié)點(diǎn)按照以下步驟執(zhí)行:
每個(gè)節(jié)點(diǎn)檢查自己是否被其它節(jié)點(diǎn)所引用,如果有,就通知這些節(jié)點(diǎn)準(zhǔn)備提交(進(jìn)入 Prepare階段)。
每個(gè)節(jié)點(diǎn)檢查自己運(yùn)行的事務(wù),如果發(fā)現(xiàn)本地運(yùn)行的事務(wù)沒有修改數(shù)據(jù)的操作(只讀),則跳過后面的步驟,直接返回一個(gè)read only給全局協(xié)調(diào)器。
如果事務(wù)需要修改數(shù)據(jù),則為事務(wù)分配相應(yīng)的資源用于保證修改的正常進(jìn)行。
當(dāng)上面的工作都成功后,給全局協(xié)調(diào)器返回準(zhǔn)備就緒的信息,反之,則返回失敗的信息。
2) Commit Phase
在該階段,協(xié)調(diào)者將基于第一個(gè)階段的投票結(jié)果進(jìn)行決策:提交或取消。當(dāng)且僅當(dāng)所有的參與者同意提交事務(wù)協(xié)調(diào)者才通知所有的參與者提交事務(wù),否則協(xié)調(diào)者將通知所有的參與者取消事務(wù)。參與者在接收到協(xié)調(diào)者發(fā)來的消息后將執(zhí)行響應(yīng)的操作。
提交階段按下面的步驟進(jìn)行:
全局協(xié)調(diào)器通知 commit point site 進(jìn)行提交。
commit point site 提交,完成后通知全局協(xié)調(diào)器。
全局協(xié)調(diào)器通知其它節(jié)點(diǎn)進(jìn)行提交。
其它節(jié)點(diǎn)各自提交本地事務(wù),完成后釋放鎖和資源。
其它節(jié)點(diǎn)通知全局協(xié)調(diào)器提交完成。
3)結(jié)束階段
全局協(xié)調(diào)器通知commit point site說所有節(jié)點(diǎn)提交完成。
commit point site數(shù)據(jù)庫釋放和事務(wù)相關(guān)的所有資源,然后通知全局協(xié)調(diào)器。
全局協(xié)調(diào)器釋放自己持有的資源。
分布式事務(wù)結(jié)束
一般情況下,兩階段提交機(jī)制都能較好的運(yùn)行,當(dāng)在事務(wù)進(jìn)行過程中,有參與者宕機(jī)時(shí),重啟以后,可以通過詢問其他參與者或者協(xié)調(diào)者,從而知道這個(gè)事務(wù)到底提交了沒有。當(dāng)然,這一切的前提都是各個(gè)參與者在進(jìn)行每一步操作時(shí),都會(huì)事先寫入日志。
唯一一個(gè)兩階段提交不能解決的困境是:當(dāng)協(xié)調(diào)者在發(fā)出commit 消息后宕機(jī),而唯一收到這條命令的一個(gè)參與者也宕機(jī)了,這個(gè)時(shí)候這個(gè)事務(wù)就處于一個(gè)未知的狀態(tài),沒有人知道這個(gè)事務(wù)到底是提交了還是未提交,從而需要數(shù)據(jù)庫管理員的介入,防止數(shù)據(jù)庫進(jìn)入一個(gè)不一致的狀態(tài)。當(dāng)然,如果有一個(gè)前提是:所有節(jié)點(diǎn)或者網(wǎng)絡(luò)的異常最終都會(huì)恢復(fù),那么這個(gè)問題就不存在了,協(xié)調(diào)者和參與者最終會(huì)重啟,其他節(jié)點(diǎn)也最終會(huì)收到commit 的信息。這也符合CAP理論。
http://blog.itpub.net/48010/viewspace-1016050/
下面簡(jiǎn)單介紹一下分布式事務(wù)。
分布式事務(wù),簡(jiǎn)單來說,是指一個(gè)事務(wù)在本地和遠(yuǎn)程執(zhí)行,本地需要等待確認(rèn)遠(yuǎn)程的事務(wù)結(jié)束后,進(jìn)行下一步本地的操作。如通過dblink update遠(yuǎn)程數(shù)據(jù)庫的一行記錄,如果在執(zhí)行過程中網(wǎng)絡(luò)異常,或者其他事件導(dǎo)致本地?cái)?shù)據(jù)庫無法得知遠(yuǎn)程數(shù)據(jù)庫的執(zhí)行情況,此時(shí)就會(huì)發(fā)生in doublt的報(bào)錯(cuò)。此時(shí)需要dba介入,且需要分多種情況進(jìn)行處理。
分布式事務(wù)的Two-Phase Commit機(jī)制,會(huì)經(jīng)歷3個(gè)階段:
1.PREPARE PHASE:
1.1 決定哪個(gè)數(shù)據(jù)庫為commit point site。(注,參數(shù)文件中commit_point_strength值高的那個(gè)數(shù)據(jù)庫為commit point site)
1.2 全局協(xié)調(diào)者(Global Coordinator)要求所有的點(diǎn)(除commit point site外)做好commit或者rollback的準(zhǔn)備。此時(shí),對(duì)分布式事務(wù)的表加鎖。
1.3 所有分布式事務(wù)的節(jié)點(diǎn)將它的scn告知全局協(xié)調(diào)者。
1.4 全局協(xié)調(diào)者取各個(gè)點(diǎn)的最大的scn作為分布式事務(wù)的scn。
至此,所有的點(diǎn)都完成了準(zhǔn)備工作,我們開始進(jìn)入COMMIT PHASE階段,此時(shí)除commit point site點(diǎn)外所有點(diǎn)的事務(wù)均為in doubt狀態(tài),直到COMMIT PHASE階段結(jié)束。
2.COMMIT PHASE:
2.1 Global Coordinator將最大scn傳到commit point site,要求其commit。
2.2 commit point嘗試commit或者rollback。分布式事務(wù)鎖釋放。
2.3 commit point通知Global Coordinator已經(jīng)commit。
2.4 Global Coordinator通知分布式事務(wù)的所有點(diǎn)進(jìn)行commit。
3.FORGET PHASE:
3.1 參與的點(diǎn)通知commit point site他們已經(jīng)完成commit,commit point site就能忘記(forget)這個(gè)事務(wù)。
3.2 commit point site在遠(yuǎn)程數(shù)據(jù)庫上清除分布式事務(wù)信息。
3.3 commit point site通知Global Coordinator可以清除本地的分布式事務(wù)信息。
3.4 Global Coordinator清除分布式事務(wù)信息
以上3個(gè)階段,在任何一個(gè)階段的前、中、后發(fā)生失敗都會(huì)導(dǎo)致two phase commit失敗,一般來說,Oracle后臺(tái)進(jìn)程REC0會(huì)自動(dòng)恢復(fù)事務(wù),只有在分布式事務(wù)鎖住的對(duì)象急需被訪問,鎖住的回滾段阻止了其他事務(wù)的使用,網(wǎng)絡(luò)故障或CRASH的數(shù)據(jù)庫的恢復(fù)需要很長(zhǎng)的時(shí)間等情況出現(xiàn)時(shí),才需要使用人工操作的方式來維護(hù)分布式事務(wù),而分布式事務(wù)失敗的情況也比較復(fù)雜,需要針對(duì)不同的情形采取相應(yīng)的措施,Oracle中提供了視圖dba_2pc_pending和dba_2pc_neighbors供用戶查看分布式事務(wù)的相關(guān)信息,通常two phase commit失敗有如下5種情況:
1.prepare階段沒準(zhǔn)備好就失敗了,global coordinator正在等待各個(gè)站點(diǎn)返回已準(zhǔn)備好的通知,處于collecting狀態(tài),dba_2pc_pending試圖中的state列的值是collecting,各個(gè)站點(diǎn)什么都沒發(fā)生,無需執(zhí)行任何操作,在本地?cái)?shù)據(jù)庫執(zhí)行exec dbms_transaction.purge_lost_db_entry(’transaction_id’)清除in_doubt狀態(tài)的分布式事務(wù)記錄就可以了
2.prepare階段完成時(shí)發(fā)生失敗,global coordinator處于prepared狀態(tài),已經(jīng)加上分布鎖,等待提交,遠(yuǎn)程commit point site已經(jīng)自動(dòng)回滾,此時(shí)需要在global coordinator上執(zhí)行rollback force ‘transaction_id’,然后清除in_doubt狀態(tài)的分布式事務(wù)記錄
3.commit point site執(zhí)行commit完成后其他站點(diǎn)尚未commit時(shí)發(fā)生失敗,這時(shí)需要在其他站點(diǎn)執(zhí)行commit force ‘transaction_id’,'commit#’,注意后面的commit#使用較高的commit#,可以查詢各個(gè)站點(diǎn)的dba_2pc_pending試圖的commit#列得到,然后清除in_doubt狀態(tài)的分布式事務(wù)記錄
4.所有站點(diǎn)commit成功,進(jìn)入forget階段時(shí)發(fā)生失敗,數(shù)據(jù)已經(jīng)一致,只需在各站點(diǎn)清除in_doubt狀態(tài)的分布式事務(wù)記錄就可以了
5.commit point site完成forget階段,其他站點(diǎn)沒完成forget,只需在其他站點(diǎn)清除in_doubt狀態(tài)的分布式事務(wù)記錄就可以了
來自 “ ITPUB博客 ” ,鏈接:http://blog.itpub.net/31397003/viewspace-2153090/,如需轉(zhuǎn)載,請(qǐng)注明出處,否則將追究法律責(zé)任。
總結(jié)
以上是生活随笔為你收集整理的ORA-01591: 锁被未决分布式事务处理解决方案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 17,Flask-admin后台管理系统
- 下一篇: 如何成为一名专家级的开发人员(转载)