天天看點

texedo 分布式事務

1、問題現象

但是實際情況,完全出乎筆者的想法。檢查一般對象資料表鎖定,隻需要檢查v$locked_object和v$transaction視圖,就可以定位到具體人。但是檢查之後的結果如下:

SQL> select * from v$locked_object;

XIDUSN XIDSLOT XIDSQN OBJECT_ID SESSION_ID

---------- ---------- ---------- ---------- ----------

SQL> select * from v$transaction;

ADDR XIDUSN XIDSLOT XIDSQN

---------------- ---------- ---------- ----------

兩個關鍵視圖中,沒有鎖定的對象,也沒有正在進行沒有送出的事務。那是不是沒有鎖定呢?嘗試對資料表加鎖。

SQL> select * from nbs_common.inc_inputlog for update;

select * from nbs_common.inc_inputlog for update

ORA-01591:鎖被未決分布式事務處理4.30.31555持有

SQL> select count(*) from nbs_common.inc_inputlog;

COUNT(*)

----------

426

系統沒有像一般阻塞那樣等待,而是報錯Ora-01591。并且提示鎖被一個分布式事務持有,不能實作加鎖操作。

看來是一個沒有見到過的新錯誤。

2、分析問題

Ora-01591錯誤究竟是什麼呢?我們使用oerr工具檢視該錯誤編号,看看有沒有值得關注的資訊。

[oracle@bspdev ~]$ 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.

簡單的說,01591錯誤的原因是該對象被一個處在“in-doubt”狀态的分布式事務鎖定。分布式事務使用的是“two-phase commit”二階段送出技術。解決該問題的方法就是檢視内部表pending_trans$,确定分布式事務資訊。這種狀态的事務主要是由于在進行分布式事務時候,發生網絡突發中斷的情況,引起分布式事務無法正常結束,等待中斷節點的事務響應。于是,各節點的事務所鎖定的表就不會被釋放掉。

此時,我們檢查視圖DBA_2PC_PENDING(或者基表pending_trans$),檢視是否存在這種情況。

SQL> select * from DBA_2PC_PENDING;

LOCAL_TRAN_ID GLOBAL_TRAN_ID STATE

---------------------- ----------------------------------------------------- ----------------

4.30.31555 096044365.31302E312E33392E38392E746D30303034313030303237 Pepared

果然,目前存在一個阻塞分布式事務,處在prepared狀态。

3、知識介紹

現代資料庫系統往往伴随着複雜的結構和環境,其中分布式資料庫組成是一個重要方面。系統背景的資料庫系統不再是由單個資料構成,而是由多台獨立資料庫、甚至是多台異構資料庫構成。這種情況下,分布式事務就是開發設計人員不能不面對的一個難題。

處理分布式事務的方案,有兩種趨勢。其一是借助資料庫自身的分布式處理能力,如Oracle的分布式二階段送出模型,進行多個資料庫的分布式事務同步。其二是将分布式事務處理權傳遞給應用中間層,讓應用去處理分布式事務問題。

進行分布式事務的時候,使用的“二階段送出”模型,大緻分為幾個過程。

ü Prepare階段:多個資料庫的commit_point_strength進行比較,确定出一個資料庫作為commit point site。由全局協調者(Global Coordinator)通知除了commit point site外所有節點準備好commit和rollback。同時,各節點對事務相關資料表加鎖。之後,各個節點通知全局協調者自己的SCN,選擇最大的那個SCN作為目前事務的SCN;注意,從此刻開始,除了commit point site外,其他節點均進入in_double狀态;

ü Commit階段:全局協調者将确定好的最大SCN通知給commit point site,授權該節點進行commit操作。Commit point site進行事務commit/rollback之後,通知全局協調者事務完成。全局協調者通知其他所有節點進行commit操作;

ü Forget階段:當各個節點結束事務之後,通知commit point site目前事務已經完成。當全部都完成了,commit point site開始清理分布式事務資訊,然後通知全局協調者清理資訊。最後全局協調者将最後清理掉本地的事務資訊;

目前問題,主要是源于在進入prepared階段之後,發生了網絡中斷的現象,引起commit的階段不能等待到事務資訊。是以,才會一直處在Prepared狀态,資料表也就不會進行釋放。

4、問題解決

對于這個事務,隻能通過連接配接網絡或者強制送出回退事務來結束。我們可以使用commit force或者rollback force來進行處理。

SQL> rollback force '4.30.31555';

Rollback complete

Rollback force參數是DBA_2PC_PENDING中記錄本地事務資訊的編号。

此時,再次檢視資料。

---------------------- ----------------------------------------------------------

4.30.31555 096044365.31302E312E33392E38392E746D30303034313030303237forced rollback

此時,該事務狀态已經變化為forced rollback。已經強制回退。

SQL> select seq_number from nbs_common.inc_inputlog where rownum<2 for update;

SEQ_NUMBER

--------------

2

5、結論

這個故障解決,使我擷取到如下認識:

ü 系統一旦涉及到分布式資料庫,整體的複雜性就要提升很多。是以,要對分布式事務處理技術有非常成熟的認識和了解,而且要經過嚴格的測試;

ü 鎖表的現象多種,不同僚務類型,檢視資訊的方式有所差異;