一则TX - row lock contention处理详解

简介:

 一、问题现象:

ORACLE OEM巡检发现某时段存在较大的WAITTING事件(如图1的红色部分):

(图1:Database Activity)
其实发现这个问题还可以从v$locked_object、AWR中发现,但要数最直观的还是OEM的ACTIVESESSIONS视图。
 
二、问题分析:
1 、为了定位事件,采集该时段的ADDM 快照(如图2 :开始PM4 ,结束PM7 ):

(图2:Database Activity)
 
2 、直奔主题SQL statements were found waiting for row lock waits (如图3

(图3:SQL statements were found waiting for row lock waits)
通过“Wait class "Application" was consuming significant database time”我们分析由于应用程序的问题导致 enq: TX - row lock contention。再看SQL语句,基本判断是由于未COMMIT导致。
TX 锁通常被称为事务锁,当一个事务开始时,如执行INSERT/DELETE/UPDATE/MERGE 等操作或者使用SELECT ... FOR UPDATE 语句进行查询时,会首先获取事务锁,直到该事务结束。Oracle 的TX 锁定是在行级获得的,每个数据行上都存在一个锁定位(1b-Lock Byte ),用于判断该记录是否被锁定,同时在每个数据块的头部(Header )存在一个ITL 的数据结构,用于记录事务信息等,当需要修改数据时,首先需要获得回滚段空间用于存储前镜像信息,然后这个事务信息同样被记录在ITL 上,通过ITL 可以将回滚信息和数据块关联起来,所以说Oracle 的行级锁定是在数据块上获得的,行级锁只有排他锁没有共享模式。
 
3 、找到根源
为了区分程序调用的来源(存储过程还是直接调用),我们继续点击图2的“SQL statements consuming significant database time were found.”链接(一般WAIT事件这里也会露脸,且如果是存储过程调用的话这里会有存储过程的信息)

(图4:SQL statements consuming significant database time were found)
从图4 发现了可以的存储过程begin PR_WTCM_HOT_COUNT ( :1, :2 );end;
通过PLSQL 查看存储过程如下:
create or replace procedure PR_WTCM_HOT_COUNT(
       p_code_ts in varchar2,
       p_code_t in varchar2
) is
v_count number;
--统计热门商品
begin
 --判断当前的商品编号是否已经存在
 select count(*) into v_count from wtcm_hot_goods_count t where t.code_ts=p_code_ts;
 
 if v_count>0 then
     update wtcm_hot_goods_count t set t.v_count=t.v_count+1 where t.code_ts=p_code_ts;
 else
      insert into wtcm_hot_goods_count(code_ts,v_count,code_t) values(p_code_ts,1,p_code_t);
 end if;
end PR_WTCM_HOT_COUNT;
显然,上面存储过程代码中红色部分即是元凶,存储过程中未发现COMMIT ,如果框架未有提交动作,那么显然多个会话执行时有行锁的风险,为了证实这一想法进行了后续测试。
 
 
三、问题测试:
1 、测试数据:
   模拟测试用例:通过分析存储过程发现,存储过程有两个参数: p_code_ts、p_code_t。我们从测试库中随机抓出一条记录p_code_ts =29031100,p_code_t=29031100。

 

(图5:测试数据)
 
2 、启动一个PLSQL 模拟一个会话:

(图6:模拟会话1)
 
3 、启动另外一个PLSQL 模拟另一个会话:(看到左下角长久处于Excuting ……了么)

(图7:模拟会话2)
4 、查阻塞的会话:
查询语句:
Select osuser,machine,program, Module,sid,serial#,event,t2.logon_time
from v$locked_object t1,v$session t2 
where t1.session_id=t2.sid  order  by t2.logon_time
结果如下(图8):

(图8:阻塞会话查询)
显然是enq: TX - row lock contention导致了死锁,基本确定刚刚执行存储过程导致
 
5 提取SQL 语句:
根据sid用如下语句提取:
SELECT /*+ PUSH_SUBQ */ 
Sql_Text, Sharable_Mem, Persistent_Mem, Runtime_Mem,First_Load_Time,  SYSDATE Start_Time
FROM V$sqlarea 
WHERE Address = ( SELECT Sql_Address 
FROM V$session 
Where Sid = 992);
提取结果如下:
(图9:根据SID提取SQL语句)
很显然,语句是:UPDATE WTCM_HOT_GOODS_COUNT T SET T.V_COUNT=T.V_COUNT+1 WHERE T.CODE_TS=:B1这和我们执行的存储过程中的语句一致,证明了该存储过程如果执行后无提交,那么将会引起阻塞。
 
四、解决问题:
1 、应急措施
a.组装杀死锁的语句(dba权限):
select 'alter system kill session '||chr(39)||t2.sid||','||t2.serial#||chr(39)||';'
from v$locked_object t1,v$session t2 
where t1.session_id=t2.sid  order  by t2.logon_time

(图10:组装杀死锁的语句)
b.执行杀死锁语句(dba权限):

(图11:执行杀死锁语句)
 
c.确认会话存在否:

(图12:确认会话已经不存在)
 
2 、彻底解决方案
存储过程加COMMIT
应用程序框架中提交


本文转自zylhsy 51CTO博客,原文链接:http://blog.51cto.com/yunlongzheng/411205,如需转载请自行联系原作者
相关文章
|
SQL 监控 Oracle
Oracle 数据库发生等待事件:enq: TX - row lock contention ,排查思路
Oracle 数据库发生等待事件:enq: TX - row lock contention ,排查思路
Oracle 数据库发生等待事件:enq: TX - row lock contention ,排查思路
|
传感器
单片机的输入输出端口
单片机的输入输出端口
2685 2
|
存储 SQL Oracle
【Oracle系列】- 存储过程(Stored Procedure)
【Oracle系列】- 存储过程(Stored Procedure)
667 0
|
存储 数据可视化 关系型数据库
Apache Doris-部署
建议使用使用 Docker 开发镜像编译
1515 0
Apache Doris-部署
2025最后一次S级大促,12月1688采购节报名指南!
1222采购节作为1688平台2025年最后一场S级大促,汇聚产业带优质货源,助力商家冲刺年终业绩。活动期间(12月22日-24日),跨店每满200减20,报名商品有机会入选“百亿补贴”获流量加持。商家需注意价格不超市场9.9折,建议优化运费提升竞争力。把握年底商机,积极备战,共赢收官之战!
|
Ubuntu Linux Windows
Debian:apt-get命令汇总
`apt-get` 是 Debian 及其衍生发行版(如 Ubuntu)中的核心包管理工具,用于安装、更新和卸载软件。它通过操作 `.deb` 格式的软件包,实现对系统软件的集中管理。常见命令包括 `install`(安装)、`remove`(卸载)、`update`(更新软件列表)和 `upgrade`(升级软件)。此外,`autoclean` 和 `clean` 可清理无用的包文件以释放空间。掌握 `apt-get` 的使用方法,是 Linux 系统管理的基础技能之一。
560 3
|
人工智能 监控 物联网
深度探索人工智能与物联网的融合:构建未来智能生态系统###
在当今这个数据驱动的时代,人工智能(AI)与物联网(IoT)的深度融合正引领着一场前所未有的技术革命。本文旨在深入剖析这一融合背后的技术原理、探讨其在不同领域的应用实例及面临的挑战与机遇,为读者描绘一幅关于未来智能生态系统的宏伟蓝图。通过技术创新的视角,我们不仅揭示了AI与IoT结合的强大潜力,也展望了它们如何共同塑造一个更加高效、可持续且互联的世界。 ###
|
Java 测试技术 数据库
@Transactional(readOnly=true):真的是提高性能的灵丹妙药吗?
【10月更文挑战第1天】在Java开发中,特别是使用Spring框架进行企业级应用开发时,@Transactional注解是处理事务管理的一个关键工具。其中,readOnly=true属性常被用来标记一个事务为只读,以期达到提高性能的效果。然而,这一属性是否真的是提高性能的灵丹妙药呢?本文将深入探讨@Transactional(readOnly=true)的工作机制、潜在影响以及在实际应用中的正确使用方法。
655 1
|
机器学习/深度学习 数据采集 算法
探索机器学习在金融风控中的应用
本文深入探讨了机器学习技术在金融风险控制领域的应用与挑战。通过分析当前金融市场的风险类型及传统风控方法的局限性,本文详细阐述了如何利用机器学习算法提升风控效率和准确性。文中不仅分享了机器学习模型在实际风控场景中的成功案例,还讨论了实施过程中可能遇到的技术挑战和策略选择问题。最后,本文对机器学习在金融风控领域的未来发展趋势进行了展望,旨在为金融科技从业者提供有价值的参考。
540 2