一次enq: TM - contention分析

客户反映前台业务卡住了,怀疑是有锁表,锁表时查询等待事件是enq: TM - contention,因为是业务高峰期,所以直接把锁杀掉了,事后想要查一下锁表原因。

客户数据库环境是11g rac,我采集了锁表时间段两节点的awr报告。发现等待事件排在第一位的都是enq: TM - contention。

节点一等待事件:
在这里插入图片描述
节点二等待事件:
在这里插入图片描述
节点一SQL ordered by Elapsed Time:
在这里插入图片描述
节点二SQL ordered by Elapsed Time:
在这里插入图片描述
节点二top sql对表MSG_MESSAGE01插入的等待事件过长。同时发现同一时间段还有对该表MSG_MESSAGE01的删除操作。但是一般情况下对同一表同时进行insert和delete操作不会导致TM锁,所以我们还需要进一步确认是否是这个delete操作导致的死锁。

这里我们需要查询一下发生死锁时间段的等待事件的源头。这里我选择了10点到10点30,我尝试过查询十点之前的发现并没有等待事件。我们可以查询相应时间段v$active_session_history或者dba_hist_active_sess_history视图

select * from v$active_session_history
                where sample_time >
                    to_timestamp('2024-02-02 10:00:00',
                                 'yyyy-mm-dd hh24:mi:ss')
                and sample_time <
                    to_timestamp('2024-02-02 10:30:00',
                                 'yyyy-mm-dd hh24:mi:ss');

在这里插入图片描述
查询到blocking_session锁对应的sql_id:6qmt9una23q3s 就是节点二上对表MSG_MESSAGE01进行delete的那条sql。

锁的源头找出来了,那么问题来了,一个常规的delete操作为什么会导致锁的?

有一种可能就是,MSG_MESSAGE01表是某张表的父表,在删除父表记录的之前要将子表对应数据先删掉,而该子表数据量比较多并且对应的外键上没有索引,索引才导致删除表MSG_MESSAGE01记录的时候产生等待。

查找与表MSG_MESSAGE01关联的子表:

这里要用表所属的用户查询,才能查到,我也不知道为什么。
select * from user_constraints where 
R_CONSTRAINT_NAME in (select constraint_name from user_constraints where table_name = 'MSG_MESSAGE01') ;

在这里插入图片描述
这里查到两个与表MSG_MESSAGE01关联的子表。其中表MSG_MSGREC数据量为5万,其键值关系和索引如下图所示:
在这里插入图片描述
在这里插入图片描述
MSG_MSGREC表的外键上确实没有索引,这就会导致,在删除父表记录的时候,会全表扫描MSG_MSGREC表。
我们只需在MSG_MSGREC表外键上加上索引即可。

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值