等待事件 enq:TX - row lock contention分析与解决

article/2025/8/28 11:42:35

6月30日,数据库发生了大量锁表。大概持续1小时,并且越锁越多。后来通过业务人员停掉程序,并kill掉会话后解决。

几天后再EM上查看CPU占用:
在这里插入图片描述
CPU发生了明显等待。
在这里插入图片描述
主要是由于enq:TX - row lock contention等待事件造成。

等待事件—enq:TX - row lock contention

enq是一种保护共享资源的锁定机制,一个排队机制,先进先出(FIFO)

发生TX锁的原因一般有几个:
1.不同的session更新或删除同一个记录。
2.唯一索引有重复索引
3.位图索引多次更新
4.同时对同一个数据块更新
5.等待索引块分裂

官网上关于TX - row lock contention的内容:

Oracle官网上关于TX - row lock contention的内容

10.3.7.2.4 TX enqueueThese are acquired exclusive when a transaction initiates its first change and held until the transaction does a COMMIT or ROLLBACK.
Waits for TX in mode 6: occurs when a session is waiting for a row level lock that is already held by another session. This occurs when one user is updating or deleting a row, which another session wishes to update or delete. This type of TX enqueue wait corresponds to the wait event enq: TX - row lock contention.
The solution is to have the first session already holding the lock perform a COMMIT or ROLLBACK.
Waits for TX in mode 4 can occur if the session is waiting for an ITL (interested transaction list) slot in a block. This happens when the session wants to lock a row in the block but one or more other sessions have rows locked in the same block, and there is no free ITL slot in the block. Usually, Oracle dynamically adds another ITL slot. This may not be possible if there is insufficient free space in the block to add an ITL. If so, the session waits for a slot with a TX enqueue in mode 4. This type of TX enqueue wait corresponds to the wait event enq: TX - allocate ITL entry.
The solution is to increase the number of ITLs available, either by changing the INITRANS or MAXTRANS for the table (either by using an ALTER statement, or by re-creating the table with the higher values).
Waits for TX in mode 4 can also occur if a session is waiting due to potential duplicates in UNIQUE index. If two sessions try to insert the same key value the second session has to wait to see if an ORA-0001 should be raised or not. This type of TX enqueue wait corresponds to the wait event enq: TX - row lock contention.
The solution is to have the first session already holding the lock perform a COMMIT or ROLLBACK.
Waits for TX in mode 4 is also possible if the session is waiting due to shared bitmap index fragment. Bitmap indexes index key values and a range of ROWIDs. Each 'entry' in a bitmap index can cover many rows in the actual table. If two sessions want to update rows covered by the same bitmap index fragment, then the second session waits for the first transaction to either COMMIT or ROLLBACK by waiting for the TX lock in mode 4. This type of TX enqueue wait corresponds to the wait event enq: TX - row lock contention.
Waits for TX in Mode 4 can also occur waiting for a PREPARED transaction.
Waits for TX in mode 4 also occur when a transaction inserting a row in an index has to wait for the end of an index block split being done by another transaction. This type of TX enqueue wait corresponds to the wait event enq: TX - index contention.10.3.7 enqueue (enq:) waitsEnqueues are locks that coordinate access to database resources. This event indicates that the session is waiting for a lock that is held by another session.The name of the enqueue is included as part of the wait event name, in the form enq: enqueue_type - related_details. In some cases, the same enqueue type can be held for different purposes, such as the following related TX types:enq: TX - allocate ITL entryenq: TX - contentionenq: TX - index contentionenq: TX - row lock contentionThe V$EVENT_NAME view provides a complete list of all the enq: wait events.You can check the following V$SESSION_WAIT parameter columns for additional information:P1 - Lock TYPE (or name) and MODEP2 - Resource identifier ID1 for the lockP3 - Resource identifier ID2 for the lock
通过awr报告查看:
SQL> @?/rdbms/admin/awrrpt.sql

1.这2个小时进行AWR的收集和分析,首先,从报告头中看到DB Time达到2176分钟,(DB Time)/Elapsed=18,这个比值偏高:
在这里插入图片描述
2.再看TOP 10事件:
看到排在第一位的是enq: TX - row lock contention事件,也就是说系统中在这一个小时里产生了较为严重的行级锁等待事件。
在这里插入图片描述
3. 同时,从段的统计信息章节中,也看到下面的信息:
在这里插入图片描述
看到row lock waits发生在表上。

