【故障處理】分佈式事務ORA-01591錯誤解決數據庫
各位技術愛好者,看完本文後,你能夠掌握以下的技能,也能夠學到一些其它你所不知道的知識,~O(∩_∩)O~:瀏覽器
① 分佈式事務的簡單概念服務器
② ORA-01591錯誤解決微信
Tips:網絡
① 本文在ITpub(http://blog.itpub.net/26736162)、博客園(http://www.cnblogs.com/lhrbest)和微信公衆號(xiaomaimiaolhr)有同步更新分佈式
② 文章中用到的全部代碼,相關軟件,相關資料請前往小麥苗的雲盤下載(http://blog.itpub.net/26736162/viewspace-1624453/)ide
③ 若文章代碼格式有錯亂,推薦使用搜狗、360或QQ瀏覽器,也能夠下載pdf格式的文檔來查看,pdf文檔下載地址:http://blog.itpub.net/26736162/viewspace-1624453/,另外itpub格式顯示有問題,能夠去博客園地址閱讀svg
④ 本篇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皆可,您的批評指正是我寫做的最大動力。
項目 |
source db |
db 類型 |
RAC |
db version |
11.2.0.3 |
db 存儲 |
ASM |
OS版本及kernel版本 |
AIX 64位 6.1.0.0 |
有同事發來錯誤:
執行一個update語句的時候報錯ORA-01591的錯誤。
這個錯誤是因爲分佈式事務引發,而不是普通的鎖引發的,檢查通常對象數據表鎖定,只須要檢查v$locked_object和v$transaction視圖,就能夠定位到具體的SQL語句和操做人等信息,可是檢查以後的結果以下:
SYS@ora LHR12> select * from gv$locked_object;
no rows selected
SYS@ora LHR12> select * from gv$transaction;
no rows selected
兩個關鍵視圖中,沒有鎖定的對象,也沒有正在進行沒有提交的事務。那是否是沒有鎖定呢?或者鎖已經釋放了,咱們嘗試對數據表加鎖:
SYS@ora LHR12> 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@ora LHR12> select count(1) from LHR.LHRBOKBAL;
COUNT(1)
----------
30998411
系統沒有像通常阻塞那樣等待,而是報錯ORA-01591的錯誤,而且提示鎖被一個分佈式事務持有,不能實現加鎖操做,那麼ORA-01591錯誤到底是什麼呢?咱們使用oerr工具查看該錯誤編號,看看有沒有值得關注的信息。
root@ZF LHRRSP:/# 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
能夠看出已經不報錯了,能夠正常執行。
分佈式事務,簡單來講,是指一個事務在本地和遠程執行,本地須要等待確認遠程的事務結束後,進行下一步本地的操做。如經過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恢復自動解決分佈事務。
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;
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’表示本地節點正在通知遠程節點﹐說它已準備好。 |