完成RDBMS的跨时代天才——Bob Miner.
2017-11-21
Hello, Global:第一届EXEM海外工程师培训后记
2017-12-28

 

目录

1 Basic Info. 2

2 Parameter & Wait Time. 3

2.1 Wait Paremeters 3

2.2 Wait Time. 3

3 Check Point & Solution. 4

3.1无索引的外键… 4

3.2不当的DDL引起的TM锁争用… 4

3.3 利用Lock table…主动获取TM锁时… 6

3.4 执行Direct/Parallel Load工作时… 6

 

 

1 Basic Info

执行DML期间,为防止对与DML 相关的对象进行修改,执行DML的进程必须对该表获得TM锁。若在获取TM锁的过程中发生争用,则等待enq:TM-contention 事件。

TM锁其用途虽然十分明确,但是准确的概念及定义方面有容易混淆的一面。例如,Oracle的概念手册上,关于锁的分类说明如下:

  • DML锁 : Data lock。执行DML时保护数据的锁。Row Lock(TX)保护特定行,Table Lock(TM)保护整个表,可以通过DBA_DML_LOCKS观察。
  • DDL锁 : Data dictionary lock。保护用户、表、视图、过程等定义,可以通过DBA_DDL_LOCKS 观察。

以上说明可能让大家以为存在DML锁和DDL锁这两个锁,给大家带来混乱。实际上,DML锁和DDL锁只是为了合理分配锁而赋予的名称,请注意这一点。

DML锁实际上与TM锁一致。DML锁可以通过DBA_DML_LOCKS视图观察,这个视图的作用是从V$LOCK视图上筛选出锁类型为TM 的。数据库上允许的TM锁数量,可以利用DML_LOCKS参数指定。若将DML_LOCKS参数值设为0,则对于表无法获得TM锁。这时,Oracle为了保障表定义被保护,对于表根本上不允许DDL操作。因此,即便不获得TM锁,也允许修改表的特定行。如OPS环境下,为了减少在全局范围内获得TM锁过程中发生的附加资源消耗,有时也将DML_LOCKS值修改为0。

DDL锁实际上与library cache lock一致。DDL锁可以通过DBA_DDL_LOCKS视图观察,这个视图实际上起到加工X$KGLLK视图后显示的作用。DDL锁除DBA_DDL_LOCKS视图之外,还可以通过X$KGLLK,DBA_KGLLOCK等视图观察。

对于表,普通DML语句以Sub-Exclusive(SX)模式获得TM锁。Sub-Exclusive模式之间存在共享性,所以多个会话可以对相同的表执行DML。已执行DML 的会话对于表,以Sub-Exclusive模式获得TM锁,对于已修改的数据以独占(Exclusive)模式获得TX锁。

如下所示,可以通过V$LOCK视图,观察执行DML的会话以何种模式获得了哪些锁。

SQL> update test set id = 1 where rownum = 1;

SQL> exec print_table(‘select * from v$lock where sid = 148’);

 

ADDR                           : C0000000ED2663D0

KADDR                          : C0000000ED2663F8

SID                             : 148

TYPE                            : TM

ID1                              : 54679

ID2                              : 0

LMODE                           : 3

REQUEST                         : 0

CTIME                            : 67

BLOCK                            : 0

—————–

ADDR                             : C0000000ED2DB7F8

KADDR                            : C0000000ED2DB980

SID                               : 148

TYPE                              : TX

ID1                               : 4718594

ID2                               : 439

LMODE                            : 6

REQUEST                          : 0

CTIME                            : 67

BLOCK                            : 0

对于Object ID 54679(ID1)相应的对象,可以确认正在以Sub-Exclusive(3)模式获得TM锁。TM锁的ID1相当于表的Object ID。因此结合DBA_OBJECTS,就可以判断TM锁对应的表。因为Sub-Exclusive模式之间存在共享性,所以DML之间不发生围绕TM锁的争用,enq:TM-contention等待也不会发生。一般发生TM锁争用的情况如下:

  • 修改无索引外键foreign key的父键时
  • DML DDL 间的TM争用
  • Lock table …引起的TM争用
    • Direct load 工作引起的TM锁争用

 

2 Parameter & Wait Time

2.1 Wait Paremeters

P1 : Enqueue信息

P2 : Object#

P3 : Table/Partition信息

2.2 Wait Time

与enqueue等待事件相同。最大等待时间为3秒。若没有获取TM锁直等到到获取等待。

 

3 Check Point & Solution

3.1无索引的外键

Oracle 9i之前,没有索引的外键列是TM锁争用的主要原因。Oracle 9i之前版本上,子表的外键列没有索引的状态下,若父表的键(Key)被修改,则对子表应该以共享(Shared)模式或Shared-Sub-Exclusive模式获得TM锁。已获得的TM锁一直拥有到父表修改键的事务结束为止(提交或回滚),因此经常发生性能严重下降的现象。但是从Oracle 9i开始,算法大幅得到改善,不再发生类似的争用现象。若还在使用Oracle 9i之前版本,则需要养成在外键列创建索引的习惯。

