深入剖析:insert 的enq: TM – contention

张大朋(Lunar)Oracle 资深技术专家

Lunar 拥有超过十年的 ORACLE SUPPORT 从业经验,曾经服务于ORACLE ACS部门,现就职于 ORACLE Sales Consultant 部门,负责的产品主要是 Exadata,Golden Gate,Database 等。

编辑手记:此文通过分场景环环紧扣的测试,深入剖析了enq: TM – contention等待事件的原理,今日拣选与大家共享。

结论:当外键无索引时 1,对子表的insert操作所在的事务没有完成前,对于父表的DML操作(INSERT/UPDATE/DELETE)都会因为不能获得对子表的TM锁而出现enq: TM – contention。 2,在1的基础上,如果又有了对子表的insert,那么这个对子表的insert同样被阻塞,等待事件也是 enq: TM – contention。 3,对父表的insert会阻塞对父表的delete。同样的道理,此时对父表的insert也阻塞对父表的update pk操作。

当没有索引的时候

测试1, 在子表发生 Insert,然后在父表上有update操作

Session 1: 对子表进行insert,不commit时:

这是,我们看到,该回话在主表(1062788 DEPT)和子表(1062790 EMP)上都分别持有了 exclusive lock(LMODE=3)锁

同时,该回话还持有一个tx锁(在子表 emp上)

另开一个会话,观察锁:

Session 2 : 然后,我们在父表做DML操作update:

Session 3: 检查锁的变化

这是我们看到,Session 2 在子表(1062790 EMP)上请求LMODE=4,并在主表(1062788 DEPT)上持有等待:enq: TM – contention

这是很清晰,有blocker了,也就是Session 1(SID 321),此时该回话正在对子表(1062790 EMP)进行插入操作

换句话说,当外键无索引时,对子表的insert操作,会造成对父表的更新操作的阻塞。

Session 4 更新父表:

这是我们看到,session 4(sid 116)遵循了跟session 220同样的所规律

这是我们在Session 1中执行commit,在Session 3中观察:

可以看到Session 2和Session 4都完成了update: Session 2:

这里我们看到,当外键无索引时,对子表的insert操作,会造成对父表的更新操作的阻塞,该阻塞直到子表的insert事务结束,才自动释放。

测试2, 在子表发生 Insert,然后在父表上有update操作,然后再有一个会话对子表做insert

重复上面的操作,不对session 1进行commit时,再开一个窗口(Session 5)对子表做insert

这是我们看到,对于子表的insert语句被阻塞了。

在Session 3中观察:

这里我们看到: 1,当外键无索引时,对子表的insert操作,会造成对父表的更新操作的阻塞,该阻塞直到子表的insert事务结束,才自动释放。 2,如果对子表有insert操作,在这个insert所在事务没有commit之前,有对父表的update,那么接下来的对子表的inser会被阻塞

测试3: 在测试2的场景上,将session 2和session 4中的对父表的update执行Ctrl+C,然后分别改为INSERT 和delete 父表(dept)的操作,观察一下

Session 4:

Session 5 随之自动解锁,并报了正常的违反约束的错误:

在session 2中执行delete 父表的操作:

注意: 1,delete父表的操作被阻塞,依然是正在请求以LMODE=4的模式对子表(1062790 EMP)的TM锁 2,这里的sid 222中为非活动会话,当该回话执行了commit或者rollback后,这个Insert的“SQL*Net message from client”等待就会消失了。

测试4: 在测试3的场景上,继续session 4中的对父表做insert 的操作,观察一下 Session 4:

这里我们看到,虽然Session 4执行的是对父表的insert,session 2执行的是对父表的 delete,他们的表现跟update的表现都是相同的。也就是说,对于子表的insert操作所在的事务没有完成前,对于父表的DML操作(INSERT/UPDATE/DELETE)都会因为不能获得对子表的TM锁而出现enq: TM – contention

测试5: 在测试4的基础上,我们在Session 1对做commit,完成对子表的insert操作,然后观察其他session:

Session 1:

Session 4:对父表的insert插入操作随着session 1的commit 自动解锁:

Session 2(SID 220):对父表的delete操作依然是hang的状态:

也就是说,这里我们看到了,对父表的insert,阻塞了对父表的delete

----the end

原文发布于微信公众号 - 数据和云(OraNews)

原文发表时间:2016-09-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏性能与架构

Redis 实现安全队列

Redis的列表数据结构可以让我们方便的实现消息队列 例如用 LPUSH(BLPUSH)把消息入队,用 RPOP(BRPOP)获取消息 绝大部分的情况下,这...

3465
来自专栏杨建荣的学习笔记

Oracle 12c PDB浅析(二)(r8笔记第29天)

之前写了第一篇Oracle 12c PDB浅析 在上次的基础上继续来学习学习。 首先关于多租户的架构设计来说,就好比在一座已经几十年的老房子上动地基...

3086
来自专栏算法channel

基础|进程和线程模型

计算机中最重要的模型之一,莫过于进程模型和线程模型了,对于它们的深刻理解,直接关系到软件开发,算法设计等计算机细分方向。 01 — 进程模型 进程是指一个具有一...

3345
来自专栏iOS 开发杂谈

iOS多线程之一:基本概念

进程:就是一个正在执行的程序。 线程:是执行程序最基本的单元,它有自己栈和寄存器。

541
来自专栏炉边夜话

对中断的一点思考

    对于X86的单处理器机器,一般采用可编程中断控制器8259A做为中断控制电路。传统的PIC(Programmable Interrupt Contr...

1062
来自专栏idba

MetaData Lock 之三

一 简介 通过前面两篇文章的介绍,相信读到这里的各位对MDL 锁已经有了比较深入的了解了,本文将结合理论知识介绍几组MDL 锁的案例。 二 常见MDL 锁的...

803
来自专栏漏斗社区

工具| 诸神之眼nmap定制化之并发处理

当我们使用nmap来进行大规模探测的时候,速度和准确度是摆在我们面前的两个问题,这时需要考虑到nmap的并发处理能力。 0x01 nmap本身的并发执行 相关...

3405
来自专栏宋凯伦的技术小栈

【Microsoft Azure学习之旅】测试消息队列(Service Bus Queue)是否会丢消息

  组里最近遇到一个问题,微软的Azure Service Bus Queue是否可靠?是否会出现丢失消息的情况?

481
来自专栏Android 研究

Android跨进程通信IPC之1——Linux基础

由于Android系统是基于Linux系统的,所以有必要简单的介绍下Linux的跨进程通信,对大家后续了解Android的跨进程通信是有帮助的,本篇的主要内容如...

853
来自专栏用户2442861的专栏

java数据库操作 (附带数据库连接池的代码)

本文来自:曹胜欢博客专栏。转载请注明出处:http://blog.csdn.net/csh624366188

572

扫码关注云+社区