Enqueue Lock 介绍

Jametong@DBA
http://www.dbthink.com/

内容介绍
• Enqueue Lock 基本的概念
• 相关 Enqueue Lock 介绍







TM 锁 (Table Lock)
TX 锁 (Transaction Lock)
HW 锁 (High Watermark Lock)
US 锁 (Undo Segment Lock)
TO 锁 (Temporary Object Lock)
CF 锁 (Control File Lock)
JO 锁 (Job Queue Lock)
SQ 锁 (Sequence Cache)

Enqueue Lock 类型
• 数据字典锁 (Data Dictionary Lock)
– 行缓存锁 (Row Cache Lock)
– 库缓存锁 (Library Cache Lock & Library Cache
Pin)

• 数据处理锁 (Data Manipulation Lock)
– 行锁 (Row Lock)
– 表锁 (Table Lock)

• 内部锁以及内部闩锁 (Internal Lock and Latch)
• 分布式锁 (Distributed Lock)
• 并行缓存管理锁 (Parallel Cache Management
(PCM)Lock)

锁资源标识符
Enqueue Resource Identifier
• 每个 Enqueue Lock 都有一个唯一名称 ,
这个名称也被成为锁名称或资源名称
• 标识符的格式为 <type-id1-id2>
– Type 由有两个字母组成 , 如” TM”,”TX”
– Id1 与 id2 为正的数字 (4 个字节长 )

• 下面分别是一个 TX 锁与 TM 锁的例子
– TX-393237-184
– TM-6317-0

Enqueue Lock 模式
模式值

描述 ( 以 DML 为例来说明 )

模式

内部编号

Null

KSQMNull 1

Null 模式 , 不妨碍任何并发访问 , 主要用
来作为 Cache Invalidate 的通知机制存

SS

KSQMSS

2

SubShare 模式 , 使用共享模式锁住一条
记录

SX

KSQMSX

3

SubExclusive 模式 , 使用独占模式锁住
一条记录

S

KSQMS

4

共享模式

SSX

KSQMSSX 5

Share,SubExclusive, 对表持有共享锁 ,
对其中的记录持独占模式

X

KSQMX

Exclusive 模式 , 对全表持独占模式

6

Enqueue 模式兼容性
请求 / 占

Null

SS

SX

S

SSX

X

Null

Yes

Yes

Yes

Yes

Yes

Yes

SS

Yes

Yes

Yes

Yes

Yes

No

SX

Yes

Yes

Yes

No

No

No

S

Yes

Yes

No

Yes

No

No

SSX

Yes

Yes

No

No

No

No

X

Yes

No

No

No

No

No

Enqueue Resource & Enqueue
Lock
• Enqueue 的获取 / 转换 / 释放操作都是由
Session 操作的 ( 而不是 Process)
• 当一个 Session 持有一个 Enqueue 的时候 ,
同时也可能有其它 Session 在请求持有或转
换 Enqueue 模式
• 每个 Enqueue 都有一个资源结构与其对应 ,
由它来管理持有者 (Owners), 等待者
(Waiters) 以及请求转换模式者 (Converter).
• 每个 Owner/waiter/Converter 都有一个对
应的锁结构

Enqueue Resource 结构

Enqueue Hash 与 Latch
• 所有的 Enqueue Resource 都属于一个
Resource 表 (X$ksqrs,v$resource).
• Oracle 使用 hash 来访问数据库中的
Enqueue Resource.
• 每个 Hash bucket 都包含一个资源链表
(Hash Chain)
• 每个 Hash Chain 都有一个或多个 Latch 来控
制访问 .

获取 Enqueue Lock 的步骤
• 计算 hash 值 , 确定所需访问资源所在的链表
• 得到对应的 enqueue hash chains latch
• 定位此资源 , 如果不存在 , 则在空闲资源列表中取
一个放到此处
• 获取 enqueues latch
• 获取一个空闲的 Lock 结构
• 将此 Enqueue Lock 对应的信息填充进去
• 将此 Lock 结构挂到此 Enqueue Resource 结构

• 释放 enqueues latch
• 释放 enqueue hash chains latch

获取 Enqueue Lock 的步骤 (2)

释放 Enqueue Lock 的步骤
计算 hash 值 , 确定所需访问资源所在的链表
得到对应的 enqueue hash chains latch
定位此资源
获取 enqueues latch
将 lock 结构从 Enqueue Resource 结构上取出
释放 Enqueues latch
通知处在等待 ( 转换 ) 队列上的进程 ( 如果有的话 )
如果可能 , 释放此 Enqueue Resource, 并将其放入
空闲资源列表
• 释放 enqueue hash chains latch