通过命令查看

那么,究竟是什么操作导致了这个enq: TX - row lock contention等待事件呢? 查看系统中,当前有哪些会话产生了enq: TX - row lock contention等待事件?

现在已经解锁了,所以无法查询

SQL> select event,sid,p1,p2,p3 from v$session_wait where event='enq: TX - row lock contention';未选定行

如果正在锁着,可以参考enq: TX - row lock contention等待事件

查看系统中的当前会话,是在哪个对象上产生了enq: TX - row lock contention等待事件?

  • 查看引起enq: TX - row lock contention等待事件的object_id对象号
SQL> select ROW_WAIT_OBJ#,ROW_WAIT_FILE#,ROW_WAIT_BLOCK#,ROW_WAIT_ROW#  from v$session  where event='enq: TX - row lock contention';

那么这个数据库对象为ROW_WAIT_OBJ#的对象究竟是什么呢?

  • 查看ROW_WAIT_OBJ#对应的对象名称
SQL> select  object_name,object_idfrom  dba_objects  where object_id=【ROW_WAIT_OBJ#】;
  • 通过对象名称查看对象的owner及类型
SQL> select OWNER,OBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID, OBJECT_TYPEfrom dba_objectswhereobject_name='【OBJECT_NAME】';

定位到的结果应该同AWR报告中段统计信息吻合。

通过查询gv$session找到当前的等待事件

SQL> select event,count(*) from gv$session group by event;EVENT                                   COUNT(*)
---------------------------------------------------------------- ----------
SQL*Net message from client                           3205
wait for unread message on broadcast channel                  5
Streams AQ: waiting for messages in the queue                  4
ASM background timer                              2
ges remote message                              2
gcs remote message                              8
LNS ASYNC end of log                              2
pmon timer                                  2
rdbms ipc message                             60
jobq slave wait                               4
smon timer                                  2
gc cr request                                  1
Streams AQ: qmn slave idle wait                       2
class slave wait                             12
SQL*Net message to client                          1
Space Manager: slave idle wait                          9
GCR sleep                                  2
VKTM Logical Idle Wait                              2
Streams AQ: waiting for time management or cleanup tasks          2
Streams AQ: qmn coordinator idle wait                      2
PX Deq: Execution Msg                              1
PX Deq Credit: send blkd                          1
DIAG idle wait                                  4
PING                                      2
PX Deq: Execute Reply                              1已选择25行。

因为当前已经没有这个等待事件了,可以查看GV_$ACTIVE_SESSION_HISTORY

SQL> select SAMPLE_TIME,SESSION_ID,USER_ID,SQL_ID,EVENT,CURRENT_OBJ#,CURRENT_FILE#,CURRENT_BLOCK#  from GV_$ACTIVE_SESSION_HISTORY
where event like 'enq: TX%' and  SAMPLE_TIME like '30-6月%' and module='JDBC Thin Client' and rownum<=500;

在这里插入图片描述
结果发现很多的enq: TX - row lock contention等待事件。

定位具体SQL:

  • 通过sql_ID字段,查询
SQL> select INST_ID,SQL_TEXT from GV_$SQL where sql_id='f9kdn3mdv252a';SQL> select * from dba_hist_sqltext where sql_id='f9kdn3mdv252a';
  • 查看是哪个用户的SQL
    GV_$ACTIVE_SESSION_HISTORY中还有一个USER_ID=54
SQL> select USERNAME,USER_ID,CREATED from dba_users where USER_ID='54' ;
  • 查看到底是那个表出现了锁等待
SQL> select * from dba_objects where object_id='183598';
OWNER  OBJECT_NAME              SUBOBJECT_NAME    OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE  CREATED                 LAST_DDL_TIME          TIMESTAMP           STATUS  T G S  NAMESPACE EDITION_NAME
------------------------------ -----------------  --------- -------------- ------------ ----------------------- ---------------------- ------------------- ------- - - - ---------- -----------
XX     NODETITLEREPORT_TASK_PRJ                   183598    183598         TABLE        25-4月 -2014 12:23:53   30-6月 -2020 15:42:53   2014-04-25:12:23:53 VALID   N N N            1

