百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 优雅编程 > 正文

面试官:Oracle数据库中的enq:TM-contention一般是由什么引起的

sinye56 2024-10-08 17:02 10 浏览 0 评论

概述

最近运维人员在去掉了一些外键索引的时候,隔天发现数据库多了很多告警,提示enq:TM-contention,下面记录一下问题发生及解决的过程。


1、监控异常

隔天我从数据库监控系统发现XX数据库多了很多这类型等待事件,询问时才说是觉得索引很多,所以去掉了一些看起来没什么作用的索引。


2、ASH监控

@?/rdbms/admin/ashrpt.sql

输出结果如下:

从ASH报告可以看到,TM锁的争用很多。


3、查看涉及对象

查一下当时等待事件的p1,p2,p3的值

select ash.SAMPLE_TIME,
 ash.EVENT,
 ash.SESSION_ID,
 ash.BLOCKING_SESSION,
 ash.P1TEXT,
 ash.P1,
 ash.P2TEXT,
 ash.p2,
 ash.p3text,
 ash.p3,
 ash.SESSION_STATE,
 ash.SQL_OPNAME,
 ash.SQL_ID
--ash.*
 from v$active_session_history ash
 where ash.SAMPLE_TIME >
 to_date('xx 06:00:00', 'yyyymmdd HH24:MI:SS')
 and ash.SAMPLE_TIME <
 to_date('xx 07:00:00', 'yyyymmdd HH24:MI:SS')
 and ash.WAIT_CLASS <> 'Idle'
 and ash.EVENT like 'enq: TM - contention'
 order by sample_time desc;

可以看到红色的p2的值为产生TM争用的对象id,经过查证,这些object均是session正在更新的表的子表,而且通过v$sql查看update语句均更改了主表的主键,问题到这里已经很明朗了,由于外键没加索引,导致了主表在更新主表主键或删除主表记录时对子表的锁定,而且这张主表被大量的子表引用,此时子表上也同时进行事务处理,所以造成了更新主表的session 不时hang住。

--具体object:ORDER_MOVEMENT

 select * from dba_objects where object_id='176647'

4、检测未加索引的外键语句

通过对所有子表的外键加索引,消除了争用,检测未加索引的外键语句:

 SELECT TABLE_NAME,
 CONSTRAINT_NAME,
 CNAME1 || NVL2(CNAME2, ',' || CNAME2, NULL) ||
 NVL2(CNAME3, ',' || CNAME3, NULL) ||
 NVL2(CNAME4, ',' || CNAME4, NULL) ||
 NVL2(CNAME5, ',' || CNAME5, NULL) ||
 NVL2(CNAME6, ',' || CNAME6, NULL) ||
 NVL2(CNAME7, ',' || CNAME7, NULL) ||
 NVL2(CNAME8, ',' || CNAME8, NULL) COLUMNS
 FROM (SELECT B.TABLE_NAME,
 B.CONSTRAINT_NAME,
 MAX(DECODE(POSITION, 1, COLUMN_NAME, NULL)) CNAME1,
 MAX(DECODE(POSITION, 2, COLUMN_NAME, NULL)) CNAME2,
 MAX(DECODE(POSITION, 3, COLUMN_NAME, NULL)) CNAME3,
 MAX(DECODE(POSITION, 4, COLUMN_NAME, NULL)) CNAME4,
 MAX(DECODE(POSITION, 5, COLUMN_NAME, NULL)) CNAME5,
 MAX(DECODE(POSITION, 6, COLUMN_NAME, NULL)) CNAME6,
 MAX(DECODE(POSITION, 7, COLUMN_NAME, NULL)) CNAME7,
 MAX(DECODE(POSITION, 8, COLUMN_NAME, NULL)) CNAME8,
 COUNT(*) COL_CNT
 FROM (SELECT SUBSTR(TABLE_NAME, 1, 30) TABLE_NAME,
 SUBSTR(CONSTRAINT_NAME, 1, 30) CONSTRAINT_NAME,
 SUBSTR(COLUMN_NAME, 1, 30) COLUMN_NAME,
 POSITION
 FROM USER_CONS_COLUMNS) A,
 USER_CONSTRAINTS B
 WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
 AND B.CONSTRAINT_TYPE = 'R'
 GROUP BY B.TABLE_NAME, B.CONSTRAINT_NAME) CONS
 WHERE COL_CNT > ALL
 (SELECT COUNT(*)
 FROM USER_IND_COLUMNS I
 WHERE I.TABLE_NAME = CONS.TABLE_NAME
 AND I.COLUMN_NAME IN (CNAME1, CNAME2, CNAME3, CNAME4, CNAME5,
 CNAME6, CNAME7, CNAME8)
 AND I.COLUMN_POSITION <= CONS.COL_CNT
 GROUP BY I.INDEX_NAME);