死锁的检测 (dead-lock)

Enqueue Lock 转储
• alter session set events 'immediate
trace name enqueues level x‘
– Level 1 转储当前活动资源与锁的概要信息 ,
资源空闲列表以及哈希表
– Level >= 2 加上资源结构 (Resource
Structure) 的转储信息
– Level >= 3 加上锁结构 (Lock Structure)
的转储信息

Enqueue Lock 的事件跟踪
• Alter session set events ‘10704 trace
name context forever,level x’;
• 当打开此等待事件 , 将输出请求 Enqueue 的
操作信息 , 以及请求相关的参数
• X 表示等待事件的级别 , 具体说明如下
– 1-4 打出 ksqlrl,ksqcmi 的基本信息
– 5-9 还打出 ksqlac,ksqlop 等回调信息
– 10+ 还打出每个操作对应的时间信息

相关动态视图介绍
• V$resource ( 来自 x$ksqrs) 所有 enqueue resource 相关信息
• V$enqueue_lock ( 主要来自 x$ksqeq) lock Structure 为其主要
信息 , 此视图同时也将此 lock structure 对应的 session 信息与
enqueue resource 信息关联过来了
• V$resource_limit 查看 enqueue_lock 与 enqueue_resource 的
当前使用情况
• V$enqueue_stat ( 来自 x$ksqst) enqueue 操作的相关统计信息
• V$lock 所有 enqueue lock 相关锁信息
• V$locked_object ( 来在 x$ktcxb,v$transaction 完全来自此视
图 ) 查找当前被锁住的对象 .

相关视图介绍
• Lock 相关的视图信息 , 不会自动创建 , 需要执行
catblock.sql
Dba_lock 基本锁信息
Dba_lock_internal 包含内部锁 (library cache pin/lock) 以及 latch
Dba_dml_locks 仅显示 TM 锁信息 , 不过同时关联此锁对应的
Dba_ddl_locks 仅显示 library cache lock 锁 , 也即基本对象做 ddl 涉及到的

– Dba_waiters,dba_blockers 显示持有或者被阻塞的锁信息



• 显示锁相关的等待树的脚本
– @?/rdbms/admin/utllockt.sql
– 显示当前持有 / 被阻塞的锁的等待树

TM 锁
• 当对表以及表的分区进行操作时就会持有此表上的
TM 锁 .
• 相关操作包含




修改表中的数据
调整表上的约束
调整表对应的索引
分析表上的统计信息或者 validate structure
并行 dml 操作

• Id1 为此对象的 object_id(dml_locks>0)
• Id2 始终为 0

TM 锁 - 相关锁 mode 对应的操

• 表上发生 dml 操作时 , 持有的 TM mode
为 3(SubExclusive)
• 修改表结构时持有锁 mode 为 6
• 对表上的索引做 rebuild 或者创建索引时
持有的锁 mode 为 4
• 当对表做并行插入时需要持有的锁 mode
为 6, 此时后续的所有 dml 操作都会被阻塞

TM 锁 -online create/rebuild
index







Rebuild 命令尝试获取一个对应表上的 Share 锁 ( 之前会获取一个 SubShare 锁 ),
接着就会因等待当前表上还未完成的事务结束 .
当前表上的所有事务结束 , 所有在 rebuild 命令之后的事务都被 Rebuild 持有的锁
阻塞
rebuild 命令获得它的锁 , 准备物化视图日志 (MV log), 开始重建过程 , 并释放之前
持有的锁
所有等待的事务继续执行
重建过程做大量的表扫描以及排序以准备此索引 , 并将排好序的索引复制到其目标
存储位置
Rebuild 命令尝试再次获取一个表上的 Share 锁 , 并阻塞以等待表上当前的所有事
务运行结束
表上的所有当前事务运行结束 , 所有的新事务阻塞在此 Rebuild 锁之后
Rebuild 命令获得它请求的锁 , 应用 Rebuild 开始到此锁获得之间的所有变更到新
的索引上 , 删除物化视图日志 (MV log) 与旧的索引 , 并释放持有的锁 .

• 所有等待的事务继续执行