解决办法

如果正在等待
1.通过v$session找到BLOCK=1的用户,告知用户提交事务

SQL> select SID,TYPE,ID1,ID2,LMODE,REQUEST,CTIME,BLOCK from V$lock where block=1 or request<>0;

2.通过sid找到pid,kill掉该进程

3.更改sql语句,

SQL> SELECT * FROM QRTZ_LOCKS WHERE LOCK_NAME = :1 FOR UPDATE no wait

加nowait的意思是得到或者得不到,不会等待

一般如果是现网中出现了大量类似的问题,排除人为原因,那么就要检查应用了。

参考:
初次遇见等待事件:enq;tx-row lock contention

enq: TX - row lock contention 等待事件


http://chatgpt.dhexx.cn/article/c94SwSC2.shtml

相关文章

java -- 随机获取字母或者数字

java只有涉及到随机的&#xff0c;最经常用到的方法就是Math.random()&#xff0c;这个方法会返回一个大于0小于1的随机数( 能取0不能取1 )&#xff0c;如果我们要随机0-9&#xff0c;就可以用&#xff08;Math.random()*10&#xff09;来表示&#xff0c;随机0-99也类似如此操…

JavaScript生成随机字母数字字符串

如何使用javascript生成随机字母数字字符串&#xff1f;下面本篇文章就来给大家介绍一下使用JavaScript生成随机字母数字字符串的方法&#xff0c;希望对大家有所帮助。 方法一&#xff1a;Math.random()方法和Math.floor()方法 ● 创建一个函数&#xff0c;该函数有两个参数…

Python - 怎么将一个数字拆分成多个随机数字

前情提要 使用numpy.random.choice()的时候&#xff0c;通过参数p&#xff08;一个列表&#xff09;来指定所给选择元素的选择概率。但参数p&#xff08;选择概率&#xff09;要保证和为1&#xff0c;这时我又想随机生成选择概率&#xff0c;所以现在的问题就是怎么将1拆分成多…

python随机生成一个数字_如何实现python随机生成数字?

今天小编就生成随机数,整理了多个方式,方便大家在项目时,根据自己的需求,直接拿来套用即可,以下内容相当详细,具体来看看吧~ 说明:python中生成随机数主要用到random模块,方法主要包括:randint、uniform、random、sample、choice等几种常用方法; 环境:Mac OS 10.1…

python随机生成三位数字_python3 随机生成数字

原博文 2019-11-25 10:07 − random模块 random.randint(1,10)--随机生成0-10之间的随机整数 random.uniform(1,10)--随机生成0-10之间的实数 random.randrange(9,100,10)--从9-100之间随机选取一个实数,差为10,也就是说从9,19,29,39,49... 0 3530 相关推荐 2019-12-0…

C#生成含数字字母的随机字符串

C#生成含数字字母的随机字符串 要求生成的字符串是随机的&#xff0c;也就是字母和数字都需要随机&#xff0c;既可能只包含数字&#xff0c;也可能只包含字母&#xff0c;也可能两者都有。 实现方式如下: 首先定义一个包含所有字母和数字的字符串和一个空串&#xff0c;随后…

css 随机 数,纯CSS实现随机效果

最近在Codepen上看到了Adir写的随机翻牌和找蛋蛋(可以想象是砸金蛋)效果&#xff0c;让我再次刷新了对CSS的认知。看到这两个效果之后我才知道&#xff0c;在CSS中除了可以实现 来自其他语言的随机性 众所周知&#xff0c;CSS是一种声明式的标记语言。在很多同学的认知中&#…

舒尔特表-5*5表格1-25个数字随机生成且不重复

大家好&#xff1a;最近在玩快速记忆&#xff0c;看到舒尔特表&#xff0c;整理出一版来。v1.0版本。 舒尔特表&#xff1a;5*5表格 1-25个数字&#xff0c;随机生成且不重复。 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http:/…

计算机随机数字excel,excel怎么生成随机数字 excel随机数字区间怎么设定

excel是我们日常生活中处理表格数据必备的工具&#xff0c;当我们知道了一定范围内的数值&#xff0c;并且不用精准的数值时&#xff0c;我们完全可以设置excel随机生成数字即可&#xff0c;怎么设置?很简单&#xff0c;下面小编为大家带来excel生成随机数字的详细教程&#x…

随机生成4个数字php,PHP随机生成4位数字的方法

//方法1 $code .mt_rand(1000,9999).; echo $code; echo ; //方法2 $code .mt_rand(1000,9999).; echo $code; echo ; //方法3 $code ; $code..mt_rand(0,9).; $code..mt_rand(0,9).; $code..mt_rand(0,9).; $code..mt_rand(0,9).; echo $code; echo ; //方法4 $code ; $r…

java生成1到10的随机数_用java生成一个1到10十个数字随机排列的数组

效果如图&#xff1a; 代码如下public class ArrayListToAry { public static void main(String[] args) { // 数组 int[] ary new int[10]; // 集合 ,临时集合temp存放1~10个数字 ArrayList temp new ArrayList(); //list集合存放需要的数字 ArrayList list new ArrayList(…

你知道如何生成随机数吗?(超详细附图)

目录 &#x1f609;前言 &#x1f378;如何用C语言实现随机数 &#x1f379;随机数原理 &#x1f379;rand函数&#xff08;生成随机数&#xff09; &#x1f379;srand&#xff08;避免每次运行程序产生的随机数都相同&#xff09; &#x1f379;时间戳 &#x1f964;t…

如何批量生成个位随机数字

众所周知&#xff0c;条码软件可以批量打印条码二维码以及各种各样的产品标签&#xff0c;功能比较齐全&#xff0c;在输入数据时有各种类型&#xff0c;比如手动输入、计数器生成、数据库字段、日期时间、序列生成、流水号等等。今天小编给大家介绍如何随机生成个位数字。 打开…

使用cmd查看端口号

打开cmd命令窗口&#xff1b;输入 netstat -nao|findstr "端口号" &#xff1b;在本地地址中查看端口号&#xff0c;并记住该进程的PID&#xff1a;在运行中输入taskmgr打开任务管理器&#xff0c;在名称一处右击&#xff0c;选中PID&#xff1b;查看第三步的PID所对…

【cmd命令】查看端口占用情况

1、昨晚安装BIS 6遇到一个问题&#xff0c;本地10000端口被占用&#xff0c;安装进行不下去。 2、通过netstat -ano&#xff08;-a 显示所有socket&#xff0c;包括正在监听的&#xff1b;-n 以网络IP地址代替名称&#xff0c;显示出网络连接&#xff1b;o查看进程pid&#xff…

windows cmd关闭端口命令

netstat -ano|findstr 8906taskkill /pid 23440 /f

cmd解决端口被占用

文章目录 一、winr打开cmd窗口二、查找被占用端口的pid号&#xff0c;例如8080端口三、通过命令杀掉当前pid进程总结 一、winr打开cmd窗口 二、查找被占用端口的pid号&#xff0c;例如8080端口 输入命令&#xff1a;netstat -aon|findstr "8080" 如果有如下输出&…

cmd命令查看端口,并强制关闭该端口号

1.查看端口&#xff08;删除8080是指查看所有端口&#xff09; netstat -aon|findstr 8080 2.强制关闭端口号 taskkill /pid 3784 /f 例如&#xff1a;效果如下图

计算机cmd测试命令,常见CMD网络诊断命令

在维修电脑的时候&#xff0c;我们可以利用一些简单的CAM命令来查看当前网络的一些状态。 操作方法 ,在开始中找到运行框&#xff0c;输入cmd&#xff0c;打开批处理窗口。输入CMD命令按回车键。 1 Ping命令 ping IP地址 &#xff0d;t 用于测试此电脑到目标IP地址的数据连通性…

CMD 命令查看本机的端口占用情况解决办法

操作步骤&#xff1a; 打开cmd命令提示符&#xff0c;输入netstat -ano&#xff0c;可以看到当前本机的所有端口情况。 &#xff08;1&#xff09;地址一栏相关说明&#xff1a;0.0.0.0是对外开放&#xff0c;通过服务域名、ip可以访问的端口。​ 127.0.0.1只能对本机…