Oracle 数据库发生等待事件:enq: TX - row lock contention ,排查思路

举报
Lucifer三思而后行 发表于 2021/08/22 22:16:06 2021/08/22
【摘要】 目录 前言现象排查AWR 报告Top 10 Foreground Events by Total Wait TimeSegments by Row Lock WaitsSQL ordered by...

前言

最近看 awr 报告时,经常会看到一些 enq: TX - row lock contention 的等待事件,所以简单研究一下如何排查,仅为个人所见,如有异议或者修正还请评论指出,谢谢!

通常,产生enq: TX - row lock contention事件的原因有以下几种可能:

  • 不同的session更新或删除同一条记录;
  • 唯一索引有重复索引;
  • 位图索引同时被更新或同时并发的向位图索引字段上插入相同字段值;
  • 并发的对同一个数据块上的数据进行update操作;
  • 等待索引块完成分裂;

现象

应用反馈系统使用存在延时,需要排查情况。查看监控服务器,发现数据库存在 enq: TX - row lock contention 锁的情况。

排查

首先确认发生问题的时间段,然后抓取问题时间段的报告来分析。

AWR 报告

执行 sqlplus / as sysdba @?/rdbms/admin/awrrpt.sql 输入对应时间段的信息,获取 awr 报告。

Top 10 Foreground Events by Total Wait Time

也可通过 awrcrt sqlplus / as sysdba @awrcrt.sql 来获取多段性能指标信息:

Segments by Row Lock Waits

通过观察 awr 报告中段的统计信息章节 Segments by Row Lock Waits 项,可以发现发生锁的对象主要是两张表 ABA 表的索引:

与应用确认后,发现其中一张表 A 为核心业务表,暂时怀疑另一张表可能存在问题,这里称之为表 B,所以 A 表暂且不考虑。

SQL ordered by Elapsed Time

通过 🔍 搜索关键字,查出 B 表对应的 UPDATE 语句,执行较为频繁,先记录待查看:

sql_id 为:2xb71ufa5wmrh

ASH 报告

抓取对应时间段的 ash 报告,查看是否存在有用信息。

执行 sqlplus / as sysdba @?/rdbms/admin/ashrpt.sql 获取报告:

Top User Events

Top SQL with Top Events

Top Blocking Sessions

Top DB Objects

从以上信息,不难看出,与 awr 报告分析出的结果吻合,同样的 sql_id 和 对象,并且获取到了 blocking sid

ADDMRPT 报告

有时,也可以通过抓取 addmrpt 报告来辅助看一下问题,可能有奇效。

执行 sqlplus / as sysdba @?/rdbms/admin/addmrpt.sql 获取 addmrpt 报告:

Summary of Findings

Finding 2: Row Lock Waits

同样都指向了 B 表和 sql_id 为 2xb71ufa5wmrh 的这条语句。

应用确认

经过应用确认,该条 sql 是一张核心业务表的一个触发器发起的,业务表每次新增提交时,会去执行该 sql 更新数据。由于未确认该触发器具体作用,因此无法尝试禁用来观察。

写在最后

经过排查,大部分的阻塞都是因为 sql_id 为 2xb71ufa5wmrh 的语句导致,具体也可以通过以以下 sql语句 来进行查询:

select DISTINCT b.sql_id,c.blocked_sql_id
  from DBA_HIST_ACTIVE_SESS_HISTORY b,
       (select a.sql_id as blocked_sql_id,
       a.blocking_session,
               a.blocking_session_serial#,
               count(a.blocking_session)
          from DBA_HIST_ACTIVE_SESS_HISTORY a
         where event like '%enq: TX - row lock contention%'
           and snap_id between 18835 and 18836
         group by a.blocking_session, a.blocking_session_serial#,a.sql_id
        having count(a.blocking_session) > 100
         order by 3 desc) c
 where b.session_id = c.blocking_session
   and b.session_serial# = c.blocking_session_serial#
   and b.snap_id between 18835 and 18836;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

需自行替换对应的快照范围 snap_id 值,查询结果 sql_id 为被阻塞,blocked_sql_id 为阻塞 ID。

📢 如有问题,请及时指正,谢谢!


本次分享到此结束啦~

如果觉得文章对你有帮助,点赞、收藏、关注、评论,一键四连支持,你的支持就是我创作最大的动力。

文章来源: luciferliu.blog.csdn.net,作者:Lucifer三思而后行,版权归原作者所有,如需转载,请联系作者。

原文链接:luciferliu.blog.csdn.net/article/details/119846499

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。