【DB笔试面试691】在Oracle中,分布式事务ORA-01591错误如何解决?


题目 部分

在Oracle中,分布式事务ORA-01591错误如何解决?

     

答案部分

1、故障环境介绍

项目

数据库

DB类型

RAC

DB版本

11.2.0.3

DB存储

ASM

OS版本及kernel版本

AIX 64位 6.1.0.0

2、故障发生现象及报错信息

有同事发来错误,截图如下:

执行一个UPDATE语句的时候报ORA-01591的错误。

3、故障分析及解决过程

这个错误是由于分布式事务引起,而不是普通的锁引起的。若检查一般对象数据表锁定,则只需要检查V$LOCKED_OBJECT和V$TRANSACTION视图,就可以定位到具体的SQL语句和操作人等信息,但是检查之后的结果如下:

1SYS@oraLHR12> SELECT * FROM GV$LOCKED_OBJECT;
2no rows selected
3SYS@oraLHR12> SELECT * FROM GV$TRANSACTION;
4no rows selected

两个关键视图中,没有锁定的对象,也没有正在进行未提交的事务。那是不是没有锁定呢?或者锁已经释放了,重新尝试对数据表加锁,如下所示:

1SYS@oraLHR12> SELECT * FROM LHR.LHRBOKBAL FOR UPDATE;
2select * from LHR.LHRBOKBAL for update
3                   *
4ERROR at line 1:
5ORA-01591: lock held by in-doubt distributed transaction 20.13.14721
6SYS@oraLHR12> SELECT COUNT(1) FROM LHR.LHRBOKBAL;
7  COUNT(1)
8----------
9  30998411

系统没有像一般阻塞那样等待,而是报错ORA-01591的错误,并且提示锁被一个分布式事务持有,不能实现加锁操作。那么ORA-01591错误究竟是什么错误呢?可以使用Oracle提供的oerr工具查看该错误编号,如下所示:

 1root@ZFLHRRSP:/# oerr ora 1591
201591, 00000, "lock held by in-doubt distributed transaction %s"
3// *Cause:  Trying to access resource that is locked by a dead two-phase commit
4//          transaction that is in prepared state.
5// *Action: DBA should query the pending_trans$ and related tables, and attempt
6//          to repair network connection(s) to coordinator and commit point.
7//          If timely repair is not possible, DBA should contact DBA at commit
8//          point if known or end user for correct outcome, or use heuristic
9//          default if given to issue a heuristic commit or abort command to
10//          finalize the local portion of the distributed transaction.
11

简单的说,01591错误的原因是该对象被一个处在“IN-DOUBT”状态的分布式事务锁定。分布式事务使用的是“two-phase commit”二阶段提交技术。解决该问题的方法就是查看内部表PENDING_TRANS$,确定分布式事务信息。这种状态的事务主要是由于在进行分布式事务时候,发生网络突发中断的情况,引起分布式事务无法正常结束,等待中断节点的事务响应。于是,各节点的事务所锁定的表就不会被释放掉。

此时,检查视图DBA_2PC_PENDING(或者基表PENDING_TRANS$),查看是否存在这种情况。

果然,当前存在一个阻塞分布式事务,处在prepared状态。当前问题,主要是源于在进入prepared阶段之后,发生了网络中断的现象,引起COMMIT的阶段不能等待到事务信息。所以,才会一直处在Prepared状态,数据表也就不会进行释放。

对于这个事务,只能通过连接网络或者强制提交回退事务来结束。可以使用COMMIT FORCE或者ROLLBACK FORCE来进行处理,在这里,进行回滚操作,如下所示:

1SYS@oraLHR12> ROLLBACK FORCE '20.13.14721';
2Rollback complete.

ROLLBACK FORCE的参数是DBA_2PC_PENDING中记录本地事务信息的编号即LOCAL_TRAN_ID。

此时,再次查看数据。

此时,该事务状态已经变化为forced rollback表示已经强制回退,此时再次尝试锁定表操作:

116:25:31 SQL> SELECT * FROM LHR.LHRBOKBAL FOR UPDATE;
2CURRENCY
3--------
4001

可以看出已经不报错了,可以正常执行。

& 说明:

有关该案例的更多内容可以参考我的BLOG:http://blog.itpub.net/26736162/viewspace-2122999/

 

本文选自《Oracle程序员面试笔试宝典》,作者:小麦苗

---------------优质麦课------------

详细内容可以添加麦老师微信或QQ私聊。

About Me:小麦苗

● 本文作者:小麦苗,只专注于数据库的技术,更注重技术的运用

● 作者博客地址:http://blog.itpub.net/26736162/abstract/1/

● 本系列题目来源于作者的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解

● 版权所有,欢迎分享本文,转载请保留出处

● QQ:646634621  QQ群:618766405

● 提供OCP、OCM和高可用部分最实用的技能培训

● 题目解答若有不当之处,还望各位朋友批评指正,共同进步

DBA宝典

长按下图识别二维码或微信扫描下图二维码来关注小麦苗的微信公众号:xiaomaimiaolhr,学习最实用的数据库技术。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小麦苗DBA宝典

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值