oracle 中 'enq:TM contention' 等待事件的原因

Cause of 'enq:TM contention' wait event in oracle

在监视 v$session 中的等待事件时,我观察到处于“等待”状态的会话数和事件为“enq: TM 争用”。

像下面这样的查询 运行 来自不同的会话,none 个表有任何外键约束。

INSERT /* APPEND */ INTO tabA SELECT /*+ PARALLEL(t,4) */<select list> FROM tabX t;   
INSERT /* APPEND */ INTO tabA SELECT /*+ PARALLEL(t,4) */<select list> FROM tabY t;   
INSERT /* APPEND */ INTO tabA SELECT /*+ PARALLEL(t,4) */<select list> FROM tabZ t; 
etc

这个等待事件的原因是什么。

Here 你会找到一个简短的解释和一些例子。

An append hint instructs Oracle to take out a TM lock in exclusive mode 6 (“enq: TM – contention” wait event).

发生这种情况是因为您数据库中的多个会话需要很长时间来处理某些插入语句。因此,“活动”会话数非常高,数据库无法接受新的会话连接。

解法:

enq: TM – 争用事件通常是由于 table 缺少外键约束,这是 Oracle DML 操作的一部分。通过将外键约束添加到相关 table 解决问题后,enq: TM – 争用事件将消失。

等待 enq: TM – 等待执行插入操作的会话的争用事件几乎总是由于未索引的外键约束。当从属或子 table'引用父 table 的外键约束缺少关联键的索引。如果 Oracle 正在对子 table 的外键引用的父 table 中的主键列进行修改,则 Oracle 会获取子 table 上的 table 锁。请注意,这些是完全 table 锁 (TM),而不是行级锁 (TX)——因此,这些锁不限于一行,而是整个 table。当然,一旦获得此 table 锁,Oracle 将阻止所有其他试图修改子 table 数据的会话。一旦您在引用父 table 的列上执行的子 table 中创建索引,由于 TM 争用而导致的等待将消失。

由于在您的情况下 table 没有外键约束,您可以检查以下几点:

1) 检查任何相关的 table 是否有任何 disabled 外键。如果找到请启用它们。如果您在启用时遇到问题,请如下检查阻塞会话并杀死它们。

SQL> select a.sid, a.serial#
    from v$session a, v$locked_object b, dba_objects c 
    where b.object_id = c.object_id 
    and a.sid = b.session_id
    and OBJECT_NAME='EMP';

   SID    SERIAL#
   ----   --------
   753     8910

然后终止这个阻塞会话。

SQL> ALTER SYSTEM KILL SESSION '753,8910';

session killed.

希望之后您能够启用外键,如果有的话,争用问题将得到解决。