暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

enq: TX - row lock contention处理

原创 2022-12-01
1764

一、Oracle 的enqueue 包含以下模式:

模式代码

解释

1

Null mode

2

Sub-Share

3

Sub-Exclusive

4

Share

5

Share/Sub-Exclusive

6

Exclusive

enq: TX - row lock contention 通常是Application级别的问题。通常情况下,Oracle数据库的等待事件enq: TX - row lock contention会在下列三种情况下会出现。

(一)第一种情况,是真正的业务逻辑上的行锁冲突,如一条记录被多个人同时修改。这种锁对应的请求模式是6(Waits for TX in mode 6 :A 会话持有row level lock,B会话等待这个lock释放。)。不同的session更新或删除同一个记录。(This occurs when one application is updating or deleting a row that another session is also trying to update or delete. )

解决办法:持有锁的会话commit或者rollback。

(二)第二种情况,是唯一键冲突(In mode 4,唯一索引),如主键字段相同的多条记录同时插入。这种锁对应的请求模式是4。这也是应用逻辑问题。表上存在唯一索引,A会话插入一个值(未提交),B会话随后也插入同样的值;A会话提交后,enq: TX - row lock contention消失。

解决办法:持有锁的会话commit或者rollback。

(三)第三种情况,是bitmap索引的更新冲突(in mode 4 :bitmap),就是多个会话同时更新bitmap索引的同一个数据块。源于bitmap的特性:位图索引的一个键值,会指向多行记录,所以更新一行就会把该键值指向的所有行锁定。此时会话请求锁的对应的请求模式是4。bitmap索引的物理结构和普通索引一样,也是 B-tree 结构,但它存储的数据记录的逻辑结构为"key_value,start_rowid,end_rowid,bitmap"。

其内容类似这样:"‘8088’,00000000000,10000034441,1001000100001111000"

Bitmap是一个二进制,表示 START_ROWID 到 END_ROWID 的记录,1 表示等于 key_value即‘8088’的 ROWID 记录, 0 则表示不是这个记录。

解决办法:持有锁的会话commit或者rollback。

在了解bitmap索引的结构之后,我们就能理解同时插入多条记录到拥有bitmap索引的表时,就会同时更新bitmap索引中一个块中的记录,等于某一个记录被同时更新,自然就会出现行锁等待。插入并发量越大,等待越严重。

(四)其他原因

二、查询出现问题时间段的ASH视图DBA_HIST_ACTIVE_SESS_HISTORY来找到我们需要的锁类型及SQL语句。

SELECT D.SQL_ID, COUNT(1)

  FROM DBA_HIST_ACTIVE_SESS_HISTORY D

 WHERE D.SAMPLE_TIME BETWEEN TO_DATE('2016-08-31 17:30:00', 'YYYY-MM-DD HH24:MI:SS') AND

       TO_DATE('2016-08-31 18:15:00', 'YYYY-MM-DD HH24:MI:SS')

   AND D.EVENT = 'enq: TX - row lock contention'

 GROUP BY D.SQL_ID; 

   

只有一条SQL语句,看来就是它了,我们来看看锁的类型:

 SELECT D.SQL_ID,CHR(BITAND(P1, -16777216) / 16777215) ||

        CHR(BITAND(P1, 16711680) / 65535) "Lock",

        BITAND(P1, 65535) "Mode", COUNT(1),COUNT(DISTINCT d.session_id )

  FROM DBA_HIST_ACTIVE_SESS_HISTORY D

 WHERE D.SAMPLE_TIME BETWEEN TO_DATE('2016-08-31 17:30:00', 'YYYY-MM-DD HH24:MI:SS') AND

       TO_DATE('2016-08-31 18:15:00', 'YYYY-MM-DD HH24:MI:SS')

   AND D.EVENT = 'enq: TX - row lock contention'

 GROUP BY D.SQL_ID,(CHR(BITAND(P1, -16777216) / 16777215) ||

        CHR(BITAND(P1, 16711680) / 65535)),(BITAND(P1, 65535));


分析具体的对象是哪个:

 SELECT  D.current_obj#,

        D.current_file#,

        D.current_block#,

        D.current_row#,D.EVENT,

        D.P1TEXT,

        D.P1,

        D.P2TEXT,

        D.P2,

        CHR(BITAND(P1, -16777216) / 16777215) ||

        CHR(BITAND(P1, 16711680) / 65535) "Lock",

        BITAND(P1, 65535) "Mode",

        D.BLOCKING_SESSION,

        D.BLOCKING_SESSION_STATUS,

        D.BLOCKING_SESSION_SERIAL#,

        D.SQL_ID,

        TO_CHAR(D.SAMPLE_TIME, 'YYYYMMDDHH24MISS') SAMPLE_TIME

   FROM DBA_HIST_ACTIVE_SESS_HISTORY D

  WHERE D.SAMPLE_TIME BETWEEN TO_DATE('2016-08-31 17:30:00', 'YYYY-MM-DD HH24:MI:SS') AND

       TO_DATE('2016-08-31 18:15:00', 'YYYY-MM-DD HH24:MI:SS')

    AND D.EVENT = 'enq: TX - row lock contention'; 


看该语句的V$SQL详细sql内容、执行计划等。

查看该SQL的绑定变量的值具体是多少,如下:

SELECT   A.sql_id,A.name,A.datatype_string,A.value_string,COUNT(1)

     FROM DBA_HIST_SQLBIND A

    WHERE A.SQL_ID IN ('1cmnjddakrqbv')

      AND A.SNAP_ID BETWEEN 1145 AND 1148  

GROUP BY A.sql_id,A.name,A.datatype_string,A.value_string


查看ADDM建议

DECLARE

  TASK_NAME VARCHAR2(50) := 'HEALTH_CHECK_BY_LHR';

  TASK_DESC VARCHAR2(50) := 'HEALTH_CHECK_BY_LHR';

  TASK_ID   NUMBER;

BEGIN

  DBMS_ADVISOR.CREATE_TASK('ADDM', TASK_ID, TASK_NAME, TASK_DESC, NULL);

  DBMS_ADVISOR.SET_TASK_PARAMETER(TASK_NAME, 'START_SNAPSHOT', 1145);

  DBMS_ADVISOR.SET_TASK_PARAMETER(TASK_NAME, 'END_SNAPSHOT', 1148);

  DBMS_ADVISOR.SET_TASK_PARAMETER(TASK_NAME, 'INSTANCE', 1);

  DBMS_ADVISOR.SET_TASK_PARAMETER(TASK_NAME, 'DB_ID', 3860591551);

  DBMS_ADVISOR.EXECUTE_TASK(TASK_NAME);

EXCEPTION

  WHEN OTHERS THEN

    NULL;

END;

/

执行完成后ADDM报告就创建好了,然后我们用函数DBMS_ADVISOR.GET_TASK_REPORT来获取报告:

SELECT DBMS_ADVISOR.GET_TASK_REPORT('HEALTH_CHECK_BY_LHR', 'TEXT', 'ALL') ADDM_RESULTS

FROM DUAL;


「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论