oracle分佈式事務總結(轉)

oracle分佈式事務總結(轉)
基本概念

Local Coordinator:在分佈事務中,必須參考其它節點上的數據才能完成自己這部分操作的站點。

Global Coordinator:分佈事務的發起者,負責協調這個分佈事務。

Commit Point Site:在分佈事務中,首先執行COMMIT或ROLLBACK操作的站點。一般情況下,應該把存儲關鍵數據的站點作爲Commit Point Site。因爲Commit Point Site和其它站點不一樣,從來不會進入prepared狀態,所以不會存在IN-DOUBT事務。

可以設置初始化參數COMMIT_POINT_STRENGTH,在分佈式事務中,會根據這個值的大小來確定Commit Point Site,分佈事物的狀態信息也存在該數據庫中。一般將關鍵的數據庫作爲commit point site ,commit_point_strength值較高的數據庫爲commit point site,在分佈事物中最先提交

分佈式提交的3個階段

分佈事物的兩階段提交分三個過程:

1. 準備階段(PREPARE PHASE)

·本地數據庫Global Coordinator向其它數據庫發出COMMIT通知

·比較所有數據庫的SCN號,將最高的SCN號作爲分佈事物的全局SCN號

·所有數據庫寫在線日誌

·對分佈事物修改的表加分佈鎖,防止被讀寫

·各數據庫向Global Coordinator發出已經準備好的通知

所有參與分佈事物的數據庫必須經過上述準備,才能進入下一階段。

2. 提交階段(COMMIT PHASE)

·本地數據庫Global Coordinator通知commit point site首先提交。commit point site提交後,釋放其佔有的資源,通知Global Coordinator完成提交

·本地數據庫Global Coordinator通知其它數據庫提交

·提交節點在日誌中追加一條信息,表示分佈事物已經完成提交,並通知Global Coordinator。此時所有數據庫的數據保持了一致性。

3. 註銷階段(FORGET PHASE)

·本地數據庫Global Coordinator通知commit point site所有數據庫已經完成提交

·commit point site清除分佈事物的記錄和狀態信息,並通知Global Coordinator

·Global Coordinator清除本地分佈事物的記錄和狀態信息

此時分佈事物的兩階段提交全部完成。

如果兩階段提交完成之前,數據庫或網絡出現異常,應用就會報錯,分佈事物處於IN_DOUBT狀態。一旦數據庫或網絡恢復正常,系統(RECO PROCESS)會自動處理IN_DOUBT狀態的分佈事物。有些情況需要管理員手工處理IN_DOUBT狀態的分佈事物:

·IN_DOUBT狀態的分佈事物,將關鍵表鎖住,造成應用不能正常工作

兩個重要的視圖

DBA_2PC_PENDING:列出所有的懸而未決的事務﹐此視圖在末填入懸而未決的事務之前是空的﹐解決這後也被清空。
LOCAL_TRAN_ID


本地事務標識﹐格式爲integer.integer.ingeger。

當一個連接的local_tran_id和global_tran_id相同時﹐那麼該節點是該事務的全局協調器。

GLOBAL_TRAN_ID

全局事務標識,格式爲﹕global_db_name.db_hex_id.local_tran_id,其中db_hex_id是用來標識數據庫八字符的十六進制數﹐公共事各id在分佈式事務的每個節點都是相同的。

“YES”意味着一部分事務已經在一個節點上提交﹐而在另一個節點上被回滾。

TRAN_COMMENT

事務的註釋﹐或者如果使用了事務命名﹐當事各被提交時﹐事務的名字就會出現在此處

已提交的事務的全局提交數




DBA_2PC_PENDING的STATE列的說明 Connecting


通常情況下﹐只有全局協調器和本地協調器才使用這個條目﹐節點在能夠決定它是否能夠準備好之前﹐要收集來自於其它數據庫服務的信息。

節點已準好﹐可能或者也可能沒有將已準備好的消息通知本地協調器﹐但此時﹐該節點還沒有接收到提交的請求﹐仍保持着准許備好的狀態﹐控制着提交事務所必需的任何本地資源。

節點(任何類型)已經提交了事務﹐但該事務所包含的其它節點可能並沒有提交﹐也就是該事務在一個個或多個其它節點上仍然是懸而未決 。

Forced commit

DBA進行判斷後﹐可以強行提交未決的事務﹐如果一個事務由DBA在本地節點進行手動提交時﹐產生此項目

Forced abor(rollback)

DBA進行判斷後﹐可以強行回滾未決的事務﹐如果一個事務由DBA在本地節點進行手動回滾時﹐產生此項目



