[20120412]自治事务(AUTONOMOUS_TRANSACTION)与deadlock问题.txt

[20120412]自治事务(AUTONOMOUS_TRANSACTION)与deadlock问题.txt

生产系统rac遇到一个问题,在alert*.log:
Sat Mar 17 11:43:31 2012
Global Enqueue Services Deadlock detected. More info in file
 /u01/app/oracle/admin/orcl/udump/orcl2_ora_18076.trc.
Sat Mar 17 11:43:31 2012
Trace dumping is performing id=[cdmp_20120317114331]
Sat Mar 17 11:44:29 2012
System State dumped to trace file /u01/app/oracle/admin/orcl/bdump/orcl2_diag_20766.trc

在10.2.0.3以前,会转储很大的文件到进程ora_diag_orcl*对应的转储文件,查看对应cdmp*目录,发现自己
能力有限,一直没有解决这个问题。我不得不经常检查/u01的使用情况,避免磁盘空间不足。

google找了许多链接,提示大部分都是主外键的问题。另外google这个链接:
http://studycow.itpub.net/post/37461/502772

转载如下:

五.烦人的Bug
    来之前就已经知道,Oracle的安装目录/opt所在盘,时常被充满,导致Oracle停止响应。由于一直忙于处理性能问题,把这个问题
放到了最后。之前的考虑是性能问题解决了,可能这个问题就自动解决了;确实有些时候Oracle的一些bug在性能差的时候,更容易被
触发。自从调整性能后,这个问题出现的频率的降低了一些,但还是在出;正在思考的时候,发现/opt的使用率又已经到90%了,检查
发现在安装目录的bdump目录又新生成了一个4g左右的核心转储文件。

正是这个核心转储文件,占用了大量的磁盘空间。检查alertSID.log文件发现如下的内容:
Sun Jun 6 18:51:35 2010
Global Enqueue Services Deadlock detected. More info in file
/opt/oracle/product/admin/orcl/udump/orcl1_ora_26649.trc.
Sun Jun 6 19:14:05 2010
System State dumped to trace file /opt/oracle/product/admin/orcl/bdump/orcl1_diag_4783.trc
....
日志显示是由于Oracle检查到了一个ges的死锁,于是做了系统级的dump操作,这种系统级的dump出来的内容很多,导致了dump文件特别大。
感觉象是遇到了bug,在metalink找到了现象类似的bug:6145177,bug中描述的现象与医院有些相似,但不完全一样,但打了补丁后,没再
出现这个问题。这个问题在10.2.0.4中已经解决了,目前医院使用的是10.2.0.3,Oracle已经提供了单独的Patch,为了避免大的版本升级,
就应用了单独的patch,整个过程比较顺利。打了这个patch,一直用到第二天上午,再也没有出现这个错误 ,看来patch已经起了作用。

根据这个建议要升级到10.2.0.4.
我自己也检查自己的alert文件,我发现大量出现是从2011/7/14号开始,估计开发人员改动程序引起,问了半天对方也不能确定是那个程序引起的问题。
看来良好的记录与文档很重要!去年7月5号也有出现,实际上个人感觉开发人员可以回忆起来。

$ grep -B 1 '^Global Enqueue Services Deadlock detected' alert_orcl2.log | egrep '2011|2012' > /tmp/a1
Thu Jun 30 09:12:56 2011
Tue Jul  5 08:37:28 2011
Tue Jul  5 08:38:25 2011
Tue Jul  5 08:38:55 2011
Tue Jul  5 08:39:09 2011
Tue Jul  5 08:39:47 2011
Tue Jul  5 08:40:02 2011
Sat Jul  9 10:50:39 2011
Sat Jul  9 10:50:52 2011
Sun Jul 10 10:11:50 2011
Thu Jul 14 13:36:10 2011
Thu Jul 14 13:36:15 2011
Thu Jul 14 13:41:34 2011
Thu Jul 14 13:41:39 2011
Thu Jul 14 16:24:29 2011
Thu Jul 14 16:24:35 2011
Thu Jul 14 16:25:00 2011
Thu Jul 14 16:25:09 2011
Thu Jul 14 16:25:16 2011
Thu Jul 14 16:25:23 2011
Thu Jul 14 17:02:01 2011
Fri Jul 15 08:45:24 2011
Fri Jul 15 08:45:30 2011
Fri Jul 15 08:49:36 2011
Fri Jul 15 14:20:11 2011
.....
Wed Apr 11 11:46:39 2012
Wed Apr 11 19:53:17 2012
Thu Apr 12 07:47:45 2012
Thu Apr 12 14:26:26 2012
Thu Apr 12 14:26:46 2012
--从以上信息可以发现,2011/6/30号前根本没有出现这个问题,编程出现问题的可能性个人认为情况很大。

