zoukankan      html  css  js  c++  java
  • Oracle死锁

    1.什么是死锁

    在程序运行过程中,只有一个进程在运行,其他进程都在等待状态,并且点击进程的确定和保存按钮,程序无反应,但是也不报错,之中现象称作死锁。

    2.Oracle死锁原理

    操作Oracle数据库一个sql语句在执行对某个表增删改查操作时,一直处于执行状态,且没有结果返回,其他对该表操作的语句一直处于等待状态,也没有报错信息

    3.死锁产生原因

    A.存在竞争资源。系统存在共享资源不足以满足进程的需要时,就会引起进程之间竞争资源产生死锁现象。生活例子---很多人拥挤在地铁门口等待上车,地铁门一开,人们蜂拥进去,难免会有三两个人同时进去卡在们中的现象;

    B.不正当的进程推进。进程在运行过程中,请求和释放资源的顺序不当,也同样会导致产生进程死锁。

    如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。

    4.产生死锁的四个必要条件

    A.互斥条件(Mutual exclusion):一个资源每次只能被一个进程使用(资源不能被共享,只能由一个进程使用)。

    B.请求与保持条件(Hold and wait):一个进程因请求资源而阻塞时,对已获得的资源保持不放(已经得到资源的进程可以再次申请新的资源)。

    C.不剥夺条件(No pre-emption):进程已获得的资源,在末使用完之前,不能强行剥夺。

    D.循环等待条件(Circular wait):若干进程之间形成一种头尾相接的循环等待资源关系(系统中若干进程组成环路,改环路中每个进程都在等待相邻进程正占用的资源)。

    这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

    5.预防死锁的方法

    A.破坏“互斥”条件:就是在系统里取消互斥。若资源不被一个进程独占使用,那么死锁是肯定不会发生的。但一般来说在所列的四个条件中,“互斥”条件是无法破坏的。因此,在死锁预防里主要是破坏其他几个必要条件,而不去涉及破坏“互斥”条件。

    B.破坏“占有并等待”条件:破坏“占有并等待”条件,就是在系统中不允许进程在已获得某种资源的情况下,申请其他资源。即要想出一个办法,阻止进程在持有资源的同时申请其他资源。

    方法一:创建进程时,要求它申请所需的全部资源,系统或满足其所有要求,或什么也不给它。这是所谓的 “ 一次性分配”方案。
    方法二:要求每个进程提出新的资源申请前,释放它所占有的资源。这样,一个进程在需要资源S时,须先把它先前占有的资源R释放掉,然后才能提出对S的申请,即使它可能很快又要用到资源R。

    C.破坏“不可抢占”条件:破坏“不可抢占”条件就是允许对资源实行抢夺。
    方法一:如果占有某些资源的一个进程进行进一步资源请求被拒绝,则该进程必须释放它最初占有的资源,如果有必要,可再次请求这些资源和另外的资源。
    方法二:如果一个进程请求当前被另一个进程占有的一个资源,则操作系统可以抢占另一个进程,要求它释放资源。只有在任意两个进程的优先级都不相同的条件下,方法二才能预防死锁。

    D.破坏“循环等待”条件:破坏“循环等待”条件的一种方法,是将系统中的所有资源统一编号,进程可在任何时刻提出资源申请,但所有申请必须按照资源的编号顺序(升序)提出。这样做就能保证系统不出现死锁。

    6.利用银行算法避免死锁

    银行家算法:

    设进程i提出请求Request[j],则银行家算法按如下规则进行判断。

    (1) 如果Request[j]≤Need[i,j],则转向(2),否则认为出错。

    (2) 如果Request[j]≤Available[j],则转向(3);否则表示尚无足够资源,Pi需等待。

    (3) 假设进程i的申请已获批准,于是修改系统状态:

    Available[j]=Available[j]-Request[i]

    Allocation[i,j]=Allocation[i,j]+Request[j]

    Need[i,j]=Need[i,j]-Request[j]

    (4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。

    安全性检查:

    A. 设置两个工作向量Work=Available;Finish[i]=False

    B. 从进程集合中找到一个满足下述条件的进程,

    Finish [i]=False;

    Need[i,j]≤Work[j];

    如找到,执行(3);否则,执行(4)

    C.设进程获得资源,可顺利执行,直至完成,从而释放资源。

    Work[j]=Work[i]+Allocation[i,j];

    Finish[i]=True;

    go to step 2;

    D.如所有的进程Finish[i]=true,则表示安全;否则系统不安全。

    7.死锁的检测与解除

    资源分配图:

    系统死锁,可利用资源分配图来描述。如图2-17所示,用圆圈代表一个进程,用框代表一类资源。由于一种类型的资源可能有多个,用框中的一个点代表一类资源中的一个资源。从进程到资源的有向边叫请求边,表示该进程申请一个单位的该类资源;从资源到进程的边叫分配边,表示该类资源已经有一个资源被分配给了该进程。

    在图2-17所示的资源分配图中,进程P1已经分得了两个R1资源,并又请求一个R2 资源;进程P2分得了一个R1和一个R2资源,并又请求一个R1资源。
    死锁定理:

    可以通过将资源分配图简化的方法来检测系统状态S是否为死锁状态。简化方法如下:

    1) 在资源分配图中,找出既不阻塞又不是孤点的进程Pi(即找出一条有向边与它相连,且该有向边对应资源的申请数量小于等于系统中已有空闲资源数量。若所有的连接该进程的边均满足上述条件,则这个进程能继续运行直至完成,然后释放它所占有的所有资源)。消去它所有的请求边和分配边,使之成为孤立的结点。在图2-18(a)中,P1是满足这一条件的进程结点,将P1的所有边消去,便得到图248(b)所示的情况。

    2) 进程Pi所释放的资源,可以唤醒某些因等待这些资源而阻塞的进程,原来的阻塞进程可能变为非阻塞进程。在图2-17中,进程P2就满足这样的条件。根据第1) 条中的方法进行一系列简化后,若能消去图中所有的边,则称该图是可完全简化的,如图2-18(c)所示。

    S为死锁的条件是当且仅当S状态的资源分配图是不可完全简化的,该条件为死锁定理。

    死锁的解除:

    一旦检测出死锁,就应立即釆取相应的措施,以解除死锁。死锁解除的主要方法有:

    1) 资源剥夺法。挂起某些死锁进程,并抢占它的资源,将这些资源分配给其他的死锁进程。但应防止被挂起的进程长时间得不到资源,而处于资源匮乏的状态。

    2) 撤销进程法。强制撤销部分、甚至全部死锁进程并剥夺这些进程的资源。撤销的原则可以按进程优先级和撤销进程代价的高低进行。

    3) 进程回退法。让一(多)个进程回退到足以回避死锁的地步,进程回退时自愿释放资源而不是被剥夺。要求系统保持进程的历史信息,设置还原点。

    8.Oracle死锁检测

    通过检查数据库表,能够检查出是哪一条语句被死锁,产生死锁的机器是哪一台。

      1)用dba用户执行以下语句

    以下是代码片段:

    select username,lockwait,status,machine,program from v$session where sid in 
    (select session_id from v$locked_object)

      

    如果有输出的结果,则说明有死锁,且能看到死锁的机器是哪一台。字段说明:

      Username:死锁语句所用的数据库用户;

      Lockwait:死锁的状态,如果有内容表示被死锁。

      Status: 状态,active表示被死锁

      Machine: 死锁语句所在的机器。

      Program: 产生死锁的语句主要来自哪个应用程序。

      2)用dba用户执行以下语句,可以查看到被死锁的语句。

    select sql_text from v$sql where hash_value in 
    (select sql_hash_value from v$session where sid in 
    (select session_id from v$locked_object))

       A. kill掉这个死锁的进程:

      alter system kill session 'sid,serial#'; (其中sid=l.session_id)

      B. 如果还不能解决:(linux)

              select pro.spid from v$session ses, v$process pro where ses.sid=XX and ses.paddr=pro.addr;

       其中sid用死锁的sid替换:

           exit
           ps -ef|grep spid

           其中spid是这个进程的进程号,kill掉这个Oracle进程。

    参考资料:1.http://www.cnblogs.com/gdzhong/p/4863898.html

         2.http://www.2cto.com/kf/201607/528015.html 

  • 相关阅读:
    Tensor:Pytorch神经网络界的Numpy
    你真的懂语音特征吗?
    ES高级(17) 使用基础(5)安装(5) Linux 集群
    ES高级(16) 使用基础(4)安装(4) Linux 单机
    ES高级(15) 使用基础(3)安装(3) Windows 集群
    ES高级(14) 使用基础(2)安装(2) 概念
    ES入门 (13)Java API 操作(4)DQL(1) 请求体查询/term 查询,查询条件为关键字/分页查询/数据排序/过滤字段/Bool 查询/范围查询/模糊查询/高亮查询/聚合查询/分组查询
    ES入门 (12)Java API 操作(3)DML 新增文档/修改文档/查询文档/删除文档/批量操作
    ES入门 (11)Java API 操作(2)DDL 索引操作
    ES入门 (10)Java API 操作(1)准备
  • 原文地址:https://www.cnblogs.com/kuoAT/p/6641931.html
Copyright © 2011-2022 走看看