ITPub博客

首页 > Linux操作系统 > Linux操作系统 > ORA-01591错误与分布式事务

ORA-01591错误与分布式事务

原创 Linux操作系统 作者:realkid4 时间:2011-05-20 16:06:19 0 删除 编辑

 

下午,一个开发组长过来找到笔者,说一个数据库表被锁定,不能修改数据。开始以为是简单的数据表锁定,开发阶段由于工具使用的原因,经常发生锁表的事件。查找锁定对象,定位锁定人和机器之后,就可以了。

 

1、问题现象

 

但是实际情况,完全出乎笔者的想法。检查一般对象数据表锁定,只需要检查v$locked_objectv$transaction视图,就可以定位到具体人。但是检查之后的结果如下:

 

 

SQL> select * from v$locked_object;

    XIDUSN    XIDSLOT     XIDSQN  OBJECT_ID SESSION_ID

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

 

SQL> select * from v$transaction;

ADDR                 XIDUSN    XIDSLOT     XIDSQN  

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

 

 

 

两个关键视图中,没有锁定的对象,也没有正在进行没有提交的事务。那是不是没有锁定呢?尝试对数据表加锁。

 

 

SQL> select * from nbs_common.inc_inputlog for update;

select * from nbs_common.inc_inputlog for update

 

ORA-01591: 锁被未决分布式事务处理 4.30.31555 持有

 

SQL> select count(*) from nbs_common.inc_inputlog;

  COUNT(*)

----------

       426

 

 

 

系统没有像一般阻塞那样等待,而是报错Ora-01591。并且提示锁被一个分布式事务持有,不能实现加锁操作。

 

看来是一个没有见到过的新错误。

 

2、分析问题

 

Ora-01591错误究竟是什么呢?我们使用oerr工具查看该错误编号,看看有没有值得关注的信息。

 

 

[oracle@bspdev ~]$ oerr ora 01591

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$),查看是否存在这种情况。

 

 

SQL> select * from DBA_2PC_PENDING;

 

LOCAL_TRAN_ID    GLOBAL_TRAN_ID                       STATE           

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

4.30.31555   096044365.31302E312E33392E38392E746D30303034313030303237   Pepared

 

(篇幅原因,有省略……

 

果然,当前存在一个阻塞分布式事务,处在prepared状态。

 

3、知识介绍

 

现代数据库系统往往伴随着复杂的结构和环境,其中分布式数据库组成是一个重要方面。系统后台的数据库系统不再是由单个数据构成,而是由多台独立数据库、甚至是多台异构数据库构成。这种情况下,分布式事务就是开发设计人员不能不面对的一个难题。

 

处理分布式事务的方案,有两种趋势。其一是借助数据库自身的分布式处理能力,如Oracle的分布式二阶段提交模型,进行多个数据库的分布式事务同步。其二是将分布式事务处理权交付给应用中间层,让应用去处理分布式事务问题。

 

 

进行分布式事务的时候,使用的“二阶段提交”模型,大致分为几个过程。(参考:http://blog.itpub.net/post/38439/477038

 

ü         Prepare阶段:多个数据库的commit_point_strength进行比较,确定出一个数据库作为commit point site。由全局协调者(Global Coordinator)通知除了commit point site外所有节点准备好commitrollback。同时,各节点对事务相关数据表加锁。之后,各个节点通知全局协调者自己的SCN,选择最大的那个SCN作为当前事务的SCN注意,从此刻开始,除了commit point site外,其他节点均进入in_double状态;

ü         Commit阶段:全局协调者将确定好的最大SCN通知给commit point site,授权该节点进行commit操作。Commit point site进行事务commit/rollback之后,通知全局协调者事务完成。全局协调者通知其他所有节点进行commit操作;

ü         Forget阶段:当各个节点结束事务之后,通知commit point site当前事务已经完成。当全部都完成了,commit point site开始清理分布式事务信息,然后通知全局协调者清理信息。最后全局协调者将最后清理掉本地的事务信息;

 

 

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

 

4、问题解决

 

对于这个事务,只能通过连接网络或者强制提交回退事务来结束。我们可以使用commit force或者rollback force来进行处理。

 

 

SQL> rollback force '4.30.31555';

 

Rollback complete

 

 

Rollback force参数是DBA_2PC_PENDING中记录本地事务信息的编号。

 

此时,再次查看数据。

 

 

SQL> select * from DBA_2PC_PENDING;

 

LOCAL_TRAN_ID    GLOBAL_TRAN_ID                           STATE  

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

4.30.31555  096044365.31302E312E33392E38392E746D30303034313030303237 forced rollback   

 

 

此时,该事务状态已经变化为forced rollback。已经强制回退。

 

 

SQL> select seq_number from nbs_common.inc_inputlog where rownum<2 for update;

 

    SEQ_NUMBER

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

             2

 

 

 

5、结论

 

这个故障解决,使我获取到如下认识:

 

ü         系统一旦涉及到分布式数据库,整体的复杂性就要提升很多。所以,要对分布式事务处理技术有非常成熟的认识和理解,而且要经过严格的测试;

ü         锁表的现象多种,不同事务类型,查看信息的方式有所差异;

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17203031/viewspace-695840/,如需转载,请注明出处,否则将追究法律责任。

下一篇: 说说函数索引
请登录后发表评论 登录
全部评论
求道~

注册时间:2010-11-30

  • 博文量
    545
  • 访问量
    7677167