2012年3月18号作了升级到10.2.0.4,我开始一直关注以前的情况是否解决。检查发现diag文件不再迅速增加,但是
Global Enqueue Services Deadlock detected依旧出现,不过这回我可以定位问题了。

Fri Apr 13 16:29:03 2012
Global Enqueue Services Deadlock detected. More info in file
 /u01/app/oracle/admin/orcl/udump/orcl2_ora_3135.trc.
Fri Apr 13 16:29:03 2012
Trace dumping is performing id=[cdmp_20120413162903]

查看对用的orcl2_ora_3135.trc转储文件,发现里面有记录的sql语句结合记录里面的XID,最终确定是问题,是开发人员在一个存储过程使用了自治事务引起的。

自己做了一个测试例子来再现这个问题:

1.测试环境:
SQL> select * from v$version ;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

create table t (id number,name varchar2(10));
CREATE UNIQUE INDEX I_T_I ON SCOTT.T(ID);

CREATE  PROCEDURE test1( l_id number,l_name varchar2,flag VARCHAR2) AS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
    commit ;
    IF flag = 'INSERT' THEN
        insert into t values(l_id,l_name);
    END IF;
    IF flag = 'UPDATE' THEN
        update t set id=l_id,name=l_name where id=l_id;
    END IF;
    IF flag = 'DELETE' THEN
        delete from t where id=l_id;
    END IF;
    commit;
    dbms_output.put_line (flag);
END;
/

insert into t values(1,'a');
insert into t values(2,'b');
commit;

2.测试:
打开会话1,执行如下:
SQL> set SERVEROUT on
SQL> update t set name='aaa' where id=1;

SQL> exec test1(1,'A','UPDATE');
BEGIN test1(1,'A','UPDATE'); END;

*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
ORA-06512: at "SCOTT.TEST1", line 9
ORA-06512: at line 1

alert提示如下:
Mon Apr 16 10:37:38 2012
ORA-00060: Deadlock detected. More info in file /u01/app/oracle11g/diag/rdbms/test/test/trace/test_ora_13751.trc.

--而且11G下记录更加详细,定位更加方便。
Deadlock graph:
                       ---------Blocker(s)--------  ---------Waiter(s)---------
Resource Name          process session holds waits  process session holds waits
TX-00090008-00001193        26     132     X             26     132           X

session 132: DID 0001-001A-00000007 session 132: DID 0001-001A-00000007

Rows waited on:
  Session 132: obj - rowid = 00015D00 - AAAV0AAAEAAAAIMAAA
  (dictionary objn - 89344, file - 4, block - 524, slot - 0)

----- Information for the OTHER waiting sessions -----
----- End of information for the OTHER waiting sessions -----

Information for THIS session:

----- Current SQL Statement for this session (sql_id=2bbypw0dj45w2) -----
UPDATE T SET ID=:B1 ,NAME=:B2 WHERE ID=:B1
----- PL/SQL Stack -----
----- PL/SQL Call Stack -----
  object      line  object
  handle    number  name
0x95fcdac0         9  procedure SCOTT.TEST1
0x95f2c440         1  anonymous block
===================================================

--我的测试环境是单机,如果在rac环境下,alert提示如下:
Thu Apr 12 15:56:49 2012
Global Enqueue Services Deadlock detected. More info in file
 /u01/app/oracle/admin/orcl/udump/orcl1_ora_8070.trc.
Thu Apr 12 15:56:49 2012
Trace dumping is performing id=[cdmp_20120412155649]

3.再做一个另外的测试:
SQL> rollback ;
Rollback complete.

SQL> select * from t;
        ID NAME
---------- ----------
         1 a
         2 b

SQL> insert into t values(3,'c');
1 row created.

SQL> exec test1(1,'A','UPDATE');
UPDATE

PL/SQL procedure successfully completed.

SQL> select * from t;
        ID NAME
---------- ----------
         1 A
         2 b
         3 c

--打开另外的会话,执行:
SQL> select * from t;
        ID NAME
---------- ----------
         1 A
         2 b

--可以发现自治事务的特点,id=1的记录已经显示修改,而插入的记录却还没有提交。

如果会话1这个时候rollback, 对id=1的修改依旧有效!
SQL> rollback ;
Rollback complete.

SQL> select * from t;
        ID NAME
---------- ----------
         1 A
         2 b

时间: 2024-09-19 09:03:06

[20120412]自治事务(AUTONOMOUS_TRANSACTION)与deadlock问题.txt的相关文章

[20120421] 自治事务(AUTONOMOUS_TRANSACTION) 与临时表.txt

