程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> 【故障處理】分布式事務ORA-01591錯誤解決,故障處理ora-01591

【故障處理】分布式事務ORA-01591錯誤解決,故障處理ora-01591

編輯:Oracle教程

【故障處理】分布式事務ORA-01591錯誤解決,故障處理ora-01591


【故障處理】分布式事務ORA-01591錯誤解決

1  BLOG文檔結構圖

 

 

 

2  前言部分

2.1  導讀和注意事項

各位技術愛好者,看完本文後,你可以掌握如下的技能,也可以學到一些其它你所不知道的知識,~O(∩_∩)O~:

① 分布式事務的簡單概念

        ② ORA-01591錯誤解決

  Tips:

① 本文在ITpub(http://blog.itpub.net/26736162)、博客園(http://www.cnblogs.com/lhrbest)和微信公眾號(xiaomaimiaolhr)有同步更新

② 文章中用到的所有代碼,相關軟件,相關資料請前往小麥苗的雲盤下載(http://blog.itpub.net/26736162/viewspace-1624453/)

③ 若文章代碼格式有錯亂,推薦使用搜狗、360或QQ浏覽器,也可以下載pdf格式的文檔來查看,pdf文檔下載地址:http://blog.itpub.net/26736162/viewspace-1624453/,另外itpub格式顯示有問題,可以去博客園地址閱讀

④ 本篇BLOG中命令的輸出部分需要特別關注的地方我都用灰色背景和粉紅色字體來表示,比如下邊的例子中,thread 1的最大歸檔日志號為33,thread 2的最大歸檔日志號為43是需要特別關注的地方;而命令一般使用黃色背景和紅色字體標注;對代碼或代碼輸出部分的注釋一般采用藍色字體表示。

  List of Archived Logs in backup set 11

  Thrd Seq     Low SCN    Low Time            Next SCN   Next Time

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

  1    32      1621589    2015-05-29 11:09:52 1625242    2015-05-29 11:15:48

  1    33      1625242    2015-05-29 11:15:48 1625293    2015-05-29 11:15:58

  2    42      1613951    2015-05-29 10:41:18 1625245    2015-05-29 11:15:49

  2    43      1625245    2015-05-29 11:15:49 1625253    2015-05-29 11:15:53

 

[ZHLHRDB1:root]:/>lsvg -o

T_XDESK_APP1_vg

rootvg

[ZHLHRDB1:root]:/>

00:27:22 SQL> alter tablespace idxtbs read write;

 

====》2097152*512/1024/1024/1024=1G 

 

本文如有錯誤或不完善的地方請大家多多指正,ITPUB留言或QQ皆可,您的批評指正是我寫作的最大動力。

 

 

3  故障分析及解決過程

 

3.1  故障環境介紹

 

項目

source db

db 類型

RAC

db version

11.2.0.3

db 存儲

ASM

OS版本及kernel版本

AIX 64位 6.1.0.0

 

3.2  故障發生現象及報錯信息

有同事發來錯誤:

 

 

執行一個update語句的時候報錯ORA-01591的錯誤。

 

3.3  故障分析及解決過程

這個錯誤是由於分布式事務引起,而不是普通的鎖引起的,檢查一般對象數據表鎖定,只需要檢查v$locked_object和v$transaction視圖,就可以定位到具體的SQL語句和操作人等信息,但是檢查之後的結果如下:

SYS@oraLHR12>  select * from gv$locked_object;

 

no rows selected

 

SYS@oraLHR12> select * from gv$transaction;

 

no rows selected

兩個關鍵視圖中,沒有鎖定的對象,也沒有正在進行沒有提交的事務。那是不是沒有鎖定呢?或者鎖已經釋放了,我們嘗試對數據表加鎖:

SYS@oraLHR12> select * from LHR.LHRBOKBAL for update;

select * from LHR.LHRBOKBAL for update

                   *

ERROR at line 1:

ORA-01591: lock held by in-doubt distributed transaction 20.13.14721

 

SYS@oraLHR12> select count(1) from LHR.LHRBOKBAL;

 

  COUNT(1)

----------

  30998411

 

 

系統沒有像一般阻塞那樣等待,而是報錯ORA-01591的錯誤,並且提示鎖被一個分布式事務持有,不能實現加鎖操作,那麼ORA-01591錯誤究竟是什麼呢?我們使用oerr工具查看該錯誤編號,看看有沒有值得關注的信息。

root@ZFLHRRSP:/# oerr ora 1591

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$),查看是否存在這種情況。

 

果然,當前存在一個阻塞分布式事務,處在prepared狀態。當前問題,主要是源於在進入prepared階段之後,發生了網絡中斷的現象,引起commit的階段不能等待到事務信息。所以,才會一直處在Prepared狀態,數據表也就不會進行釋放。

對於這個事務,只能通過連接網絡或者強制提交回退事務來結束。我們可以使用commit force或者rollback force來進行處理,這裡我們進行回滾操作:

SYS@oraLHR12> rollback force '20.13.14721';

 

Rollback complete.

 

SYS@oraLHR12>

Rollback force的參數是DBA_2PC_PENDING中記錄本地事務信息的編號即LOCAL_TRAN_ID。

 

此時,再次查看數據。

 

此時,該事務狀態已經變化為forced rollback表示已經強制回退,我們再次嘗試鎖定表操作:

16:25:31 SQL> select CURRENCY from tpcc.TPCCBOKBAL WHERE ROWNUM=1  for update;

CURRENCY

--------

001

Executed in 0.025 seconds

可以看出已經不報錯了,可以正常執行。

4  分布式事務相關知識點

分布式事務,簡單來說,是指一個事務在本地和遠程執行,本地需要等待確認遠程的事務結束後,進行下一步本地的操作。如通過dblink update遠程數據庫的一行記錄,如果在執行過程中網絡異常,或者其他事件導致本地數據庫無法得知遠程數據庫的執行情況,此時就會發生in doublt的報錯。此時需要dba介入,且需要分多種情況進行處理。

Oracle會自動處理分布事務,保證分布事務的一致性,所有站點全部提交或全部回滾。一般情況下,處理過程在很短的時間內完成,根本無法察覺到。

但是,如果在commit或rollback的時候,出現了連接中斷或某個數據庫 站點CRASH的情況,則提交操作可能會無法繼續,此時DBA_2PC_PENDING和DBA_2PC_NEIGHBORS中會包含尚未解決的分布事務。 對於絕大多數情況,當恢復連接或CRASH的數據庫重新啟動後,會自動解決分布式事務,不需要人工干預。只有分布事務鎖住的對象急需被訪問,鎖住的回滾段阻止了其他事務的使用,網絡故障或CRASH的數據庫的恢復需要很長的時間等情況出現時,才使用人工操作的方式來維護分布式事務。 手工強制提交或回滾將失去二層提交的特性,Oracle無法繼續保證事務的一致性,事務的一致性應由手工操作者保證

使用ALTER SYSTEM DISABLE DISTRIBUTED RECOVERY,可以使Oracle不再自動解決分布事務,即使網絡恢復連接或者CRASH的數據庫重新啟動。

ALTER SYSTEM ENABLE DISTRIBUTED RECOVERY恢復自動解決分布事務。

 

5  兩個重要的視圖

5.1  DBA_2PC_PENDING

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在分布式事務的每個節點都是相同的。

STATE

下圖表進行說明

MIXED

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

TRAN_COMMENT

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

Host

主機名

Commit#

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

 

DBA_2PC_PENDING的STATE列的說明

列值

說明

Connecting

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

Prepared

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

Commited

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

Forced commit

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

Forced abor(rollback)

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

 

SELECT * FROM DBA_2PC_PENDING;

 

 

5.2  DBA_2PC_NEIGHBORS

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

列名

說明

LOCAL_TRAN_ID

同上

IN_OUT

獲得事務為IN﹐送出事務為OUT

Database

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

DBuser_owner

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

INTERFACE

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

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

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

 

  About Me

..........................................................................................................................................................................................................                        

v 本文作者:小麥苗,只專注於數據庫的技術,更注重技術的運用

v 本文在ITpub(http://blog.itpub.net/26736162)、博客園(http://www.cnblogs.com/lhrbest)和個人微信公眾號(xiaomaimiaolhr)上有同步更新,推薦pdf文件閱讀或博客園地址閱讀

v QQ群:230161599 微信群:私聊

v 本文itpub地址: http://blog.itpub.net/26736162/viewspace-2122999/   博客園地址:http://www.cnblogs.com/lhrbest/p/5738544.html

v 本文pdf版:http://yunpan.cn/cdEQedhCs2kFz (提取碼:ed9b)

v 小麥苗分享的其它資料:http://blog.itpub.net/26736162/viewspace-1624453/

v 聯系我請加QQ好友(642808185),注明添加緣由

v 於 2016-08-02 09:00~2016-08-03 19:00 在中行完成

v 【版權所有,文章允許轉載,但須以鏈接方式注明源地址,否則追究法律責任】

..........................................................................................................................................................................................................

長按識別二維碼或微信客戶端掃描下邊的二維碼來關注小麥苗的微信公眾號:xiaomaimiaolhr,學習最實用的數據庫技術。

 

 

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved