♣  

题目         部分

在Oracle中,死锁的产生情况有哪些?


     


♣  

答案部分          


Oracle中的死锁比较复杂,产生死锁的原因也有很多种,曾经有面试官让面试人员口头模拟死锁产生的一个场景。下面详细介绍死锁的相关内容。

(一)什么是死锁?

所谓死锁,是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。Oracle对于“死锁”是要做处理的,而不是不闻不问。

(二)死锁的trace文件

Oracle中产生死锁的时候会在告警日志(alert_$ORACLE_SID.log)文件中记录死锁的相关信息,无论单机还是RAC环境都有Deadlock这个关键字,而且当发生死锁时都会生成一个trace文件,这个文件名在告警日志文件中都有记载。由于在RAC环境中,是由LMD(Lock Manager Daemon)进程统一管理各个节点之间的锁资源的,所以,RAC环境中trace文件是由LMD进程来生成的。

在RAC环境中,告警日志的形式如下所示:

1Mon Jun 20 10:10:56 20162Global Enqueue Services Deadlock detected. More info in file3 /u01/app/Oracle/diag/rdbms/raclhr/raclhr2/trace/raclhr2_lmd0_19923170.trc.

 

在单机环境中,告警日志的形式如下所示:

1Mon Jun 20 12:10:56 20162ORA-00060: Deadlock detected. More info in file /Oracle/app/Oracle/diag/rdbms/dlhr/dlhr/trace/dlhr_ora_16973880.trc.

 

通常来讲,对于单机环境,当有死锁发生后,在trace文件中会看到如下的日志信息:


当看到trace文件时,需要确认一下锁的类型,是两行还是一行,是TX还是TM,如果只有一行,那么说明是同一个SESSION,可能是自治事务引起的死锁。

对于RAC环境,当有死锁发生后,在trace文件中会看到如下的日志信息:


图 3-17 RAC环境下的死锁

(三)死锁的检测时间

死锁的检测时间是由隐含参数“_LM_DD_INTERVAL”来控制的,在Oracle 11g中,隐含参数“_LM_DD_INTERVAL”的值默认为10s,而在Oracle 10g中,该参数的值默认为60s。

(四)死锁的分类

有人的地方就有江湖,有资源阻塞的地方就可能有死锁。Oralce中最常见的死锁分为:行级死锁(Row-Level Deadlock)和块级死锁(Block-Level Deadlock),其中,行级死锁分为①主键、唯一索引的死锁(会话交叉插入相同的主键值),②外键未加索引,③表上的位图索引遭到并发更新,④常见事务引发的死锁(例如,两个表之间不同顺序相互更新操作引起的死锁;同一张表删除和更新之间引起的死锁),⑤自治事务引发的死锁。块级死锁主要指的是ITL(Interested Transaction List)死锁。

死锁分类图如下所示:

(五)块级死锁的介绍

有关每种行级死锁的介绍和模拟可以参考本节后的BLOG连接,这里简单介绍一下ITL死锁的处理办法。

ITL(Interested Transaction List)是Oracle数据块内部的一个组成部分,用来记录该块所有发生的事务,有的时候也叫ITL槽位。如果一个事务一直没有提交,那么,这个事务将一直占用一个ITL槽位,ITL里面记录了事务信息、回滚段的入口和事务类型等等。如果这个事务已经提交,那么,ITL槽位中还保存有这个事务提交时候的SCN号。ITL的个数受表的存储参数INITRANS控制,在一个块内部,默认分配了2个ITL的个数,如果这个块内还有空闲空间,那么Oracle是可以利用这些空闲空间再分配ITL的。如果没有了空闲空间,那么,这个块因为不能分配新的ITL,所以,就可能发生ITL等待。如果在并发量特别大的系统中,那么最好分配足够的ITL个数,或者设置足够的PCTFREE,保证ITL能扩展,但是PCTFREE有可能是被行数据给消耗掉的,例如UPDATE,所以,也有可能导致块内部的空间不够而导致ITL等待,出现了ITL等待就可能导致ITL死锁。

ITL等待表现出的等待事件为“TX - allocate ITL entry”,根据MOS(Troubleshooting waits for 'enq: TX - allocate ITL entry' (Doc ID 1472175.1)提供的解决办法,需要修改表和索引的参数(PCTFREE和INITRANS),修改使用的SQL如下,这里假设用户名为TLHR,表名为TLHRBOKBAL,表上的索引名为PK_TLHRBOKBAL:


1ALTER TABLE TLHR.TLHRBOKBAL PCTFREE 20  INITRANS 16;2ALTER TABLE TLHR.TLHRBOKBAL MOVE NOLOGGING PARALLEL 12;3ALTER TABLE TLHR.TLHRBOKBAL LOGGING NOPARALLEL;4ALTER INDEX TLHR.PK_TLHRBOKBAL  REBUILD PCTFREE 20 INITRANS 16 NOLOGGING PARALLEL 12;5ALTER INDEX TLHR.PK_TLHRBOKBAL LOGGING NOPARALLEL;

 



©著作权归作者所有:来自51CTO博客作者小麦苗DB宝的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 【DB笔试面试681】在Oracle中,什么是块清除(Block Cleanout)?
  2. MySQL分布式事务(XA事务)
  3. MySQL中事务的分类
  4. 事务的4种隔离级别(Isolation Level)分别是什么?
  5. spring事务详解(三)源码详解
  6. SweynTooth漏洞影响上百蓝牙产品
  7. MVCC(Multi-Version Concurrent Control,多版本并发控制)简介
  8. 事务的4个特性——ACID(原子性、一致性、隔离性和持久性)、更新丢
  9. 【MySQL】MySQL的四种事务隔离级别

随机推荐

  1. 如何在Fragment中的WebView中添加“Go Ba
  2. Android自定义控件——开源组件SlidingMe
  3. Android自动化测试学习路线
  4. 使用scala编写Android项目
  5. 在服务中设置服务重复时间
  6. weiyi通讯录(三)仿微信下拉列表和android样
  7. Android输入系统之InputChannel(上)
  8. Android程序报R cannot be resolved to a
  9. Android 平台实现按指定平率和时长发声(
  10. android源生Browser分析(四)---Webkit部分