如何处理ORA-01591 错误?

Posted diuxie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何处理ORA-01591 错误?相关的知识,希望对你有一定的参考价值。

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和www.pizei.comrollback。现在我们尝试结束这个事务:通过x$ktuxe这个基表,我们看到确实存在这个事务,而且是prepared状态。

此时,我们基本清楚了这个问题的原因:当一个分布式事务死掉时,由于该事务没有正常结束,导致事务持有的锁一直没有释放,所以在访问这个事务涉及的资源时,申请不到锁资源,所以报ORA-01591。由于是分布式事务,当在dba_2pc_pending中查询不到事务信息时,我们是无法通过commit或者rollback结束该事务。

所以,我们目前的任务是模拟出这个分布式事务。由于dba_2pc_pending试图是依赖于pending_trans$这个表,同时事务是与session关联在一起的,所以我们需要手工往pending_trans$和pending_sessions$两个表中插入数据。

以上是关于如何处理ORA-01591 错误?的主要内容,如果未能解决你的问题,请参考以下文章

ora-01591:锁被未分布式事物处理/Distrib tran

处理 Mongoose 验证错误——在哪里以及如何处理?

如何处理错误?

处理包/模块中的错误时如何处理Python异常

如何处理 ValueError:分类指标无法处理多标签指标和多类目标错误的混合

ConnectionError:如何处理这个错误?