• ORA-00060: Deadlock detected 模拟死锁产生与解决方案


    死锁:死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

    死锁产生的4个必要条件

    产生死锁的必要条件:

    1. 互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用。
    2. 请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放。
    3. 不剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放。
    4. 环路等待条件:在发生死锁时,必然存在一个进程--资源的环形链。

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

    环境介绍:

    用户test01 创建表tab01,用户test02创建表tab02。Test01 更新tab01不提交,test02 更新表tab02不提交。然后test01 更新test02下的表tab02,此时有锁阻塞、锁等待情况发生。接着test02 更新test01下的tab01,那么此时就会有 test01、test02 都在等待对方的资源,但是资源无法释放,满足死锁条件死锁产生

    创建test01用户:

    SQL>  create user test01 identified by test01;
    
    User created.
    
    SQL> grant create session,resource,dba to test01;
    
    Grant succeeded.
    
    SQL> conn test01/test01;
    Connected.
    SQL>  create table tab01 (id number);
    
    Table created.
    
    SQL>  insert into tab01 values(01);
    
    1 row created.
    
    SQL> commit;
    
    Commit complete.
    
    SQL> select * from tab01;
    
        ID
    ----------
         1

    创建test02用户:

    SQL> create user test02 identified by test02;
    
    User created.
    
    SQL> grant create session,resource,dba to test02;
    
    Grant succeeded.
    
    SQL> conn test02/test02;
    Connected.
    SQL> create table tab02 (id number);
    
    Table created.
    
    SQL>  insert into tab02 values(02);
    
    1 row created.
    
    SQL> commit;
    
    Commit complete.
    
    SQL>  select * from tab02;
    
        ID
    ----------
         2

    制造死锁:

    test01:

    SQL> update tab01 set id=id*1;
    
    1 row updated.
    
    SQL> update test02.tab02 set id=id*1;
    update test02.tab02 set id=id*1
                  *
    ERROR at line 1:
    ORA-00060: deadlock detected while waiting for resource

    test02:

    SQL> update tab02 set id=id*1 ;
    
    1 row updated.
    
    SQL> update test01.tab01 set id=id*1;
    此时一直会hang住

    查看oracle后台日志,存在ORA-00060报错

    ORA-00060: Deadlock detected. More info in file /u01/app/oracle/diag/rdbms/prod/PROD/trace/PROD_ora_3692.trc.

    解决方案:

    在我们知道是何原因引起死锁的时候,可以将一个用户的数据进行提交,可以解决死锁问题,但是如果实际生产过程中,用户以及应用产生的死锁,我们不清楚就需要去查询原因了。

    1.使用PLSQL图形工具解决死锁

    点击工具->会话

    所有会话:

     找到Blocking session status列,如果看到有valid的行,就说明存在死锁,点击箭头方向,killed掉死锁,然后进行会话刷新,就可以看到死锁被释放掉

     点击该行,可以看到具体的SQL语句

     kill掉该死锁刷新,就看不到该会话

    后台语句

    2.使用sqlplus进行语句查询

    重新制造死锁:

    SQL> update test02.tab02 set id=id*1;
    update test02.tab02 set id=id*1
    *
    ERROR at line 1:
    ORA-00060: deadlock detected while waiting for resource

    查询数据库中存在的死锁:

    col BLOCKER for a20
    col BLOCKEE for a15
    select
    (select username from v$session where sid=a.sid) blocker,a.sid,'is blocking',
      (select username from v$session where sid=b.sid) blockee,b.sid
       from v$lock a,v$lock b
        where a.block=1
         and b.request>0
      and a.id1=b.id1
      and a.id2=b.id2;

    使用SQL语句生成杀锁会话方法:

    col machine for a30
    col kill_command for a50
    col object_name for a20
    col osuser for a15
    col oracle_username for a30
    set lines 400
    select s.sid,s.machine,o.object_name,l.oracle_username,l.locked_mode,s.osuser,
        'alter system kill session '''|| s.sid || ', '|| s.serial#||''';' as kill_command
    from v$locked_object l,v$session s, all_objects o ,v$lock k
    where k.block=0 and s.sid=k.sid and l.locked_mode>2 and  l.session_id=s.sid and l.object_id=o.object_id order by 3;

     根据sid查看锁会话sql语句:

    select a.sid,a.event,a.sql_id,a.sql_child_number,b.sql_text
    from v$session a,v$sql b
    where a.sql_address=b.address
    and a.sql_hash_value=b.HASH_VALUE
    and a.sql_child_number=b.child_number
    order by 1 desc;

     根据SQL语句生成杀锁会话方法给出的KILL_COMMAND

    SQL> alter system kill session '70, 63';
    
    System altered.

    然后sqlplus中行住的SQL语句被强制结束:

     观察后台日志,ospid (4064)操作系统4064号进程被强制终止。

    Sun Sep 27 15:03:38 2020
    ORA-00060: Deadlock detected. More info in file /u01/app/oracle/diag/rdbms/prod/PROD/trace/PROD_ora_3692.trc.
    Sun Sep 27 15:10:25 2020
    opiodr aborting process unknown ospid (4064) as a result of ORA-28

    后续方法继续补充

  • 相关阅读:
    vue项目中 添加全局的随机数、随机数数组filter过滤器,并在vue的methods中使用filter过滤器
    配置如何在公网环境访问本地开发环境的微服务nat123一款很好用的公网映射工具
    使用vue开发简单的table表格插件,表头固定,内容区可滚动
    springboot study
    Clickhouse上用Order By保证绝对正确结果但代价是性能
    Java SE学习笔记
    集合与泛型
    Java常用类
    Maven
    protobuf学习详解
  • 原文地址:https://www.cnblogs.com/houzhiheng/p/13739779.html
Copyright © 2020-2023  润新知