基本概念
Local Coordinator:在分布事務(wù)中,必須參考其它節(jié)點(diǎn)上的數(shù)據(jù)才能完成自己這部分操作的站點(diǎn)。
Global Coordinator:分布事務(wù)的發(fā)起者,負(fù)責(zé)協(xié)調(diào)這個(gè)分布事務(wù)。
Commit Point Site:在分布事務(wù)中,首先執(zhí)行COMMIT或ROLLBACK操作的站點(diǎn)。一般情況下,應(yīng)該把存儲(chǔ)關(guān)鍵數(shù)據(jù)的站點(diǎn)作為Commit Point Site。因?yàn)镃ommit Point Site和其它站點(diǎn)不一樣,從來不會(huì)進(jìn)入prepared狀態(tài),所以不會(huì)存在IN-DOUBT事務(wù)。
可以設(shè)置初始化參數(shù)COMMIT_POINT_STRENGTH,在分布式事務(wù)中,會(huì)根據(jù)這個(gè)值的大小來確定Commit Point Site,分布事物的狀態(tài)信息也存在該數(shù)據(jù)庫中。一般將關(guān)鍵的數(shù)據(jù)庫作為commit point site ,commit_point_strength值較高的數(shù)據(jù)庫為commit point site,在分布事物中最先提交
分布式提交的3個(gè)階段
分布事物的兩階段提交分三個(gè)過程:
1. 準(zhǔn)備階段(PREPARE PHASE)
·本地?cái)?shù)據(jù)庫Global Coordinator向其它數(shù)據(jù)庫發(fā)出COMMIT通知
·比較所有數(shù)據(jù)庫的SCN號(hào),將最高的SCN號(hào)作為分布事物的全局SCN號(hào)
·所有數(shù)據(jù)庫寫在線日志
·對分布事物修改的表加分布鎖,防止被讀寫
·各數(shù)據(jù)庫向Global Coordinator發(fā)出已經(jīng)準(zhǔn)備好的通知
所有參與分布事物的數(shù)據(jù)庫必須經(jīng)過上述準(zhǔn)備,才能進(jìn)入下一階段。
2. 提交階段(COMMIT PHASE)
·本地?cái)?shù)據(jù)庫Global Coordinator通知commit point site首先提交。commit point site提交后,釋放其占有的資源,通知Global Coordinator完成提交
·本地?cái)?shù)據(jù)庫Global Coordinator通知其它數(shù)據(jù)庫提交
·提交節(jié)點(diǎn)在日志中追加一條信息,表示分布事物已經(jīng)完成提交,并通知Global Coordinator。此時(shí)所有數(shù)據(jù)庫的數(shù)據(jù)保持了一致性。
3. 注銷階段(FORGET PHASE)
·本地?cái)?shù)據(jù)庫Global Coordinator通知commit point site所有數(shù)據(jù)庫已經(jīng)完成提交
·commit point site清除分布事物的記錄和狀態(tài)信息,并通知Global Coordinator
·Global Coordinator清除本地分布事物的記錄和狀態(tài)信息
此時(shí)分布事物的兩階段提交全部完成。
如果兩階段提交完成之前,數(shù)據(jù)庫或網(wǎng)絡(luò)出現(xiàn)異常,應(yīng)用就會(huì)報(bào)錯(cuò),分布事物處于IN_DOUBT狀態(tài)。一旦數(shù)據(jù)庫或網(wǎng)絡(luò)恢復(fù)正常,系統(tǒng)(RECO PROCESS)會(huì)自動(dòng)處理IN_DOUBT狀態(tài)的分布事物。有些情況需要管理員手工處理IN_DOUBT狀態(tài)的分布事物:
·IN_DOUBT狀態(tài)的分布事物,將關(guān)鍵表鎖住,造成應(yīng)用不能正常工作
兩個(gè)重要的視圖
DBA_2PC_PENDING:列出所有的懸而未決的事務(wù)﹐此視圖在末填入懸而未決的事務(wù)之前是空的﹐解決這后也被清空。
LOCAL_TRAN_ID
本地事務(wù)標(biāo)識(shí)﹐格式為integer.integer.ingeger。
當(dāng)一個(gè)連接的local_tran_id和global_tran_id相同時(shí)﹐那么該節(jié)點(diǎn)是該事務(wù)的全局協(xié)調(diào)器。
GLOBAL_TRAN_ID
全局事務(wù)標(biāo)識(shí),格式為﹕global_db_name.db_hex_id.local_tran_id,其中db_hex_id是用來標(biāo)識(shí)數(shù)據(jù)庫八字符的十六進(jìn)制數(shù)﹐公共事各id在分布式事務(wù)的每個(gè)節(jié)點(diǎn)都是相同的。
“YES”意味著一部分事務(wù)已經(jīng)在一個(gè)節(jié)點(diǎn)上提交﹐而在另一個(gè)節(jié)點(diǎn)上被回滾。
TRAN_COMMENT
事務(wù)的注釋﹐或者如果使用了事務(wù)命名﹐當(dāng)事各被提交時(shí)﹐事務(wù)的名字就會(huì)出現(xiàn)在此處
已提交的事務(wù)的全局提交數(shù)
DBA_2PC_PENDING的STATE列的說明
Connecting
通常情況下﹐只有全局協(xié)調(diào)器和本地協(xié)調(diào)器才使用這個(gè)條目﹐節(jié)點(diǎn)在能夠決定它是否能夠準(zhǔn)備好之前﹐要收集來自于其它數(shù)據(jù)庫服務(wù)的信息。
節(jié)點(diǎn)已準(zhǔn)好﹐可能或者也可能沒有將已準(zhǔn)備好的消息通知本地協(xié)調(diào)器﹐但此時(shí)﹐該節(jié)點(diǎn)還沒有接收到提交的請求﹐仍保持著準(zhǔn)許備好的狀態(tài)﹐控制著提交事務(wù)所必需的任何本地資源。
節(jié)點(diǎn)(任何類型)已經(jīng)提交了事務(wù)﹐但該事務(wù)所包含的其它節(jié)點(diǎn)可能并沒有提交﹐也就是該事務(wù)在一個(gè)個(gè)或多個(gè)其它節(jié)點(diǎn)上仍然是懸而未決 。
Forced commit
DBA進(jìn)行判斷后﹐可以強(qiáng)行提交未決的事務(wù)﹐如果一個(gè)事務(wù)由DBA在本地節(jié)點(diǎn)進(jìn)行手動(dòng)提交時(shí)﹐產(chǎn)生此項(xiàng)目
Forced abor(rollback)
DBA進(jìn)行判斷后﹐可以強(qiáng)行回滾未決的事務(wù)﹐如果一個(gè)事務(wù)由DBA在本地節(jié)點(diǎn)進(jìn)行手動(dòng)回滾時(shí)﹐產(chǎn)生此項(xiàng)目
DBA_2PC_NEIGHBORS:列出所有獲得的(從遠(yuǎn)程客戶)和送出的(給遠(yuǎn)程服務(wù)器)懸而未決的事務(wù)﹐也表示該本地節(jié)點(diǎn)是不是事務(wù)的提交點(diǎn)站點(diǎn)。
LOCAL_TRAN_ID
對獲得事務(wù)來說指本地節(jié)點(diǎn)信息的客戶數(shù)據(jù)庫的名稱﹔對送出的事務(wù)來說指用于訪問遠(yuǎn)程服務(wù)器上信息的數(shù)據(jù)庫鏈接的名稱
DBuser_owner
對獲得事務(wù)來說指遠(yuǎn)程數(shù)據(jù)庫鏈接用于連接的本地賬戶﹔對于送出事務(wù)來說指該數(shù)據(jù)庫鏈接的擁有者。
INTERFACE
‘C’代表提交信息﹐’N’表示已準(zhǔn)備好狀態(tài)的一條消息或是一條請求只讀提交的請求。
當(dāng)’IN_OUT’為OUT時(shí)﹐’C’表示該連接的遠(yuǎn)程的站點(diǎn)是提交點(diǎn)站點(diǎn),并且知道是提交還是中斷?!疦’表示本地節(jié)點(diǎn)正在通知遠(yuǎn)程節(jié)點(diǎn)﹐說它已準(zhǔn)備好。
當(dāng)’IN_OUT’為IN時(shí)﹐‘C’表示本地節(jié)點(diǎn)或送出的遠(yuǎn)程的一個(gè)數(shù)據(jù)庫是提交點(diǎn)站點(diǎn)﹐’N’表示本地節(jié)點(diǎn)正在通知遠(yuǎn)程節(jié)點(diǎn)﹐說它已準(zhǔn)備好。
處理懸掛事務(wù)的一般步驟
1、 檢查alert文件,發(fā)現(xiàn)類似下面error:
ORA-1591 "lock held by in-doubt distributed transaction %s"
ORA-2062 "distributed recovery received dbid x, expected y"
ORA-2068 "following severe error from %s%s"
2、 確認(rèn)網(wǎng)絡(luò)是否正常、dblink是否valid、v$dblink和gv$dblink中查詢當(dāng)前是否在使用分布式事務(wù)。
3、 查詢視圖dba_2pc_pending,查詢懸掛事務(wù)信息:
SELECT LOCAL_TRAN_ID, GLOBAL_TRAN_ID, STATE, MIXED, HOST, COMMIT#
FROM DBA_2PC_PENDING
WHERE LOCAL_TRAN_ID = '??.';
如果沒有記錄,說明RECO進(jìn)程已經(jīng)自動(dòng)處理了該事務(wù)。
4、 在所有節(jié)點(diǎn)上查詢視圖dba_2pc_neighbors
5、得到所有節(jié)點(diǎn)的COMMIT_POINT_STRENGTH值,值最大的為commit point site,即最早提交的點(diǎn),如果懸掛事務(wù)發(fā)生在commit point site,則它的state決定了整個(gè)分布式事務(wù)的狀態(tài)。懸掛事務(wù)是否應(yīng)該commit force或者是rollback force,由此節(jié)點(diǎn)決定。
6、 檢查dba_2pc_pending的state列,如果是commited,意味著本地?cái)?shù)據(jù)庫提交已經(jīng)成功。其他節(jié)點(diǎn)需要根據(jù)本地事務(wù)號(hào)和最大的commit#進(jìn)行強(qiáng)制提交。用法如下:
SVRMGR> COMMIT FORCE 'your local transactionID on this node', 'highest SCN from already committed site';
SVRMGR> COMMIT FORCE '1.13.5197', '88123887';
7、 如果commit point site的state為commited外的其他狀態(tài),則表明commit point site 沒有提交成功,分布式事務(wù)需要強(qiáng)制回滾。這里不再需要所有節(jié)點(diǎn)的最大commit#。用法如下:
SVRMGR> ROLLBACK FORCE 'your local transactionID on this node';
SVRMGR> ROLLBACK FORCE '1.13.5197';
8、 清除dba_2pc_pending和dba_2pc_neighbers的相關(guān)記錄。一般分布式事務(wù)自動(dòng)恢復(fù)后,視圖內(nèi)容會(huì)自動(dòng)清除,如果是手工提交的事務(wù),則需要用dbms_transaction包手工清除,清除規(guī)則如下表所示:
確定何時(shí)能使用DBMS_TRANSACTION
Collecting
Purge_lost_db_entry(只有當(dāng)自動(dòng)回復(fù)不能解決事務(wù)時(shí))
Committed
Committed
Committed
Purge_lost_db_entry(只有當(dāng)自動(dòng)回復(fù)不能解決事務(wù)時(shí))
Forced
Commit
Committed
Purge_lost_db_entry(只有當(dāng)自動(dòng)回復(fù)不能解決事務(wù)時(shí))
Forced rollback
Purge_lost_db_entry(只有當(dāng)自動(dòng)回復(fù)不能解決事務(wù)時(shí))
Forced commit
Committed
手動(dòng)刪除不一致性﹐然后使用purge_mixed
Forced rollback
手動(dòng)刪除不一致性﹐然后使用purge_mixed
測試記錄
? 設(shè)置db1的commit_point_strength為1,db2的commit_point_strength為2,db2為commit point site。
? db1、db2上執(zhí)行100次insert循環(huán),每次循環(huán)用分布式事務(wù)插入db1和db2中的測試表。中間reboot db2服務(wù)器。此時(shí)db1對測試表的查詢出現(xiàn)以下錯(cuò)誤:
SQL> select count(1) from temp.my_table;
select count(1) from temp.my_table
*
ERROR at line 1:
ORA-01591: lock held by in-doubt distributed transaction 7.30.7415
[oracle@db2 bdump]$ tail -f alert_ntespay.log
Tue Mar 4 14:14:28 2008
DISTRIB TRAN 1234.4F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
is local tran 7.30.7415 (hex=07.1e.1cf7)
insert pending prepared tran, scn=934346533 (hex=0.37b0ff25)
db1中分布式事務(wù)相關(guān)的2個(gè)視圖內(nèi)容如下:
select a.* from dba_2pc_pending a where LOCAL_TRAN_ID='7.30.7415';
LOCAL_TRAN_ID GLOBAL_TRAN_ID STATE MIXED ADVICE TRAN_COMMENT FAIL_TIME FORCE_TIME RETRY_TIME OS_USER OS_TERMINAL HOST DB_USER COMMIT#
1 7.30.7415 4660.4F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 prepared no 2008-3-4 14:14:28 2008-3-4 14:22:56 zhenxingzhai ZHAIZHENXING NETEASE/ZHAIZHENXING 934346533
其中,
state有以下幾種狀態(tài):
Collecting, prepared, committed, forced commit, or forced rollback
mixed表示是否部分提交,部分回滾
advice:
C
for commit,
R
for rollback, else
NULL
select a.* from dba_2pc_neighbors a where LOCAL_TRAN_ID='7.30.7415';
LOCAL_TRAN_ID IN_OUT DATABASE DBUSER_OWNER INTERFACE DBID SESS# BRANCH
1 7.30.7415 in NULLjavaxa.oracle.com TEMP N javaxa_orcl 1 01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
此視圖說明了數(shù)據(jù)源1的輸入連接信息。因?yàn)閿?shù)據(jù)源2不是通過dblink連接的,以此沒有出現(xiàn)它的記錄。
? db2重啟后查詢my_tab:
SQL> select count(1) from my_tab;
COUNT(1)
----------
75
? 因?yàn)閐b2中dba_2pc_pending和dba_2pc_neighbers中沒有記錄,并且db2為commit point site,沒有記錄意味著沒有進(jìn)行任何操作,所以db1應(yīng)該和db2一樣,進(jìn)行強(qiáng)制rollback。
SQL> conn / as sysdba
Connected.
SQL> rollback force '7.30.7415';
Rollback complete.
SQL> select count(12) from temp.my_table;
COUNT(12)
----------
75
db1的alert日志中顯示了可疑事務(wù)的回滾過程:
Tue Mar 4 15:14:31 2008
DISTRIB TRAN 1234.4F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
is local tran 7.30.7415 (hex=07.1e.1cf7)
change pending prepared tran, scn=934346533 (hex=0.37b0ff25)
to pending forced rollback tran, scn=934346533 (hex=0.37b0ff25)
? 回滾后,兩個(gè)視圖中的狀態(tài)更改為如下:
select a.* from dba_2pc_pending a where LOCAL_TRAN_ID='9.33.5992';
LOCAL_TRAN_ID GLOBAL_TRAN_ID STATE MIXED ADVICE TRAN_COMMENT FAIL_TIME FORCE_TIME RETRY_TIME OS_USER OS_TERMINAL HOST DB_USER COMMIT#
1 7.30.7415 4660.4F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 forced rollback no 2008-3-4 14:14:28 2008-3-4 15:14:31 2008-3-4 15:20:07 zhenxingzhai ZHAIZHENXING NETEASE/ZHAIZHENXING 934346533
select a.* from dba_2pc_neighbors a where LOCAL_TRAN_ID='9.33.5992';
LOCAL_TRAN_ID IN_OUT DATABASE DBUSER_OWNER INTERFACE DBID SESS# BRANCH
1 7.30.7415 in NULLjavaxa.oracle.com TEMP N javaxa_orcl 1 01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
? 去除dba_2pc_pending和dba_2pc_ neighbors中的記錄:
(1) Disable分布式恢復(fù)
SQL> ALTER SYSTEM DISABLE DISTRIBUTED RECOVERY;
System altered.
(2)Puege(清空)in-doubt transaction entry:
SQL> exec DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('7.30.7415');
PL/SQL procedure successfully completed.
(3)commit;
(4)然后enable 分布式恢復(fù):
SQL> ALTER SYSTEM ENABLE DISTRIBUTED RECOVERY;
分布式事務(wù)相關(guān)資料
Note:1012842.102
Note:100664.1
Note:274321.1
聯(lián)系客服