oracle ORA-01591锁被未决分布式事务处理
此种情况就是在本地执行commit以后,此时远端库还没有完全commit,此时网络中断,导致本地库该表是commit状态,但是远端库还是prepare状态,一般来讲,此时如果源端得到的事务信息是全的,那么数据库不需要人为干预,能够自动根据事务信息进行提交操作,但是出现这个问题的时候,基本就表示提交的事务信息不足以让远端库执行提交操作,所以此时这种事务就需要人为干预了。– 可根据异步transact
概念:
大意就是,通过dblink连接另一个数据库的表是,对另一个数据库的表进行dml操作,同时也可能在同一个事务中对本库中的本地表做事务提交操作,那么对于dblink的表,需要确保远端的数据库也要提交,那么在本地像远端确认提交的时候,先由本地库发一个prepare的确认信息,远端回复prepare了以后,本地在执行commit信息;此种情况就是在本地执行commit以后,此时远端库还没有完全commit,此时网络中断,导致本地库该表是commit状态,但是远端库还是prepare状态,一般来讲,此时如果源端得到的事务信息是全的,那么数据库不需要人为干预,能够自动根据事务信息进行提交操作,但是出现这个问题的时候,基本就表示提交的事务信息不足以让远端库执行提交操作,所以此时这种事务就需要人为干预了。
视图:
dba_2pc_pending
dba_2pc_neighbors
1.查看
select LOCAL_TRAN_ID,GLOBAL_TRAN_ID,STATE,FAIL_TIME from dba_2pc_pending;
或者查*,更全
1.collecting:在收集数据过程中,产生异常
解决方法:
execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘11.4.419599’);
commit;
2.prepared: 在接受到异步commit/rollback指令前, 产生异常
解决方法:
rollback force tran_id
commit force tran_id; – 可根据异步transaction的状况决定使用方法。
拼接:
select 'rollback force ''' || LOCAL_TRAN_ID || ''';' || chr(10) ||
'execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(''' || LOCAL_TRAN_ID
|| ''');' || chr(10) || 'commit;' from DBA_2PC_PENDING;
3.forced rollback: 在使用rollback force出现
解决方法:
execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘11.4.419599’);
commit;
4.forced commit:在使用commit force出现
解决方法:
execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘11.4.419599’);
commit;
2.prepared解决不了的情况
查询该事务表是否有活动事务
SELECT ktuxeusn,
ktuxeslt,
ktuxesqn,
ktuxesta status,
ktuxecfl flags
FROM x$ktuxe
WHERE ktuxesta != 'inactive'
AND ktuxeusn = 11
AND ktuxeslt = 4
AND ktuxesqn = 419599;
2.1如果没有活动事务
set transaction use rollback segment SYSTEM;
delete from sys.pending_trans$ where local_tran_id ='11.4.419599' ;
delete from sys.pending_sessions$ where local_tran_id = '11.4.419599';
delete from sys.pending_sub_sessions$ where local_tran_id = '11.4.419599';
commit;
2.2如果有活动事务
尝试purge失败
execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘11.4.419599’);
commit;
删除数据字典中分布式事务信息
delete from sys.pending_trans$ where local_tran_id = '11.4.419599';
delete from sys.pending_sessions$ where local_tran_id = '11.4.419599';
delete from sys.pending_sub_sessions$ where local_tran_id ='11.4.419599';
commit;
禁用自动分布式恢复
alter system disable distributed recovery;
根据事务id插入分布式信息(信息随意,只是为了后面回滚使用)
INSERT INTO pending_trans$
(local_tran_id,
global_tran_fmt,
global_oracle_id,
state,
status,
session_vector,
reco_vector,
type#,
fail_time,
reco_time)
VALUES ( '11.4.419599', /* <== Replace this with your local tran id */
306206,
'123.12345.1.2.3',
'prepared',
'p',
Hextoraw('00000001'),
Hextoraw('00000000'),
0,
sysdate,
sysdate );
INSERT INTO pending_sessions$
VALUES ( '11.4.419599',/* <==replace only this with your local tran id */
1,
Hextoraw('05004f003a1500000104'),
'c',
0,
30258592,
'',
146 );
commit ;
回滚事务
rollback force ‘11.4.419599’;
重新启用自动分布式事务恢复
alter system enable distributed recovery;
再次查看state,已经不是prepared
select LOCAL_TRAN_ID,GLOBAL_TRAN_ID,STATE,FAIL_TIME from dba_2pc_pending where LOCAL_TRAN_ID='11.4.419599';
清理没用的事务信息
exec dbms_transaction.purge_lost_db_entry(‘11.4.419599’);
解决
3.分布式事务存在,dba_2pc(pending表)视图中没有数据
遇到ORA-2054, ORA-1591等错误,但是dba_2pc_pending没记录。
这种情况,commit force还是rollback force都会报
ORA-02058: no prepared transaction found with ID 10.20.360
一样的方式,将基表数据补齐。
1.dba_2pc_pending是否没记录
select LOCAL_TRAN_ID,GLOBAL_TRAN_ID,STATE,FAIL_TIME from dba_2pc_pending;
2.确认该事务表是否有活动事务
SELECT ktuxeusn,
ktuxeslt,
ktuxesqn,
ktuxesta status,
ktuxecfl flags
FROM x$ktuxe
WHERE ktuxesta != 'inactive'
AND ktuxeusn = 11
AND ktuxeslt = 4
AND ktuxesqn = 419599;
3.禁用自动分布式恢复
alter system disable distributed recovery;
4.根据事务id插入分布式信息(信息随意,只是为了后面回滚使用)
INSERT INTO pending_trans$
(local_tran_id,
global_tran_fmt,
global_oracle_id,
state,
status,
session_vector,
reco_vector,
type#,
fail_time,
reco_time)
VALUES ( '11.4.419599', /* <== Replace this with your local tran id */
306206,
'123.12345.1.2.3',
'prepared',
'p',
Hextoraw('00000001'),
Hextoraw('00000000'),
0,
sysdate,
sysdate );
INSERT INTO pending_sessions$
VALUES ( '11.4.419599',/* <==replace only this with your local tran id */
1,
Hextoraw('05004f003a1500000104'),
'c',
0,
30258592,
'',
146 );
commit ;
5.回滚事务
rollback force ‘11.4.419599’;
6.重新启用自动分布式事务恢复
alter system enable distributed recovery;
7.再次查看state,已经不是prepared
select LOCAL_TRAN_ID,GLOBAL_TRAN_ID,STATE,FAIL_TIME from dba_2pc_pending where LOCAL_TRAN_ID='11.4.419599';
8.清理没用的事务信息
exec dbms_transaction.purge_lost_db_entry(‘11.4.419599’);
解决
更多推荐
所有评论(0)