[20120421] 自治事务(AUTONOMOUS_TRANSACTION) 与临时表.txt 前一阵遇到一个死锁的问题,存储过程使用了自治事务,测试以下使用临时表的问题. 1.测试环境:SQL> select * from v$version ;BANNER--------------------------------------------------------------------------------Oracle Database 11g Enterprise Edition

PostgreSQL Oracle兼容性之 - plpgsql 自治事务(autonomous_transaction)补丁

PostgreSQL Oracle兼容性之 - plpgsql 自治事务(autonomous_transaction)补丁 作者 digoal 日期 2016-11-04 标签 PostgreSQL , autonomous_transaction , 自治事务 , Oracle兼容性 , plpgsql 背景 PostgreSQL的plpgsql服务端编程语言与Oracle数据库的pl/sql编程语言非常类似,但是对于自治事务一直没有语法层面的支持. 以往如果要支持自治事务,可以使用exce

PostgreSQL 10.0 preview 功能增强 - 匿名、自治事务(Oracle 兼容性)

标签 PostgreSQL , 10.0 , 匿名事务 , 自治事务 背景 PostgreSQL 10.0 通过session backendground实现了匿名事务,从此可以愉快的支持Oracle存储过程的自治事务了. 此前,我们需要通过dblink实现,或者通过匿名块+exception来实现,比较繁琐. <PostgreSQL Oracle 兼容性之 - plpgsql 自治事务(autonomous_transaction)补丁> <PostgreSQL Oracle 兼容性之

[20140802] 自治事务与死锁.txt

[20140802] 自治事务与死锁.txt --今天一上班就遇到用户报机器慢的问题,连过去看,实际上是弹出一个错误窗口. $  grep -B1 "ORA-00060: Deadlock detected. More info in file" alert_xxxx.log  | egrep '2014' | cut -c1-10 | uniq -c       1 Fri Jan  3       .......       1 Mon Jul 21       1 Tue Jul

AUTONOMOUS TRANSACTION(自治事务)的介绍

    在基于低版本的ORACLE做一些项目的过程中,有时会遇到一些头疼的问题.,比如想在执行当前一个由多个DML组成的transaction(事务)时,为每一步DML记录一些信息到跟踪表中,由于事务的原子性,这些跟踪信息的提交将决定于主事务的commit或rollback. 这样一来写程序的难度就增大了, 程序员不得不把这些跟踪信息记录到类似数组的结构中,然后在主事务结束后把它们存入跟踪表.哎,真是麻烦! 有没有一个简单的方法解决类似问题呢? ORACLE8i的AUTONOMOUS TRANS

oracle数据库自治事务的学习笔记

oracle自治事务是指的存储过程和函数可以自己处理内部事务不受外部事务的影响,用pragma autonomous_transaction来声明.要创建一个自治事务,必须在匿名块的最高层或者存储过程.函数.数据包或触发器的定义部分中,使用PL/SQL中的PRAGMA AUTONOMOUS_TRANSACTION语句. 以下是使用自治事务的几种情况: (1)Declaring Autonomous Function in Package CREATE OR REPLACE PACKAGE emp

Oracle中利用自治事务实现审计功能

在一个事务(外层事务)中可以定义一个或几个自治事务.自治事务可以独立commit,不 对外层事务产生影响,同样外层事务的 rollback 也对自治事务没有影响. 假设现在 有这样一个需求,不能对某个表进行某些操作(如更新),一旦有这类操作,就强制整个回 滚,并且在审计日志中记录该次违规操作.现在的问题是当事务回滚之后,日志中的记录也 会跟着被回滚,这时就可以利用自治事务来防止这个问题. 首先,定义日志表,用于 审计. create table error_logs( id number(10)

Oracle中怎样用自治事务保存日志表

数据库事务是一种单元操作,要么是全部操作都成功,要么全部失败.在Oracle中,一个事务是从执行第一个数据治理语言(DML)语句开始,直到执行一个COMMIT语句,提交保存这个事务,或者执行一个ROLLBACK语句,放弃此次操作结束. 事务的"要么全部完成,要么什么都没完成"的本性会使将错误信息记入数据库表中变得很困难,因为当事务失败重新运行时,用来编写日志条目的INSERT语句还未完成. 针对这种困境,Oracle提供了一种便捷的方法,即自治事务.自治事务从当前事务开始,在其自身的语

PostgreSQL Oracle兼容性之 - 函数 自治事务 的实现

使用Oracle的用户,在函数中如果使用了自治事务的话,如果要转到PostgreSQL会遇到很棘手的问题.因为PostgreSQL的函数是作为一个事务来处理的,要么全部提交,要么全部回滚,除了exception,每个exception是一个子事务.因此使用exception可以达到自治事务的目的.例子1,使用并行block和嵌套block,来控制子事务层级.输入参数为block1, block2.1, block2.2, block3.1 .这些参数代表执行在哪个block出错,出错时对应层级的