ITPub博客

首页 > 数据库 > Oracle > [20181031]模拟ora-01591错误.txt

[20181031]模拟ora-01591错误.txt

原创 Oracle 作者:lfree 时间:2018-10-31 11:09:12 0 删除 编辑

[20181031]模拟ora-01591错误.txt


--//分布式事务使用dblink更新多个数据库的事务,最常见的ORA-01591错误.

$ 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.


--//通过简单的模拟产生这个错误.


1.环境:

--//客户端:

SCOTT@book> @ ver1

PORT_STRING                    VERSION        BANNER

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

x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production


SCOTT@book> create PUBLIC database link test033 connect to scott identified by btbtms using '192.168.100.33:1521/test:DEDICATED';

Database link created.


SCOTT@book> create table deptx as select * from deptx;

Table created.


SCOTT@book> select sysdate from dual@test033;

SYSDATE

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

2018-10-31 08:55:34

--//OK,连接没有问题.

SCOTT@book> commit;

Commit complete.


--//服务端:

SCOTT@test> @ &r/ver1

PORT_STRING                    VERSION        BANNER

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

x86_64/Linux 2.4.xx            10.2.0.4.0     Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi


SCOTT@test> create table depty as select * from dept;

Table created.


SCOTT@book> select * from deptx;

    DEPTNO DNAME          LOC

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

        10 ACCOUNTING     NEW YORK

        20 RESEARCH       DALLAS

        30 SALES          CHICAGO

        40 OPERATIONS     BOSTON


SCOTT@book> select * from depty@test033;

    DEPTNO DNAME          LOC

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

        10 ACCOUNTING     NEW YORK

        20 RESEARCH       DALLAS

        30 SALES          CHICAGO

        40 OPERATIONS     BOSTON


2.一些解析与说明:

--//这次不再使用alter system disable distributed recovery;.

--//"COMMIT COMMENT 'ORA-2PC-CRASH-TEST-N'"这个命令,是Oracle用来强制分布式事务失败,4代表非提交点的分布式事务失败在

--//prepare后。其它数值代表的意思如下:


1 Crash commit point after collect

2 Crash non-commit-point site after collect

3 Crash before prepare (non-commit-point site)

4 Crash after prepare (non-commit-point site)

5 Crash commit point site before commit

6 Crash commit point site after commit

7 Crash non-commit-point site before commit

8 Crash non-commit-point site after commit

9 Crash commit point site before forget

10 Crash non-commit-point site before forget


--//实际上COMMIT COMMENT 'ORA-2PC-CRASH-TEST-7'就应该模拟出来,测试看看.


3.测试:

SCOTT@book> update deptx         set loc = lower(loc) where deptno=10;

1 row updated.


SCOTT@book> update depty@test033 set loc = lower(loc) where deptno=20;

1 row updated.


SCOTT@book> COMMIT COMMENT 'ORA-2PC-CRASH-TEST-7';

COMMIT COMMENT 'ORA-2PC-CRASH-TEST-7'

*

ERROR at line 1:

ORA-02054: transaction 9.30.2968 in-doubt

ORA-02059: ORA-2PC-CRASH-TEST-7 in commit comment


SCOTT@book> @ &r/xid

XIDUSN_XIDSLOT_XIDSQN

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


no rows selected

--//已经没有事务.


SCOTT@book> select local_tran_id, GLOBAL_TRAN_ID, state from dba_2pc_pending;

no rows selected


SCOTT@book> select * from deptx where deptno=10;

    DEPTNO DNAME          LOC

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

        10 ACCOUNTING     new york


SCOTT@book> select * from depty@test033 where deptno=20;

    DEPTNO DNAME          LOC

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

        20 RESEARCH       dallas


--//这种方式不行.换1个方式测试.


4.测试连接异常中断:

--//客户端:

SCOTT@book> @ &r/xid

XIDUSN_XIDSLOT_XIDSQN

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

no rows selected


SCOTT@book> update deptx         set loc = upper(loc) where deptno=10;

1 row updated.


SCOTT@book> update depty@test033 set loc = upper(loc) where deptno=20;

1 row updated.


SCOTT@book> @ &r/spid

       SID    SERIAL# PROCESS                  SERVER    SPID       PID  P_SERIAL# C50

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

       274         19 28023                    DEDICATED 28024       21          8 alter system kill session '274,19' immediate;

--//当前连接进程号=28024.


--//服务端: (我以前提过v$session.process记录的是客户端进程号.)

SCOTT@test> select spid,program from v$process where addr in (select paddr from v$session where process=28024);

SPID   PROGRAM

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

12619  oracle@xxxx


# lsof -P -i -n |grep -e 12619 -e COMMAND

COMMAND     PID    USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME

oracle    12619  oracle   14u  IPv4 28066050      0t0  TCP 192.168.100.33:1521->192.168.100.78:16778 (ESTABLISHED)


--//也可以对上.

# kill -9 12619


SCOTT@book> commit ;

commit

*

ERROR at line 1:

ORA-02054: transaction 10.2.24501 in-doubt

ORA-03150: end-of-file on communication channel for database link

ORA-02063: preceding line from TEST033


SCOTT@book> @ &r/xid

XIDUSN_XIDSLOT_XIDSQN

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

no rows selected


SCOTT@book> select local_tran_id, GLOBAL_TRAN_ID, state from dba_2pc_pending;

no rows selected


--//这样也不行.


5.测试(服务端数据库异常关闭)


SCOTT@book>  @ &r/xid

XIDUSN_XIDSLOT_XIDSQN

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

no rows selected


SCOTT@book> update deptx         set loc = upper(loc) where deptno=10;

1 row updated.


SCOTT@book> update depty@test033 set loc = upper(loc) where deptno=20;

1 row updated.


--//在服务端异常关闭:

SYS@test> shutdown abort ;

ORACLE instance shut down.

--//补充说明:正常关闭shutdown immediate也是一样能演示这个问题.


SCOTT@book> commit ;

commit

*

ERROR at line 1:

ORA-02054: transaction 10.23.24502 in-doubt

ORA-03150: end-of-file on communication channel for database link

ORA-02063: preceding line from TEST033


SCOTT@book> select local_tran_id, GLOBAL_TRAN_ID, state from dba_2pc_pending;

LOCAL_TRAN_ID          GLOBAL_TRAN_ID            STATE

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

10.23.24502            BOOK.e6127bf4.10.23.24502 prepared


--//OK,这次模拟出来了.

SCOTT@book> update deptx         set loc = upper(loc) where deptno=10;

update deptx         set loc = upper(loc) where deptno=10

*

ERROR at line 1:

ORA-01591: lock held by in-doubt distributed transaction 10.23.24502


--//重新启动服务端:

SYS@test> startup

ORACLE instance started.

Total System Global Area  486539264 bytes

Fixed Size                  2084872 bytes

Variable Size             360714232 bytes

Database Buffers          113246208 bytes

Redo Buffers               10493952 bytes

Database mounted.

Database opened.


SCOTT@test> select local_tran_id, GLOBAL_TRAN_ID, state from dba_2pc_pending;

no rows selected


SCOTT@test> select * from depty where deptno=20;

    DEPTNO DNAME          LOC

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

        20 RESEARCH       dallas


--//客户端:

SCOTT@book> select local_tran_id, GLOBAL_TRAN_ID, state from dba_2pc_pending;

no rows selected


---//可以发现只要服务端数据库起来,这个问题自然消失,自己rollback.

--//再次重复这个测试(过程略):


SCOTT@book> select local_tran_id, GLOBAL_TRAN_ID, state from dba_2pc_pending;

LOCAL_TRAN_ID          GLOBAL_TRAN_ID          STATE

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

5.21.1953              BOOK.e6127bf4.5.21.1953 prepared


--//解决ora-01591错误:我个人总喜欢先尝试提交:

SCOTT@book> commit force '5.21.1953';

Commit complete.


SCOTT@book> select local_tran_id, GLOBAL_TRAN_ID, state from dba_2pc_pending;

LOCAL_TRAN_ID          GLOBAL_TRAN_ID          STATE

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

5.21.1953              BOOK.e6127bf4.5.21.1953 forced commit


--//现在修改已经没有问题:

SCOTT@book> update deptx         set loc = upper(loc) where deptno=10;

1 row updated.


SCOTT@book> commit ;

Commit complete.


SCOTT@book> exec DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('5.21.1953')

BEGIN DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('5.21.1953'); END;


*

ERROR at line 1:

ORA-01031: insufficient privileges

ORA-06512: at "SYS.DBMS_TRANSACTION", line 97

ORA-06512: at line 1

--//权限不够.


SYS@book> set transaction use rollback segment SYSTEM;

Transaction set.


SYS@book>  exec DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('5.21.1953');

PL/SQL procedure successfully completed.


SCOTT@book> select local_tran_id, GLOBAL_TRAN_ID, state from dba_2pc_pending;

no rows selected


--//不过再不行,参照网上的解决方法,实际上删除一些基表的内容:

set transaction use rollback segment system;

--delete from dba_2pc_pending where local_tran_id = '1.34.240088';

delete from sys.pending_trans$ where local_tran_id ='1.34.240088';

delete from pending_sessions$ where local_tran_id = '1.34.240088';

delete from pending_sub_sessions$ where local_tran_id = '1.34.240088';

commit;


--//不行,还给人为pending_trans$插入记录.网上有详细的介绍.


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

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    2854
  • 访问量
    6641907