`

案例学习Oracle错误:ORA-00060

阅读更多

原文: ORA-00060 deadlock detected while waiting for resource.
  Cause: Your session and another session are waiting for a resource locked by the other. This condition is known as a deadlock. To resolve the deadlock, one or more statements were rolled back for the other session to continue work.

  Action Either: 1.Enter a ROLLBACK statement and re-execute all statements since the last commit or 2.Wait until the lock is released, possibly a few minutes, and then re-execute the rolled back statements.

ORA-00060:等待资源的时候检测到死锁。

  原因:A进程和B进程同时等待彼此所占用的资源,这就是所谓的死锁。解决死锁的思路是,回滚A进程的一条或多条语句,等待B进程完成后再执行。

  方案(两者皆可):回滚至最近一次提交,重新执行所有语句。或者,等待自动解锁,这个可能需要一些时间,解锁后,再执行语句。

      其实,Oracle提供的方案,多少有点保守,一般惯用方法:找到这个进程,直接kill掉!

  实验室:模拟死锁

  1.模拟死锁实验:

  1.1 主表

  -- Create table

  create table WDZ1

  (

  WDZ1ID NUMBER not null,

  MEMO VARCHAR2(20)

  )

  ;

  alter table WDZ1

  add constraint XXXXXX primary key (WDZ1ID);

  1.2 从表(没有外健的索引)

  -- Create table

  create table WDZ2

  (

  WDZ2ID NUMBER not null,

  WDZ1ID NUMBER,

  MEMO VARCHAR2(20)

  )

  ;

  -- Create/Recreate primary, unique and foreign key constraints

  alter table WDZ2

  add constraint XXXXX primary key (WDZ2ID)

  ;

  alter table WDZ2

  add constraint XXX foreign key (WDZ1ID)

  references WDZ1 (WDZ1ID);

  1.3 插入数据表到住表

  begin

  insert into wdz1 values (1,'aa');

  insert into wdz1 values(2,'aa2');

  insert into wdz1 values (3,'aa3');

  insert into wdz2 values(10,3,'wdz3--1');

  commit;

  end;

  1.4 在一个数据库seeesion里面插入数到从表,但是不提交事务

  begin

  update wdz2 set memo='update wdz2 momo'

  where wdz2id=10;

  insert into wdz2 values(20,2,'wdz2--1');

  end;

  对从表进行插入/修改记录,施加的锁也就是行级锁

  1.5 在另外一个数据库seeesion里面删除 主表数据

  delete from wdz1 where wdz1id=1

  这时候,程序会死锁,报错ORA-00060,除非上面的对从表的数据操作提交事务或者回滚事务。

  2. 具体原因分析

  一个数据表的外键主要有3种方式来维护它自己和主表数据的一致性。

  (1)delete cascade

  例子如下:

  alter table WDZ2

  add constraint XXX foreign key (WDZ1ID)

  references WDZ1 (WDZ1ID) on delete cascade;

  (2)Set null

  例子如下:

  alter table WDZ2

  add constraint XXX foreign key (WDZ1ID)

  references WDZ1 (WDZ1ID) on delete set null;

  (3)No action

  注意,这是oracle外键使用时候的默认选项。

  例子如下:

  alter table WDZ2

  add constraint XXX foreign key (WDZ1ID)

  references WDZ1 (WDZ1ID);

  以前出现死锁主要是我们认为,在 1。4。会对数据表wdz2进行施加行级锁,但是从表(wdz2)的外健是No action,删除主表(wdz1)不会去访问从表,更不会去锁定 wdz2表的记录或者对整个数据从表(wdz2)施加表级锁。事实上 oralce的No action 选项的字面意思欺骗了我们,oracle在删除主表的时候会去寻找所有以主表的主键作为外键的数据表,然后看去看从表是否有该外键的索引,如果没有则会对整个从表施加表级锁,然后对从表进行全表扫描。当然如果从表存在外键的索引,会去访问对应的索引,而不会对从表本身进行加锁。

  案例:并行运行某个特定的批处理时发生死锁错误

  描述:我的E10000 SUn /Solaris 机器有24个处理器。当并行运行某个特定的批处理的时候,总是在同一个时间点上发生死锁的错误(ora-60)。看起来,毫无疑问这是itl的问题(两个进程在等待共享锁的时候,都持有排他锁,因为initrans等于1)。我们有20个处理器在并行工作,但是Oracle总是在同一个更新语句上停滞不前。所以,解决方案看起来就是删除掉这个表,然后重新创建拥有更高initrans 的n个initrans 的表(高到什么程度?)。一些人说这可能是锁的密度带来的负面影响,所以解决方法就是增加pctfree 。你认为这个主意怎么样?选择prctfree 或者是initrans ,在哪种情况下密度会由于这些选项而产生问题。还有,我想要知道更多有关如何读取Oracle在发生死锁的时候创建的dump的信息。我如何解释这些dump,特别是,如何识别被停止的进程拥有,同时又被其他会话等待的资源?我觉得这可能会帮助我区别资源的竞争和中断的语句明显显示出来的现象。

  解答:ITL用于控制那些想要修改块的事务。有两个参数可以控制ITL。他们分别是INITRANS 和 MAXTRANS 。INITRANS 制定了ITL可以追踪的起始事务数量。对于表来说,这个参数的默认值是1。对于索引来说,这个参数默认值是2。MAXTRANS 制定了ITL可以追踪的最大的事务数量。对于表和索引来说,默认值都是255。

  由于越来越多的事务都要修改块(表或者索引),ITL的长度从INITRANS 个项增长到MAXTRANS 个项。除了在最极端的情况下,你不需要改变这些参数的默认值。在一些很罕见的情况下,有大量的事务争夺同一个块,你可以通过增加INITRANS 来加速事务的执行。通过这种方式,ITL不必增长,因为它已经被分配得更大了。但是就像我说的,这是很少见的情况,我怀疑这个是否会对你有帮助。

  设置一个较高的PCTFREE 意味着在你的块中存储的行数更少了。这会将你的数据行分配在更多的块中。同时它还意味着你要浪费更多的空间。通过将行分配到更多的块中去,你的事务也会跨越更多个块。

  我怀疑修改INITRANS 或 PCTFREE 的值并且重新构建表能否解决你的死锁问题。

  出现死锁的情况是因为事务A持有一个资源(resource_1)的锁,同时还在请求另一个资源(resource_2)的锁。事务B持有第二个资源(resource_2)的锁,同时 申请 第一个资源(resource_1)的锁。事务A正在等待事务B放开它的锁。与此同时(这是个关键,“与此同时”),事务B也在等待事务A释放它的锁。这两个事务就叫做死锁。换句话说,他们都在等待对方释放锁。同时他们在没有完成之前,又不会释放自己的锁。他们只有当获得另外一个锁的时候,才会完成。此时,Catch 22就会起作用了。Oracle的关系型数据 管理 系统自动的检测死锁,并且回滚第一个检测到死锁的过程。

  所以,你现在可以看到,当试图获得表中数据行或者索引中条目的锁的时候,死锁就发生了。这与ITL(还有INITRANS)或者块中剩余空间的大小(还有PCTFREE)毫无关系。调整这些数值不会解决你的死锁问题。并且这是非常容易测试的。重新构建具有不同数值的表并以与以前完全相同的方式重新运行你的应用程序。你还会看到死锁。这通常发生在并行运行同一个操作的时候。

  但是不要担心,因为你现在已经赢了一半了!!!你已经确定了发生死锁状况的特定的地点。这是进行追踪的最困难的事情。现在你可以看一下你的应用程序,看看它是如何引起死锁的。你也许想要实现不同的事务控制(例如串行化事务)来防止死锁情况的再一次发生。你可以在Oracle 8 Concepts Guide中阅读更多有关事务控制的内容(特别是第24章的数据并发性和一致性)。

分享到:
评论

相关推荐

    oracle ORA-01114、ORA-27067错误解决方法

    今天有朋友问到如下一则案例,ORA-01114,ORA-27067以及OSD-04026错误同时出现: *** ACTION NAME:() 2009-04-01 09:31:00.762*** MODULE NAME:(JDBC Thin Client) 2009-04-01 09:31:00.762*** SERVICE NAME:(SYS$...

    Oracle数据泵(Data Dump)使用过程当中经常会遇到一些奇奇怪怪的错误案例

    Oracle数据泵(Data Dump)使用过程当中经常会遇到一些奇奇怪怪的错误案例,下面总结一些自己使用数据泵(Data Dump)过程当中遇到的问题以及解决方法。都是在使用过程中遇到的问题,以后陆续遇到数据泵(Data Dump)的...

    TNS-12541: TNS: 无监听程序 TNS-12560

    ORA-609 : opiodr aborting process unknown ospid (4116_6104) 这时候朋友怀疑是不是监听器配置问题,就把原先的监听器删除重建了下,问题依然。 网上有个解决TNS-12535错误的案例,平台和版本都很类似,如下:...

    深入解析OracleDBA入门进阶与诊断案例 3/4

     8.13 ORA-01555成因与解决   8.14 Oracle 11g闪回数据归档   8.15 AUM下如何重建UNDO表空间   8.16 使用Flashback Query恢复误删除数据   8.17 诊断案例之一:释放过度扩展的UNDO空间   8.18 特殊...

    深入解析OracleDBA入门进阶与诊断案例 4/4

     8.13 ORA-01555成因与解决   8.14 Oracle 11g闪回数据归档   8.15 AUM下如何重建UNDO表空间   8.16 使用Flashback Query恢复误删除数据   8.17 诊断案例之一:释放过度扩展的UNDO空间   8.18 特殊...

    深入解析OracleDBA入门进阶与诊断案例 2/4

     8.13 ORA-01555成因与解决   8.14 Oracle 11g闪回数据归档   8.15 AUM下如何重建UNDO表空间   8.16 使用Flashback Query恢复误删除数据   8.17 诊断案例之一:释放过度扩展的UNDO空间   8.18 特殊...

    《Oracle DBA手记——数据库诊断案例与性能优化实践》第一章 to be continued

    │ 04.ORA-01200错误裸设备恢复 │ 05.Oracle数据库无响应故障的处理 │ 06.RAC环境诊断案例一则 ├─第三篇 SQL调优篇 │ 01.合理利用索引解决性能问题 │ 02.SQL优化与调整实践 │ 03.索引访问与数据读取 │ 04....

    深入解析Oracle.DBA入门进阶与诊断案例

    6.2.7 诊断和解决ORA-04031错误 262 6.2.8 Library Cache Pin及Library Cache Lock分析 273 6.2.9 诊断案例一:version_count过高造成的Latch竞争解决 281 6.2.10 V$SQL与V$SQLAREA视图 287 6.2.11 Oracle ...

    Oracle创建视图(View)

    ORA-01402:视图WITH CHECK OPTION 违反WHERE 子句 视图的删除:DROP VIEW VIEW_NAME语句删除视图。 删除视图的定义不影响基表中的数据。 只有视图所有者和具备DROP VIEW权限的用户可以删除视图。 视图被删除...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 第一章 Oracle入门 一、 数据库概述 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今五十年前。简单来说是本身可视...

    Oracle表空间数据库文件收缩案例解析

    【发现异常】地产客储系统数据库Oracle_192.168.xx.xx,192.168.xx.xx,数据库customer,连接错误,0 ORA-00257: archiver error. Connect internal only, until freed. 【发生时间】2018.07.04 09:12:21 二、错误原因...

Global site tag (gtag.js) - Google Analytics