这是摘自TOM大师的语句,外键不加索引也是导致死锁的常见原因之一,因此对于主表经常进行更新删除操作的情况,外键一定要加索引。


5、添加相关外键的索引

当外键无索引时,更新删除主表的数据会造成子表的锁定,如果此时子表上有事务,那么进行更新删除的session变会等待,等待事件就是enq: TM - contention

外键与 TM enqueue lock 的主要问题是 在早期版本中(9i之前) 当 子表child table上 的外键没有索引时 , 若发生 父表 parent table 上记录被delete 或 update时 , 会在child table上加 share lock, 这会 阻塞 child table 上的DML。

但是从 9i以后的当 子表child table上 的外键没有索引时, 父表parent table上的delete 、update 只在 实际这个DML执行的过程中要求share (TM lmode=4) lock,而不会在整个事务中 都要求保持 child table上的 share lock。



结论

从这个例子我们可以看到没有建相应外键索引会导致的一系列问题,外键过多会导致索引相应增加,而索引相应增加会导致表做增删改操作需维护多张表,所以一张表不是很有必要的话是不建议建太多外键的。后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注下~


相关推荐

Linux基础知识之修改root用户密码

现象:Linux修改密码出现:Authenticationtokenmanipulationerror。故障解决办法:进入单用户,执行pwconv,再执行passwdroot。...

Linux如何修改远程访问端口

对于Linux服务器而言,其默认的远程访问端口为22。但是,出于安全方面的考虑,一般都会修改该端口。下面我来简答介绍一下如何修改Linux服务器默认的远程访问端口。对于默认端口而言,其相关的配置位于/...

如何批量更改文件的权限

如果你发觉一个目录结构下的大量文件权限(读、写、可执行)很乱时,可以执行以下两个命令批量修正:批量修改文件夹的权限chmod755-Rdir_name批量修改文件的权限finddir_nam...

CentOS「linux」学习笔记10:修改文件和目录权限

?linux基础操作:主要介绍了修改文件和目录的权限及chown和chgrp高级用法6.chmod修改权限1:字母方式[修改文件或目录的权限]u代表所属者,g代表所属组,o代表其他组的用户,a代表所有...

Linux下更改串口的权限

问题描述我在Ubuntu中使用ArduinoIDE,并且遇到串口问题。它过去一直有效,但由于可能不必要的原因,我觉得有必要将一些文件的所有权从root所有权更改为我的用户所有权。...

Linux chown命令:修改文件和目录的所有者和所属组

chown命令,可以认为是"changeowner"的缩写,主要用于修改文件(或目录)的所有者,除此之外,这个命令也可以修改文件(或目录)的所属组。当只需要修改所有者时,可使用...

chmod修改文件夹及子目录权限的方法

chmod修改文件夹及子目录权限的方法打开终端进入你需要修改的目录然后执行下面这条命令chmod777*-R全部子目录及文件权限改为777查看linux文件的权限:ls-l文件名称查看li...

Android 修改隐藏设置项权限

在Android系统中,修改某些隐藏设置项或权限通常涉及到系统级别的操作,尤其是针对非标准的、未在常规用户界面显示的高级选项。这些隐藏设置往往与隐私保护、安全相关的特殊功能有关,或者涉及开发者选项、权...

完蛋了!我不小心把Linux所有的文件权限修改了!在线等修复!

最近一个客户在群里说他一不小心把某台业务服务器的根目录权限给改了,本来想修改当前目录,结果执行成了根目录。...

linux改变安全性设置-改变所属关系

CentOS7.3学习笔记总结(五十八)-改变安全性设置-改变所属关系在以前的文章里,我介绍过linux文件权限,感兴趣的朋友可以关注我,阅读一下这篇文章。这里我们不在做过的介绍,注重介绍改变文件或者...

Python基础到实战一飞冲天(一)--linux基础(七)修改权限chmod

#07_Python基础到实战一飞冲天(一)--linux基础(七)--修改权限chmod-root-groupadd-groupdel-chgrp-username-passwd...

linux更改用户权限为root权限方法大全

背景在使用linux系统时,经常会遇到需要修改用户权限为root权限。通过修改用户所属群组groupid为root,此操作只能使普通用户实现享有部分root权限,普通用户仍不能像root用户一样享有超...

怎么用ip命令在linux中添加路由表项?

在Linux中添加路由表项,可以使用ip命令的route子命令。添加路由表项的基本语法如下:sudoiprouteadd<network>via<gateway>这...

Linux配置网络

1、网卡名配置相关文件回到顶部网卡名命名规则文件:/etc/udev/rules.d/70-persistent-net.rules#PCIdevice0x8086:0x100f(e1000)...

Linux系列---网络配置文件

1.网卡配置文件在/etc/sysconfig/network-scripts/下:[root@oldboynetwork-scripts]#ls/etc/sysconfig/network-s...

取消回复欢迎 发表评论: