轉載ORA-01591錯誤故障處理
ORA-01591錯誤故障處理
摘要:
在訪問某些表的特定行時報ORA-01591錯誤
select
* from BF_INCOME_EXPENSES_T
where
account_id = 36816153
and
user_id = 39964213
and
city_code = '185'
ORA-01591:
鎖定已被有問題的分配事務處理72.0.1608712掛起
SQL>
select count(*) from UNITELE.BI_MQSYNC_SOURCE_CONTROL_T1;
ORA-01591:
鎖定已被有問題的分配事務處理72.0.1608712掛起
由於該表是業務關鍵表,部分前臺業務受到影響。
關鍵詞:ORA-01591
DBA_2PC_PENDING 分散式事務
1.故障分析
首先,在遇到ORA錯誤時,我們不可能知道每個ORA錯誤都是什麼意思,所以透過oracle的聯機文件查錯誤的cause和action可以讓我們初步瞭解該錯誤。
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.
Oracle對ORA-01591錯誤的描述是"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’該錯誤是由訪問一個處於prepared狀態的二階段事務所持有鎖的資源造成的。
下面簡單介紹一下分散式事務。
分散式事務,簡單來說,是指一個事務在本地和遠端執行,本地需要等待確認遠端的事務結束後,進行下一步本地的操作。如透過dblink
update遠端資料庫的一行記錄,如果在執行過程中網路異常,或者其他事件導致本地資料庫無法得知遠端資料庫的執行情況,此時就會發生in doublt的報錯。此時需要dba介入,且需要分多種情況進行處理。
分散式事務的,會經歷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清除分散式事務資訊。
有關分散式事務的詳細資訊請參閱oracle聯機文件.
當前的分散式事務處於Two-Phase
Commit機制中的prepared階段,這個階段事務已經在表上加鎖了,現在我們要訪問這些表,但事務沒有結束,一直持有鎖,導致訪問資源失敗報ORA-01591。(在這裡需要指出:分散式事務所持有的鎖之所以堵塞讀操作,是因為oralce不知道該顯示哪個版本的資料)
如果結束這個事務,那相應的鎖也會釋放,這樣就能解決這個問題。我們知道要結束一個事務有兩種辦法:commit和rollback。現在我們嘗試結束這個事務:
commit force
'72.0.1608712';
ORA-02058: no
prepared transaction found with ID 72.0.1608712
報錯並沒有發現prepared狀態的事務,由於該事務是分散式事務,我們首先想到的是dba_2pc_pending這個試圖
SQL> select
* from dba_2pc_pending;
no
rows selected
該試圖並沒有查到資訊,所以我們無法用commit force結束這個分散式事務,那麼現在我們檢視是否存在該事務,透過實際報錯,我們可以清晰的看到事務號為72.0.1608712,該事務在72號回滾段的0號事務槽上並且序列號是1608712,這時查詢一個基表x$ktuxe,看看72號回滾段上是否有該事務。
SQL> SELECT
KTUXEUSN, KTUXESLT, KTUXESQN, /* Transaction ID */
2
KTUXESTA
Status,
3
KTUXECFL
Flags
4
FROM x$ktuxe
5
WHERE ktuxesta!='INACTIVE'
6
AND ktuxeusn=
72;
KTUXEUSN
KTUXESLT KTUXESQN STATUS FLAGS
----------
---------- ---------- ----------------
------------------------
72 0
1608712 PREPARED SCO|COL|REV|DEAD
透過x$ktuxe這個基表,我們看到確實存在這個事務,而且是prepared狀態。
此時,我們基本清楚了這個問題的原因:當一個分散式事務死掉時,由於該事務沒有正常結束,導致事務持有的鎖一直沒有釋放,所以在訪問這個事務涉及的資源時,申請不到鎖資源,所以報ORA-01591。由於是分散式事務,當在dba_2pc_pending中查詢不到事務資訊時,我們是無法透過commit或者rollback結束該事務。
所以,我們目前的任務是模擬出這個分散式事務。由於dba_2pc_pending試圖是依賴於pending_trans$這個表,同時事務是與session關聯在一起的,所以我們需要手工往pending_trans$和pending_sessions$兩個表中插入資料。
2.故障處理
SQL> alter
system disable distributed recovery;
系統已更改。
SQL> insert
into pending_trans$ (
2
LOCAL_TRAN_ID,
3
GLOBAL_TRAN_FMT,
4
GLOBAL_ORACLE_ID,
5
STATE,
6 STATUS,
7
SESSION_VECTOR,
8
RECO_VECTOR,
9
TYPE#,
10
FAIL_TIME,
11
RECO_TIME)
12
values( '72.0.1608712',
13
306206,
14
'XXXXXXX.12345.1.2.3',
15
'prepared','P',
16
hextoraw( '00000001' ),
17
hextoraw( '00000000' ),
18
0, sysdate, sysdate );
已建立 1 行。
SQL> insert
into pending_sessions$
2
values(
'72.0.1608712',
3
1, hextoraw('05004F003A1500000104'),
4
'C', 0, 30258592, '',
5
146
6
);
已建立 1 行。
SQL>
commit;
提交完成。
SQL> alter
system enable distributed recovery;
系統已更改。
此時,查詢dba_2pc_pending發現已有該事務,並且狀態是我們模擬出的prepared狀態
SQL> select
* from dba_2pc_pending;
LOCAL_TRAN_ID GLOBAL_TRAN_ID STATE MIX A TRAN_COMMENTFAIL_TIME FORCE_TIME RETRY_TIME OS_USER
OS_TERMINAL HOST
DB_USER
COMMIT#
----------------
72.0.1608712 XXXXXXX.12345.1.2.3 prepared no12-11月-08
12-11月-08
此時我們結束這個事務
SQL> COMMIT
FORCE '72.0.1608712';
提交完成。
再次查詢dba_2pc_pending,發現事務是forced
commit狀態,該事務已經結束。
SQL> select
* from dba_2pc_pending;
LOCAL_TRAN_ID GLOBAL_TRAN_ID STATE MIX A TRAN_COMMENTFAIL_TIME FORCE_TIME RETRY_TIME OS_USER
OS_TERMINAL HOST
DB_USER COMMIT#
----------------
72.0.1608712 XXXXXXX.12345.1.2.3 forced commit
no12-11月-08 12-11月-08 12-11月-08
透過x$kutxe 查詢事務資訊,發現事務釋放了回滾段,事務已經結束。
SQL> SELECT
KTUXEUSN, KTUXESLT, KTUXESQN, /* Transaction ID */
2 KTUXESTA
Status,
3 KTUXECFL
Flags
4
FROM x$ktuxe
5
WHERE ktuxesta!='INACTIVE'
6 AND ktuxeusn=
72;
未選定行
此時,我們需要清除dba_2pc_pending中分散式事務的殘餘資訊
SQL> alter
session set "_smu_debug_mode"=4;
―― 在session級別設定回滾段處於手工管理模式,如果不設定這個引數,在回滾段自動管理模式下,清除事務資訊會報錯
會話已更改。
SQL>
execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('72.0.1608712'); ――用dbms包清除事務資訊
PL/SQL
過程已成功完成。
SQL> select
* from dba_2pc_pending;
未選定行
測試訪問業務表
SQL> select
count(*) from UNITELE.BI_MQSYNC_SOURCE_CONTROL_T1;
COUNT(*)
----------
367
問題解決。
其實,我在另外一個客戶處也碰到過類似問題,當時也是報ORA-01591,但是在dba_2pc_pending中可以查到prepared狀態的事務,此時只需要commit
force結束這個事務,並清除事務資訊就可以了。對於上面的案例,我懷疑開發商直接清除了分散式事務資訊,但是事務並沒有結束,導致鎖資源得不到釋放報ORA-01591。
總結:ORA-01591錯誤一般是由於分散式事務造成的,造成分散式事務失敗的原因主要是庫之間的網路突然中斷,造成兩個庫中的事務資訊不一致,所以會有殘餘的分散式事務資訊。此時,要針對不同的事務狀態做不同的處理。同時在遇到棘手的問題時,可以查詢metalink,該案例參考metalink文件:NOTE:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/48010/viewspace-1016050/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 轉載ORA-01591錯誤故障處理(ji)
- ORA-01591錯誤故障處理
- 【故障處理】分散式事務ORA-01591錯誤解決分散式
- 【故障處理】CRS-1153錯誤處理
- 【故障處理】ORA-19809錯誤處理
- 【故障處理】ORA-12162 錯誤的處理
- COM的錯誤處理 (轉)
- 使用PHP錯誤處理 (轉)PHP
- hbase 故障的處理方案。 (轉載文章)
- [轉] Scala Try 與錯誤處理
- Windows函式錯誤處理 (轉)Windows函式
- 錯誤處理
- 錯誤處理的一點思考 (轉)
- PHP 錯誤處理PHP
- php錯誤處理PHP
- Go 錯誤處理Go
- Swift錯誤處理Swift
- Zabbix錯誤處理
- mysqldump錯誤處理MySql
- 主從故障處理--session 級別引數複製錯誤Session
- latch: cache buffers chains故障處理總結(轉載)AI
- 錯誤處理:如何通過 error、deferred、panic 等處理錯誤?Error
- 【故障處理】ORA-31600和ORA-04063錯誤
- 【故障處理】Oracle10.2.0.3 ORA-3136 錯誤解決Oracle
- 【故障處理】修改maxuproc引數解決TNS-00519錯誤
- PHP錯誤處理和異常處理PHP
- go的錯誤處理Go
- Python錯誤處理Python
- ORA-01591錯誤與分散式事務分散式
- ORA-39700 with UPGRADE option錯誤的處理(轉)
- ORA-12516錯誤的處理(轉)
- 異常錯誤資訊處理
- PHP 核心特性 - 錯誤處理PHP
- 常用模組 PHP 錯誤處理PHP
- laravel9 錯誤處理Laravel
- 淺談前端錯誤處理前端
- Oracle異常錯誤處理Oracle
- ORACLE 異常錯誤處理Oracle