3.2不当的DDL引起的TM锁争用

对于事务正运行的表,基本上不可能执行DDL。因此,这时不会发生争用引起的性能问题,接下来看一个具体例子。

会话A

SQL> update test set id = 1 where rownum = 1;

会话 B:

SQL> alter table test add ID2 number;

alter table test add ID2 number

*

ERROR at line 1:

ORA-00054: resource busy and acquire with NOWAIT specified

对于已完成Update但还没有提交的表,不可能执行DDL。相反,对于正执行DDL的表执行DML时,可能发生TM锁争用。对于特定进程的表创建索引时,对于表在创建索引期间以共享(Shared)模式获得TM锁。

SQL> create index big_objects_idx_test

on big_objects(owner,object_name,object_id);

ß 查看创建索引的期间以什么方式获取TM锁。

SQL> exec print_table(‘select * from v$lock where sid = 148’);

ADDR                           : C0000000ED2663D0

KADDR                          : C0000000ED2663F8

SID                             : 148

TYPE                            : TM

ID1                             : 52318

ID2                             : 0

LMODE                          : 4       <– 共享模式

REQUEST                        : 0

CTIME                           : 3

BLOCK                           : 0

利用TM锁的ID1,可获得表名BIG_OBJECTS。LMODE值是4,表示共享(Shared)模式。即,create index语句对于表big_objects,以共享模式获得TM锁。问题在于,对这个表执行DML的会话,应该以Sub-Exclusive模式获得TM锁。因为共享模式和Sub-Exclusive模式没有共享性,所以执行DML的会话等到DDL 执行结束为止时,才发生enq:TM-contention等待事件。减少DDL引起的TM锁争用的方法如下:

若对于数据多的表执行不当的DDL,则访问此表的所有DML 会话都会陷入等待状态,可能发展至故障状态。通过合理的管理,从根本上防止才是最好的方法。

执行DDL 时,最好使用Online选项。随着Oracle 版本升级,Online状态下可执行的DDL逐步增加。大部分普通DDL上,可以使用Online选项。例如,利用Online选项执行create index命令时,不是以共享模式,而是以Sub-Shared(SS)模式获得TM锁的。因为Sub-Shared 模式和Sub-Exclusive模式之间有共享性。所以在创建索引的过程中,可以执行DML。即,不会发生enq: TM-contention等待,接下来看一下例子。

会话A:(SID=148)

SQL> create index big_objects_idx_test111 on

big_objects(secondary, generated, temporary, status, timestamp, last_ddl_time)

online;  以Online选项创建

会话B:

SQL> exec print_table(‘select * from v$lock where sid = 148’);

ADDR                           : C0000000ED2663D0

KADDR                          : C0000000ED2663F8

SID                             : 148

TYPE                            : TM

ID1                             : 52318

ID2                             : 0

LMODE                          : 2    <– Sub-Shared模式

REQUEST                        : 0

CTIME                           : 1

BLOCK                           : 0

使用Parallel DDL将DDL的执行速度最大化。对拥有大量数据的表执行DDL时,若恰当使用Parallel 选项,可将DDL本身性能最大化,而且同时使用Nologging选项也比较好。如果提升了DDL执行速度,TX锁争用引起的等待时间相应地也会下降。

3.3 利用Lock table…主动获取TM锁时

利用Lock table …语句有意获取TM锁时可能发生TM锁争用。

会话A: (SID=148)

SQL> update test set id=1 where rownum=1;

 

会话B:(SID=150

SQL> lock table test in exclusive mode;

… Wait …

如上所示,会话A上因update以Sub-Exclusive 模式拥有TM锁的状态下,会话B利用lock table 命令,试图以独占(Exclusive)模式获得TM锁时,如果发生争用,则等待enq:TM-contention事件。

发生TM锁引起的争用时,收集锁拥有者(lock holder)在会话上执行的SQL语句尤为重要。发生TM锁的情况非常多样,因此没有SQL语句,就很难作出准确判断的情况较多。引发问题的SQL语句是Lock table …语句,因此如果发生大量的TM锁争用,可以通过对应用程序的适当修正解决争用。与其为了同步对整个表上锁,不如考虑使用DMBS_LOCK程序包或使用select … for update等,减少锁范围的方法。

3.4 执行Direct/Parallel Load工作时

INSERT /*+ APPEND */ INTO…或SQL*Loader的direct path load之类的部分功能,对于相应表以Exclusive 模式获得TM锁。Direct load工作不经过SGA,而是直接写入到数据文件里,所以在执行工作期间不允许对表进行任何修改。总之,以独占模式获得TM锁,对于表不允许发生任何修改,这点应该得到保障,工作才能得以继续。

Direct load 工作在执行期间,不允许对于表执行任何DDL或DML。因此事务多的时刻执行Direct load工作时,需要确认TM锁争用是否可能引发问题。将SQL*Loader利用parallel模式执行时,对表以共享模式获取TM锁。因此,此种情况下也不会允许其他会话上的DDL 或DML。

 

Leave a Reply

Be the First to Comment!

Notify of
avatar
wpDiscuz