暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

队列、锁

原创 木底木叉 云和恩墨 2022-08-11
1292

一、锁分类

  • Data Dictionary Locks (DDL)

    • Row cache locks
    • Library cache locks and pins
  • Data Manipulation Locks (DML)

    • Row locks
    • Table locks

二、队列

2.1、队列概念
  • 队列是由**Kernel Service Enqueues (KSQ)**内核服务层提供的一种服务,供其它层调用。

  • 队列就是管理访问共享资源的锁机制,同时提供访问、转换、释放队列的接口。

  • 如果对不能够访问,用户只能等待或者超时。

2.2、队列确认
  • 队列用锁或者资源名作为唯一名
  • 队列使用如下格式:
select substr(type,1,2),substr(name,1,30),substr(description,1,40)
from v$lock_type


SUBSTR(TYPE, SUBSTR(NAME,1,30)              SUBSTR(DESCRIPTION,1,40)
------------ ------------------------------ --------------------------------------------------------------------------------
SV           Sequence Ordering              Lock to ensure ordered sequence allocati
HV           Direct Loader High Water Mark  Lock used to broker the high water mark
DL           Direct Loader Index Creation   Lock to prevent index DDL during direct
HQ           Hash Queue                     Synchronizes the creation of new queue I
HP           Queue Page                     Synchronizes accesses to queue pages
KL           LOB KSI LOCK                   KSI lock for buffer cache and wgc concur
WG           Write gather local enqueue     Long term lock on wgc file state
SL           Serialize Lock request         Request serialization to LCK0
ZH           Compression Analyzer           Synchronizes analysis and insert into co
SZ           IM segment populate            Lock used to serialize in-memory segment
ZC           IM FastStart Admin             Lock used to serialize in-memory FS task
2.3、队列模式
Mode Internal ID   Value   Description
NULL KSQMNULL       1       Null               --select
SS   KSQMSS         2       Sub-Share          --create index online
SX   KSQMSX         3       Sub-excusive       --delete、update、insert
S    KSQMS          4       Share , Lock Share --Create Index
SSX  KSQMSSX        5       Sub-Share-Exclusive --主表、子表更新相关
X    KSQMX          6       Exclusive           --drop table、delete table

拿TM举例

手工锁定语法
lock table in row share mode RS RS、RX、S、SRX
lock table in row exclusive mode RX RS、RX
lock table in share mode S RS、S
lock table in share row exclusive mode SRX RS
lock table in exclusive mode X RS
2.5、锁测试
2.5.1 锁模式测试

SS锁

sys@orcl> create table t as select * from dba_objects;

Table created

sys@orcl> select * from v$mystat where rownum=1;

  SID STATISTIC#      VALUE     CON_ID
----- ---------- ---------- ----------
  279          0          0          0
  
sys@orcl> lock table t in row share mode;

Table(s) Locked

sys@orcl> select sid,id1,id2,type,lmode,request from v$lock where type in ('TM','TX');

  SID        ID1        ID2 TYPE      LMODE    REQUEST
----- ---------- ---------- ---- ---------- ----------
  279      73472          0 TM            2          0
  
sys@orcl> lock table t in exclusive mode;  --session 1

Table(s) Locked.  

sys@orcl> create index idx_text on t(object_id) online;  --session 2

sys@orcl> select sid,id1,id2,type,lmode,request from v$lock where type in ('TM','TX');

  SID        ID1        ID2 TYPE      LMODE    REQUEST
----- ---------- ---------- ---- ---------- ----------
  262      73472          0 TM            0          2
  279      73472          0 TM            6          0

SS锁额外的一个测试

sys@orcl> create index idx_t on t(object_id);

Index created.

sys@orcl> /

  SID        ID1        ID2 TYPE      LMODE    REQUEST
----- ---------- ---------- ---- ---------- ----------
  279      73472          0 TM            4          0
  279         18          0 TM            3          0
  279     458753      38208 TX            6          0
 
sys@orcl> select object_name from dba_objects where object_id='18';

OBJECT_NAME
------------------------------
OBJ$ 
创建索引的时候拿到的是对象的上的4级锁(S)和OBJ$ 对象上的3级锁(SX)。

sys@orcl> create index idx_t on t(object_id) online;

Index created.

sys@orcl> /

  SID        ID1        ID2 TYPE      LMODE    REQUEST
----- ---------- ---------- ---- ---------- ----------
  279      73472          0 TM            2          0
  279      73477          0 TM            4          0
  279     458759      38203 TX            6          0
online创建的时候在表上加一个2级锁(SS)锁,在73477对象上加4级锁。  

sys@orcl> select object_name from dba_objects where object_id ='73477';

no rows selected

sys@orcl> select object_name from dba_objects where object_name='IDX_T';

OBJECT_NAME
------------------------------
IDX_T

sys@orcl> select object_name,object_id from dba_objects where object_name='IDX_T';

OBJECT_NAME                     OBJECT_ID
------------------------------ ----------
IDX_T                               73476
这里说明上面加4级锁(S)的对象并不是创建的索引的ID,那么他是什么。创建完成已经消失,重新测试一下
sys@orcl> select object_name from dba_objects where object_id ='73480';

OBJECT_NAME
------------------------------
SYS_JOURNAL_73479

online创建索引时会临时创建一个IOT的表,索引创建结束后删除IOT表

SX锁

SQL> select owner,object_name from t where object_id=3 for update;


sys@orcl> select sid,id1,id2,type,lmode,request from v$lock where type in ('TM','TX');

  SID        ID1        ID2 TYPE      LMODE    REQUEST
----- ---------- ---------- ---- ---------- ----------
  279      73472          0 TM            3          0
  279     196618      50795 TX            6          0 
  
sys@orcl> select object_name from dba_objects where object_id='73472';

OBJECT_NAME
------------------------------
T    
这个操作需要获得对象上的3级锁(SX),也需要一个事务锁(TX)保护。
2.5.2、锁兼容性测试
-RS 锁兼容测试
SID ID1 ID2 TYPE LMODE REQUEST

    55      76260          0 TM              2          0
  1042      76260          0 TM              2          0
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              2          0
  1042      76260          0 TM              3          0
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              2          0
  1042      76260          0 TM              4          0
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              2          0
  1042      76260          0 TM              5          0
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              2          0
  1042      76260          0 TM              0          6
-RX锁兼容测试
SID ID1 ID2 TYPE LMODE REQUEST

    55      76260          0 TM              3          0
  1042      76260          0 TM              2          0
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              3          0
  1042      76260          0 TM              3          0
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              3          0
  1042      76260          0 TM              0          4
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              3          0
  1042      76260          0 TM              0          5
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              3          0
  1042      76260          0 TM              0          6
S锁兼容测试
SID ID1 ID2 TYPE LMODE REQUEST

    55      76260          0 TM              4          0
  1042      76260          0 TM              2          0
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              4          0
  1042      76260          0 TM              0          3
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              4          0
  1042      76260          0 TM              4          0
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              4          0
  1042      76260          0 TM              0          5
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              4          0
  1042      76260          0 TM              0          6
--SSX锁兼容
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              5          0
  1042      76260          0 TM              2          0
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              5          0
  1042      76260          0 TM              0          3
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              5          0
  1042      76260          0 TM              0          4
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              5          0
  1042      76260          0 TM              0          5
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              5          0
  1042      76260          0 TM              0          6
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              6          0
  1042      76260          0 TM              0          2
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              6          0
  1042      76260          0 TM              0          3
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              6          0
  1042      76260          0 TM              0          4
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              6          0
  1042      76260          0 TM              0          5
SQL> /

   SID        ID1        ID2 TYPE        LMODE    REQUEST
    55      76260          0 TM              6          0
  1042      76260          0 TM              0          6

总结:

2和所有除了6,3和23,4和24,5和2,6不和任何兼容

2.5.3、创建索引阻塞测试
sys@orcl> create index idx_t on t(object_id);

sys@orcl> update t set object_name='test';

sys@orcl> select sid,id1,id2,type,lmode,request from v$lock where type in ('TM','TX');

  SID        ID1        ID2 TYPE      LMODE    REQUEST
----- ---------- ---------- ---- ---------- ----------
   46      73472          0 TM            0          3
  279      73472          0 TM            4          0
  279         18          0 TM            3          0
  279     524315      50759 TX            6          0
279会话在对象73472上加4级锁,46请求73472上的3级锁,4与3级不兼容,所以46需要等279完成。

三、资源和队列

  • 队列由会话(不是进程)申请、释放、转换.

  • 任何时间锁都有可能被会话申请、持有或者转换。

  • 任何队列都是一个资源结构(ksqrs)。它维护所有者、等待者和转换者的列表

  • 每个所有者、等待者和转换者都有一个锁结构(ksqlk)。

  • 队列类型

    • 用户队列
      • 锁结构由客户端层分配
      • 比如TM
    • 管理队列
      • 锁结构由KSQ 自己分配
      • 比如MR
        以下 3 种入队类型被定义为“用户类型”锁:

TM - DML(表操作)针对需要协调的各种表/分区操作的基表或分区调用排队。
TX - 用于保护交易信息的交易队列。
UL - 当应用程序使用 DBMS_LOCK 包时使用的用户锁定队列。

系统入队

BF enqueue      --------------------------enq: BF - contention sql语句并行访问过滤器争用
CF Controlfile Enqueue            --------enq: BF - contention 对控制文件的共享部分进行读写
DX Distributed Transaction Enqueue -------enq: DX - contention 分布式事务相关
FB Block Format Enqueue            -------enq: FB - contention 确保只有一个进程可以格式化块
HW High Water Enqueue			   -------enq HW - contention 超出段的高水位线的空间分配
JS Job Scheduler Enqueue		   -------没见过
RO Fast Object Reuse Enqueue	   -------enq: RO - fast object reuse 删除对象或截断表
SQ Sequence Cache Enqueue		   -------enq: ST – contention  序列争用
ST Space Transaction Enqueue	   -------enq: ST – contention 字典管理的表空间中的空间管理活动
TO Temporary Table Object Enqueue  -------enq: TO – contention 临时段对象争用
TT Tablespace Operations Enqueue   -------TT Enqueue Contention  resize数据文件出现
US Undo Segment Enqueue            --------enq: US - contention	undo争用
enq: DW - contention 与 SecureFile LOBS 和获取 In-Memory Dispenser Latch 相关
enq: DA - Slave Process Array 生成从属进程

四、状态对象

  • 所有锁结构都嵌入到状态对象中,以允许PMON在进程失败时恢复

  • 客户端锁结构嵌入到自定义状态对象中,比如

    • DML锁(TM)结构嵌入在DML锁状态对象中。
    • 事务(TX)锁结构嵌入在事务状态对象中。
  • 管理的锁结构嵌入在排队状态对象中。

五、Hashing and Latching

  • 所有的资源结构都存在于源表
  • 需要通过hash从资源表寻找资源结构
  • 资源名hash为hash bucket(ksqht)
  • hash bucket管理一条hash 链
  • hash 链被多个latch保护

六、资源空闲列表

  • 为了实现重用,未使用的资源结构被放置在链表上,称为资源空闲列表
  • 空闲资源列表中的操作由排队闩锁覆盖。

七、锁请求

  • 当会话获得它没有的锁时,就会发生锁获取。

  • 在以下情况下,允许会话获取锁:

    • 前面没有转换者或等待者。
    • 请求的模式与其他会话已经拥有的模式兼容。
  • 采集步骤:

    • 定位资源结构
    • 获得自由锁结构。
    • 为请求的资源填充它。
    • 将锁结构链接到资源结构。

八、锁转换

  • 当会话请求更改当前持有的锁的模式时,会发生锁转换。

  • 如果会话请求的模式满足以下条件,则允许会话转换锁:

    • 是它已持有的模式的子集
    • 与其他人持有的模式兼容

九、锁释放

  • 始终允许会话释放其在资源上的锁。

  • 释放操作:

    • 定位资源结构。
    • 取消锁定结构与资源的链接。
    • 将锁结构链接到无锁列表。
    • 通知下一个转换器或服务员(如果有)。

十、队列操作

  • 当请求新锁时,Oracle服务器会检查队列,以验证是否可以授予该请求。

  • 当锁被释放或转换时,还将重新检查转换者和等待者,以确定是否可以获得它们。

  • 首先处理转换队列,然后处理等待者队列。

十一、 Wait Event: Enqueue

  • 当会话正在等待本地排队时,可以发现它正在等待排队等待事件

  • 这可以通过查询V$SESSION WAIT看到

    select * from   v$session_wait  where  event = 'enqueue';
    
  • 优化Enqueue Waits

  • 排队等待的调整取决于引起等待的排队类型。可能的方法:

    • 减少排队请求的数量。
    • 减少排队等待的时间。

十二、死锁检测

  • 如果等待后未获取或转换锁,则通过调用ksqded()进行死锁检查。

  • 从请求锁的会话开始,此函数扫描正在查找阻塞会话的所有队列。

  • 递归地,通过阻塞会话再次调用该函数,并构建依赖关系网络。

  • 当递归调用重新访问会话并发出ORA-60信号时,就会发生死锁。

十三、状态对象dump

状态对象转储中的信息提供了有关排队的重要信息:

  • 锁结构嵌入在状态对象中,可以在系统或进程状态转储中找到。

  • 排队的名称与保持的模式(mode)和请求的模式(req)一起显示。

  • 这表明它位于哪个队列中:

    • 持有者:mode only
    • 等待者:req only
    • 转换者:mode and req

十四、队列dump

  • 语法
alter session set events 'immediate trace name enqueues level 3';
level 1:转储活动资源和锁的摘要、资源空闲列表和哈希表 
level 2:加资源结构
level 3:锁结构
2022-08-01 23:30:11.307*:ksq.c@11174:ksqdme():
===================================================
ENQUEUES
--------

Active:    lock: (nil), resource: (nil)
Global:    name: ORCL
Hash:      length: 979, at: 0x6e584d60
           [6e584d60,6e584d60] [6e584d90,6e584d90] [6e584dc0,6e584dc0]
           [6e584df0,6e584df0] [6e584e20,6e584e20] [6e584e50,6e584e50]
           [6e584e80,6e584e80] [6e584eb0,6e584eb0] [6e584ee0,6e584ee0]
"/u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_11649.trc" 863L, 41550C                                                   1,1           Top
  # of incomp w/ SS waiters: 0

lock details:

  lock                     lst hold wait   sid:ser   owner      link
  -------------------------------------------------------------------------
  L1: 0x6bb28428 OWN    X   --   279:43114 0x6f8e9c38 [6e5556d0,6e5556d0]

2022-08-01 23:30:11.326*:ksq.c@11007:ksqdmpres():
Enqueue Resource Dump
-------------------------------------------------------------------------
TM-00011F00-00000000-00000000-00000000

res: 0x6e5571f0 , flags: (0x16) ALO/-/USR/-/-/-
  held counts: NULL=0 , SS=0 , SX=0 , S=1 , SSX=0 , X=0 (bmask: 0x10)
   lock value: 00000000 00000000 00000000 00000000
  htb(0x6e5571f0): [6e58ed80,6e58ed80]
  own(0x6e557200): [6b9f1f88,6b9f1f88]
  cnv(0x6e557220): [6e557220,6e557220]
  wtr(0x6e557210): [6e557210,6e557210]

lock summary:
  OWN: L1:S
  CNV:
  WTR:
  # of incomp w/ SS converters: 0
  # of incomp w/ SS waiters: 0

lock details:

  lock                     lst hold wait   sid:ser   owner      link
  -------------------------------------------------------------------------
  L1: 0x6b9f1f78 OWN    S   --   279:43114 0x6f8e9c38 [6e557200,6e557200]

十五、诊断 V$LOCK

  • V$LOCK包含系统中当前持有的所有锁结构的列表。

  • TYPE ID1和ID2可用于连接V$RESOURCE。

  • LMODE和REQUEST指示会话正在等待的队列,如下所示:

    LMODE > 0, REQUEST = 0 owner

    LMODE = 0, REQUEST > 0 waiter (acquirer)

    LMODE > 0, REQUEST > 0 converter

十六、诊断 V$RESOURCE

  • V$RESOURCE提供了系统中当前锁定的所有资源结构的列表。

  • 每一行与V$LOCK中的一行或多行相关联。

  • VRESOURCE基于XKSQRS。

十七、V$LOCKED_OBJECT

  • V$LOCKED_OBJECT显示系统中对象上的所有锁(TM锁)。

  • 提供以下交叉参考信息:

  • 与锁定会话运行的事务相关联的回滚段(如果有)

  • 操作系统级别的用户名

  • 进程ID

最后修改时间:2022-08-18 22:04:03
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论