TX 锁
• 当事务开始时持有此锁 , 知道事务被提交或者回
滚才释放此锁 .
• 当 Pmon/Smon 需要回滚出现异常的事务时也会
持有 Exclusive mode 的事务锁
• 主要用来保护事务变更的记录不被并发修改
• Id1 为 undo segment number << 16 | slot
• Id2 为此事务的 sequence
• 由 id1,id2 的值组合出事务编号 usn.slot.seq

TX-mode 6




普通的 dml 产生的事务锁 .
持有锁的事务的 lmode = 6
被阻塞的事务的 request mode = 6
相关实例
Session 1
– Update james_t set value = ‘test 1’ where id = 1;

• Session 2
– Update james_t set value = ‘test 2’ where id = 1;

TX 锁 -index Contention
• 当两个 Session 插入的值出现主键 / 唯一键冲突的
时候
• 持有锁的 Session 的 lmode = 6
• 被阻塞的 session 请求的 mode 为 4
• Session 1
– insert into james_t (id,value) values
(6000001,'test 6000001');

• Session 2
– insert into james_t (id,value) values
(6000001,'test 6000001');

TX 锁 -itl contention
• 当 block 上的活动事务槽用完 , 又没有足够的空间来扩展事
务槽或者是达到 maxtrans 设定的事务槽数量时 . 此 block
上新请求的事务会等到 mode=4 的 tx lock

• session 1
– Update james_itl set value = ‘test 1’ where id =1;

• Session 2
– Update james_itl set value = ‘test 2’ where id = 2;

• Session 3
– Update james_itl set value = ‘test 3’ where id = 3;

HW 锁
• 此锁主要用来控制特定对象空间分配时的
并发操作
• Id1 为表空间的编号 ts#
• Id2 需要分配空间的对象 segment
header 的相对 DBA(Data Block
Address) 位置
• 争用主要发生在大量插入时 , 或手工对该对
象 allocate/deallocate 空间时

US- 锁



控制特定 Undo Segment 上的并行化操作
Id1 为此 undo segment 的编号 *1
Id2 始终为 1
触发 US 锁的相关操作








CREATE ROLLBACK SEGMENT
DROP ROLLBACK SEGMENT
ALTER ROLLBACK SEGMENT ONLINE
ALTER ROLLBACK OFFLINE
ALTER ROLLBACK SEGMENT SHRINK
ALTER ROLLBACK SEGMENT STORAGE
Offlining PENDING OFFLINE RBS by SMON
SMON - abortive offline cleanup.
STARTUP.

TO- 锁
• TO 锁主要是用来防止对临时表的并发操作
– 当针对临时表做 alter,drop,create 操作时 ,
会对此临时表取 TO 的 Exclusive mode 锁
– 当对此临时表做 DML 时获取 SX 锁
– 对此临时表的 index 做 ddl 操作时获取 S 锁

• Id1 为此临时表的 object_id
• Id2 始终为 1

CF 锁 - 说明
• 与控制文件修改相关的锁
– 串行化对控制文件的修改
– 任何涉及到对控制文件进行修改的进程都会持
有此锁

• Id1 始终为 0
• Id2 = 0 表示串行化控制文件的操作
• Id2= 1 表示共享信息的访问

CF 锁 - 使用场景
• 日志文件切换
• 新增 / 删除各种类型的文件 ( 数据文件 , 临
时文件 , 日志文件 )
• 打开 / 关闭 / 备份数据库 , 改变表空间 / 数
据文件的在线状态 , 读写状态
• 转储控制文件中的对象信息 ( 数据文件 , 日
志文件 )
• 修改数据库的 checkpoint 信息 .

JQ 锁
此锁是为了控制对 job 的并发访问与执行
正在运行的 job 才会持有此锁
Id1 始终为 0
Id2 为此 job 的编号 job_no
Dba_jobs_running 是 Oracle 以此为基础创建
的视图 , 可通过此视图确定正在运行的任务 .
• Session 13




– Exec dbms_job.run(3);

SQ- 锁
• 使用此锁来防止多个进程同时刷新 SGA 中的
Sequence 缓存
• Id1 为 sequence 对应的 object_id
• Id2 始终为 0
• 如果 Sequence 的 cache 设置较小 ( 比如选择使用默
认值 ), 就会导致系统会遭遇较多的 SQ enqueue 等
待出现 (taobao 曾经因此出现过故障 )
• 另 , 如果 sequence 使用 nocache, 系统可能会遇到
较严重的 row cache lock, 而不会出现任何 SQ
enqueue 等待

Sign up to vote on this title
UsefulNot useful