You are on page 1of 31

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 6 Exclusive 模式 , 对全表持独占模式
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 等待

You might also like