♣
题目 部分
在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 2016
2Global Enqueue Services Deadlock detected. More info in file
3 /u01/app/Oracle/diag/rdbms/raclhr/raclhr2/trace/raclhr2_lmd0_19923170.trc.
在单机环境中,告警日志的形式如下所示:
1Mon Jun 20 12:10:56 2016
2ORA-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;
由ITL不足引发的块级死锁模拟可以参考我的BLOG:http://blog.itpub.net/26736162/viewspace-2124771/。
《Oracle程序员面试笔试宝典》,作者:小麦苗
About Me:小麦苗
● 本文作者:小麦苗,只专注于数据库的技术,更注重技术的运用
● 作者博客地址:http://blog.itpub.net/26736162/abstract/1/
● 本系列题目来源于作者的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解
● 版权所有,欢迎分享本文,转载请保留出处
QQ群:618766405
● 提供OCP、OCM和高可用部分最实用的技能培训
● 题目解答若有不当之处,还望各位朋友批评指正,共同进步
DBA宝典
长按下图识别二维码或微信扫描下图二维码来关注小麦苗的微信公众号:xiaomaimiaolhr,学习最实用的数据库技术。