DBA_2PC_NEIGHBORS:列出所有獲得的(從遠程客戶)和送出的(給遠程服務器)懸而未決的事務﹐也表示該本地節點是不是事務的提交點站點。

LOCAL_TRAN_ID


對獲得事務來說指本地節點信息的客戶數據庫的名稱﹔對送出的事務來說指用於訪問遠程服務器上信息的數據庫鏈接的名稱

DBuser_owner

對獲得事務來說指遠程數據庫鏈接用於連接的本地賬戶﹔對於送出事務來說指該數據庫鏈接的擁有者。

INTERFACE

‘C’代表提交信息﹐’N’表示已準備好狀態的一條消息或是一條請求只讀提交的請求。

當’IN_OUT’爲OUT時﹐’C’表示該連接的遠程的站點是提交點站點,並且知道是提交還是中斷。’N’表示本地節點正在通知遠程節點﹐說它已準備好。

當’IN_OUT’爲IN時﹐‘C’表示本地節點或送出的遠程的一個數據庫是提交點站點﹐’N’表示本地節點正在通知遠程節點﹐說它已準備好。



處理懸掛事務的一般步驟

1、 檢查alert文件,發現類似下面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、 確認網絡是否正常、dblink是否valid、v$dblink和gv$dblink中查詢當前是否在使用分佈式事務。

3、 查詢視圖dba_2pc_pending,查詢懸掛事務信息:

SELECT LOCAL_TRAN_ID, GLOBAL_TRAN_ID, STATE, MIXED, HOST, COMMIT#

FROM DBA_2PC_PENDING

WHERE LOCAL_TRAN_ID = '??.';

如果沒有記錄,說明RECO進程已經自動處理了該事務。

4、 在所有節點上查詢視圖dba_2pc_neighbors

5、 得到所有節點的COMMIT_POINT_STRENGTH值,值最大的爲commit point site,即最早提交的點,如果懸掛事務發生在commit point site,則它的state決定了整個分佈式事務的狀態。懸掛事務是否應該commit force或者是rollback force,由此節點決定。

6、 檢查dba_2pc_pending的state列,如果是commited,意味着本地數據庫提交已經成功。其他節點需要根據本地事務號和最大的commit#進行強制提交。用法如下:

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外的其他狀態,則表明commit point site 沒有提交成功,分佈式事務需要強制回滾。這裏不再需要所有節點的最大commit#。用法如下:

SVRMGR> ROLLBACK FORCE 'your local transactionID on this node';

SVRMGR> ROLLBACK FORCE '1.13.5197';

8、 清除dba_2pc_pending和dba_2pc_neighbers的相關記錄。一般分佈式事務自動恢復後,視圖內容會自動清除,如果是手工提交的事務,則需要用dbms_transaction包手工清除,清除規則如下表所示:

確定何時能使用DBMS_TRANSACTION Collecting


Purge_lost_db_entry(只有當自動回覆不能解決事務時)

Committed

Committed

Committed

Purge_lost_db_entry(只有當自動回覆不能解決事務時)

Forced

Commit

Committed

Purge_lost_db_entry(只有當自動回覆不能解決事務時)

Forced rollback

Purge_lost_db_entry(只有當自動回覆不能解決事務時)

Forced commit

Committed

手動刪除不一致性﹐然後使用purge_mixed

Forced rollback

手動刪除不一致性﹐然後使用purge_mixed



測試記錄

¡ 設置db1的commit_point_strength爲1,db2的commit_point_strength爲2,db2爲commit point site。

¡ db1、db2上執行100次insert循環,每次循環用分佈式事務插入db1和db2中的測試表。中間reboot db2服務器。此時db1對測試表的查詢出現以下錯誤:

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中分佈式事務相關的2個視圖內容如下:

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有以下幾種狀態:

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

此視圖說明了數據源1的輸入連接信息。因爲數據源2不是通過dblink連接的,以此沒有出現它的記錄。

¡ db2重啓後查詢my_tab:

SQL> select count(1) from my_tab;

COUNT(1)

----------

75

¡ 因爲db2中dba_2pc_pending和dba_2pc_neighbers中沒有記錄,並且db2爲commit point site,沒有記錄意味着沒有進行任何操作,所以db1應該和db2一樣,進行強制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日誌中顯示了可疑事務的回滾過程:

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)

¡ 回滾後,兩個視圖中的狀態更改爲如下:

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分佈式恢復

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 分佈式恢復:

SQL> ALTER SYSTEM ENABLE DISTRIBUTED RECOVERY;

分佈式事務相關資料

Note:1012842.102

Note:100664.1

Note:274321.1

Note:126069.1

http://www.itk.ilstu.edu/docs/Oracle/server.101/b10739/ds_txns.htm#i1007721
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章