Your SlideShare is downloading. ×
Enqueue Lock介绍.ppt
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Enqueue Lock介绍.ppt

3,526
views

Published on


0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
3,526
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
152
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • 其他锁的类型 , 可参考 www.akadia.com/download/documents/session_ wait _ events .pdf 如果数据库版本为 11g 及以上 , 可以查询试图 v$lock_type 来得到 .
  • Enqueue resource 结构由参数 enqueue_resources 确定 , 此值为一个初始值 , 其内容可通过 x$ksqrs (Kernel Service enQueue ReSource) 或者 v$resource 来查询 Enqueue lock 结构由隐含参数 _enqueue_locks 确定 , 此值在系统启动后不可更改 , 其内容可通过 x$ksqlk (Kernel Service enQueue LocK) 或 v$enqueue_lock 来查询 . Enqueue Resource 的资源结构由 Latch “enqueue hash chain” 来控制访问 . Enqueue Lock 的锁结构由 Latch “enqueues” 来控制访问 这两种资源的使用情况以及数量限制可通过查询 v$resource_limit 来获得 .
  • Hash Bucket 的数量由参数 _enqueue_hash 控制 , 默认根据文件数 ,session 数据计算而来 . _enqueue_hash = 45 + 2 * ( PROCESSES + trunc(PROCESSES/10) ) 摘自 Steve Adams (Oracle 8i Internal Service,Page 50). 管理此 Hash Chain 的 Latch 为 enqueue hash chains,child latch 的数量由参数 _enqueue_hash_chain_latches 控制 , 默认值为 CPU 个数
  • 操作 Enqueue Resource 都需要获取 enqueue hash chains latch. 操作 Enqueue Lock 都需要获取 enqueues latch
  • 在释放完毕 Enqueue Lock 之后 , 如果有 converter , 则先通知 converter, 否则通知最早等待的那个 waiter.
  • 我自己测试一般都是 Alter session set events ‘10704 trace name context forever , level 10’;
  • 内容摘自 www.dbthink.com/?p=452 相关过程我自己做了测试 . 下面是持有锁的时间顺序 Lock table in SubShare mode Lock table in Share mode (very short time if not been blocked by others) Lock table in subShare mode Processing index rebuild Lock table in Share mode (very short time if not been blocked by others) Lock journal table in Exclusive mode (drop the journal table)
  • select * from v$lock where sid in (10,14); ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK 173D44A8 173D45B4 10 TX 262174 5398 6 0 37 1 17377074 17377088 10 TM 6279 0 3 0 37 0 173770F8 1737710C 14 TM 6279 0 3 0 22 0 17AE7288 17AE7298 14 TX 262174 5398 0 6 22 0 select sid,seq#,event,p1text,p1raw,p2text,p2,p3text,p3 from v$session_wait where sid in (14); SID SEQ# EVENT P1TEXT P1RAW P2TEXT P2 P3TEXT P3 14 17112 enqueue name|mode 54580006 id1 262174 id2 5398
  • select * from v$lock where sid in (10,14) ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK 173D44A8 173D45B4 10 TX 589835 6969 6 0 16 1 17377074 17377088 10 TM 6279 0 3 0 16 0 173ADA20 173ADB2C 14 TX 196633 6878 6 0 10 0 173770F8 1737710C 14 TM 6279 0 3 0 10 0 17AE7288 17AE7298 14 TX 589835 6969 0 4 10 0 select sid,seq#,event,p1text,p1raw,p2text,p2,p3text,p3 from v$session_wait where sid in (14); SID SEQ# EVENT P1TEXT P1RAW P2TEXT P2 P3TEXT P3 14 17225 enqueue name|mode 54580004 id1 589835 id2 6969
  • 创建一个 maxtrans 为 2 的表 , 表上的最小事务槽数量是 2 create table james_itl (id number,value varchar2(20)) maxtrans 2; 2. 往表中插入一定量的数据 , 找到 3 条位于同一 block 的记录 .( 比如 id 为 1,2,3 的三条记录 ) select rownum,dbms_random.string('l',15) from dual connect by level <= 1e3; select dbms_rowid.rowid_block_number(rowid) block_no,id,value from james_itl where rownum <= 5; BLOCK_NO ID VALUE 4701 1 dycxkqfjwnfmjcn 4701 2 irujlsgaesqsifx 4701 3 iujdkpwocphgewc 4701 4 clxxlwytqxvoufq 4701 5 oodfrpbgqpxybnh 3. 在三个不同的 session 分别更新这 3 条记录 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; 4. 通过 v$lock,v$session_wait 检查锁的级别 select * from v$lock where sid in (10,13,14); ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK 173D40CC 173D41D8 10 TX 196647 6879 6 0 58 1 17377074 17377088 10 TM 6391 0 3 0 58 0 1737717C 17377190 13 TM 6391 0 3 0 54 0 17AE7288 17AE7298 13 TX 196647 6879 0 4 50 0 173ADA20 173ADB2C 14 TX 393226 4744 6 0 56 0 173770F8 1737710C 14 TM 6391 0 3 0 56 0 select sid,seq#,event,p1text,p1raw,p2text,p2,nvl(p3text,'xx') p3text,p3 from v$session_wait where sid in (10,14,13); SID SEQ# EVENT P1TEXT P1RAW P2TEXT P2 P3TEXT P3 13 66 enqueue name|mode 54580004 id1 196647 id2 6879 10 35567 SQL*Net message from client driver id 42455100 #bytes 1 xx 0 14 17472 SQL*Net message from client driver id 42455100 #bytes 1 xx 0
  • 测试方式 : 在一个 uniform size 较小 ( 例如 128k) 的表空间中创建一个行记录本身很大的表 . 在几个 Session 同时对此表做大批量的数据插入操作 . 检查 v$enqueue_stat 查看 hw enqueue 的发生情况 Create tablespace test_128k datafile ‘ +datadatafile est_128k01.dbf’ size 1024m Extent management local uniform size 128k; Create table james_128k (id number,col1 varchar2(4000),col2 varchar2(4000),col3 varchar2(4000),col4 varchar2(4000)) tablespace test_128k; 在几个 session 中同时执行下面的插入语句 . Insert into james_128k Select rownum id,dbms_random.string(‘l’,4000) col1, dbms_random.string(‘l’,4000) col2, dbms_random.string(‘l’,4000) col3, dbms_random.string(‘l’,4000) col4 From dual Connect by level <= 1e5;
  • *1 select segment_id,segment_name from dba_rollback_segs;
  • 在 session 1 中创建全局临时表 , 并执行 dml 插入部分数据到临时表中 create global temporary table james_to on commit preserve rows as select * from obj; 2. 在 session 2 中对此临时表分别执行插入 ,truncate 以及在此表上创建索引的操作 . 对应的锁等待如下所示 Insert into james_to select * from obj; ksqcmi: TM,18e0,0 mode=3 timeout=21474836 ksqcmi: returns 0 *** 2010-07-25 21:43:06.000 ksqcmi: TO,18e0,1 mode=3 timeout=21474836 ksqcmi: returns 0 对此表执行 drop 操作 *** 2010-07-25 21:44:08.000 ksqcmi: TO,18e0,1 mode=6 timeout=0 ksqcmi: returns 51 对此表执行创建索引操作 ksqcmi: TO,18e0,1 mode=4 timeout=0 ksqcmi: returns 51
  • select * from v$lock where sid in (13); ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK 17AE7288 17AE7298 13 JQ 0 3 6 0 272 0 select * from dba_jobs_running; SID JOB FAILURES LAST_DATE LAST_SEC THIS_DATE THIS_SEC INSTANCE 13 3 07/25/2010 23:58:24 23:58:24 0
  • Transcript

    • 1. Enqueue Lock 介绍 [email_address] http://www.dbthink.com/
    • 2. 内容介绍
      • 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)
    • 3. 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)
    • 4. 锁资源标识符 Enqueue Resource Identifier
      • 每个 Enqueue Lock 都有一个唯一名称 , 这个名称也被成为锁名称或资源名称
      • 标识符的格式为 <type-id1-id2>
        • Type 由有两个字母组成 , 如” TM”,”TX”
        • Id1 与 id2 为正的数字 (4 个字节长 )
      • 下面分别是一个 TX 锁与 TM 锁的例子
        • TX-393237-184
        • TM-6317-0
    • 5. 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 模式 , 对全表持独占模式
    • 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
    • 7. Enqueue Resource & Enqueue Lock
      • Enqueue 的获取 / 转换 / 释放操作都是由 Session 操作的 ( 而不是 Process)
      • 当一个 Session 持有一个 Enqueue 的时候 , 同时也可能有其它 Session 在请求持有或转换 Enqueue 模式
      • 每个 Enqueue 都有一个资源结构与其对应 , 由它来管理持有者 (Owners), 等待者 (Waiters) 以及请求转换模式者 (Converter).
      • 每个 Owner/waiter/Converter 都有一个对应的锁结构
    • 8. Enqueue Resource 结构
    • 9. Enqueue Hash 与 Latch
      • 所有的 Enqueue Resource 都属于一个 Resource 表 (X$ksqrs,v$resource).
      • Oracle 使用 hash 来访问数据库中的 Enqueue Resource.
      • 每个 Hash bucket 都包含一个资源链表 (Hash Chain)
      • 每个 Hash Chain 都有一个或多个 Latch 来控制访问 .
    • 10. 获取 Enqueue Lock 的步骤
      • 计算 hash 值 , 确定所需访问资源所在的链表
      • 得到对应的 enqueue hash chains latch
      • 定位此资源 , 如果不存在 , 则在空闲资源列表中取一个放到此处
      • 获取 enqueues latch
      • 获取一个空闲的 Lock 结构
      • 将此 Enqueue Lock 对应的信息填充进去
      • 将此 Lock 结构挂到此 Enqueue Resource 结构上
      • 释放 enqueues latch
      • 释放 enqueue hash chains latch
    • 11. 获取 Enqueue Lock 的步骤 (2)
    • 12. 释放 Enqueue Lock 的步骤
      • 计算 hash 值 , 确定所需访问资源所在的链表
      • 得到对应的 enqueue hash chains latch
      • 定位此资源
      • 获取 enqueues latch
      • 将 lock 结构从 Enqueue Resource 结构上取出
      • 释放 Enqueues latch
      • 通知处在等待 ( 转换 ) 队列上的进程 ( 如果有的话 )
      • 如果可能 , 释放此 Enqueue Resource, 并将其放入空闲资源列表
      • 释放 enqueue hash chains latch
    • 13. 死锁的检测 (dead-lock)
    • 14. Enqueue Lock 转储
      • alter session set events 'immediate trace name enqueues level x‘
        • Level 1 转储当前活动资源与锁的概要信息 , 资源空闲列表以及哈希表
        • Level >= 2 加上资源结构 (Resource Structure) 的转储信息
        • Level >= 3 加上锁结构 (Lock Structure) 的转储信息
    • 15. Enqueue Lock 的事件跟踪
      • Alter session set events ‘10704 trace name context forever,level x’;
      • 当打开此等待事件 , 将输出请求 Enqueue 的操作信息 , 以及请求相关的参数
      • X 表示等待事件的级别 , 具体说明如下
        • 1-4 打出 ksqlrl,ksqcmi 的基本信息
        • 5-9 还打出 ksqlac,ksqlop 等回调信息
        • 10+ 还打出每个操作对应的时间信息
    • 16. 相关动态视图介绍
      • 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 完全来自此视图 ) 查找当前被锁住的对象 .
    • 17. 相关视图介绍
      • 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
        • 显示当前持有 / 被阻塞的锁的等待树
    • 18. TM 锁
      • 当对表以及表的分区进行操作时就会持有此表上的 TM 锁 .
      • 相关操作包含
        • 修改表中的数据
        • 调整表上的约束
        • 调整表对应的索引
        • 分析表上的统计信息或者 validate structure
        • 并行 dml 操作
      • Id1 为此对象的 object_id(dml_locks>0)
      • Id2 始终为 0
    • 19. TM 锁 - 相关锁 mode 对应的操作
      • 表上发生 dml 操作时 , 持有的 TM mode 为 3(SubExclusive)
      • 修改表结构时持有锁 mode 为 6
      • 对表上的索引做 rebuild 或者创建索引时持有的锁 mode 为 4
      • 当对表做并行插入时需要持有的锁 mode 为 6, 此时后续的所有 dml 操作都会被阻塞
    • 20. TM 锁 -online create/rebuild index
      • Rebuild 命令尝试获取一个对应表上的 Share 锁 ( 之前会获取一个 SubShare 锁 ), 接着就会因等待当前表上还未完成的事务结束 .
      • 当前表上的所有事务结束 , 所有在 rebuild 命令之后的事务都被 Rebuild 持有的锁阻塞
      • rebuild 命令获得它的锁 , 准备物化视图日志 (MV log), 开始重建过程 , 并释放之前持有的锁
      • 所有等待的事务继续执行
      • 重建过程做大量的表扫描以及排序以准备此索引 , 并将排好序的索引复制到其目标存储位置
      • Rebuild 命令尝试再次获取一个表上的 Share 锁 , 并阻塞以等待表上当前的所有事务运行结束
      • 表上的所有当前事务运行结束 , 所有的新事务阻塞在此 Rebuild 锁之后
      • Rebuild 命令获得它请求的锁 , 应用 Rebuild 开始到此锁获得之间的所有变更到新的索引上 , 删除物化视图日志 (MV log) 与旧的索引 , 并释放持有的锁 .
      • 所有等待的事务继续执行
    • 21. TX 锁
      • 当事务开始时持有此锁 , 知道事务被提交或者回滚才释放此锁 .
      • 当 Pmon/Smon 需要回滚出现异常的事务时也会持有 Exclusive mode 的事务锁
      • 主要用来保护事务变更的记录不被并发修改
      • Id1 为 undo segment number << 16 | slot
      • Id2 为此事务的 sequence
      • 由 id1,id2 的值组合出事务编号 usn.slot.seq
    • 22. 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;
    • 23. 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');
    • 24. 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;
    • 25. HW 锁
      • 此锁主要用来控制特定对象空间分配时的并发操作
      • Id1 为表空间的编号 ts#
      • Id2 需要分配空间的对象 segment header 的相对 DBA(Data Block Address) 位置
      • 争用主要发生在大量插入时 , 或手工对该对象 allocate/deallocate 空间时
    • 26. 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.
    • 27. TO- 锁
      • TO 锁主要是用来防止对临时表的并发操作
        • 当针对临时表做 alter,drop,create 操作时 , 会对此临时表取 TO 的 Exclusive mode 锁
        • 当对此临时表做 DML 时获取 SX 锁
        • 对此临时表的 index 做 ddl 操作时获取 S 锁
      • Id1 为此临时表的 object_id
      • Id2 始终为 1
    • 28. CF 锁 - 说明
      • 与控制文件修改相关的锁
        • 串行化对控制文件的修改
        • 任何涉及到对控制文件进行修改的进程都会持有此锁
      • Id1 始终为 0
      • Id2 = 0 表示串行化控制文件的操作
      • Id2= 1 表示共享信息的访问
    • 29. CF 锁 - 使用场景
      • 日志文件切换
      • 新增 / 删除各种类型的文件 ( 数据文件 , 临时文件 , 日志文件 )
      • 打开 / 关闭 / 备份数据库 , 改变表空间 / 数据文件的在线状态 , 读写状态
      • 转储控制文件中的对象信息 ( 数据文件 , 日志文件 )
      • 修改数据库的 checkpoint 信息 .
    • 30. JQ 锁
      • 此锁是为了控制对 job 的并发访问与执行
      • 正在运行的 job 才会持有此锁
      • Id1 始终为 0
      • Id2 为此 job 的编号 job_no
      • Dba_jobs_running 是 Oracle 以此为基础创建的视图 , 可通过此视图确定正在运行的任务 .
      • Session 13
        • Exec dbms_job.run(3);
    • 31. SQ- 锁
      • 使用此锁来防止多个进程同时刷新 SGA 中的 Sequence 缓存
      • Id1 为 sequence 对应的 object_id
      • Id2 始终为 0
      • 如果 Sequence 的 cache 设置较小 ( 比如选择使用默认值 ), 就会导致系统会遭遇较多的 SQ enqueue 等待出现 (taobao 曾经因此出现过故障 )
      • 另 , 如果 sequence 使用 nocache, 系统可能会遇到较严重的 row cache lock, 而不会出现任何 SQ enqueue 等待