zoukankan      html  css  js  c++  java
  • OCP知识点讲解 之 队列、资源与锁:RHCA|OCM|CCIE RedHat大中华地区前50位RHCA系统架构师:叶绍琛

     

     

    一、队列与共享资源

         共享资源可以被多个会话、进程同时访问,因此它的访问需要保护。Oracle中,除了PGA,所有的东西(包括内存、磁盘、CPU、表、索引、事务等等,种类太多,一概用东西两字来代表)都是共享资源。多个进程或会话对共享资源操作时,就需要排队。这里所需要排的队就是队列(Enqueue)。访问不同的共享资源,需要排不同的队。可以这样说,有多少种队列,就有多少种需要保护的共享资源。队列的名字一般是两个字节构成,如TMTXJQ,……。具体所有队列的种类、名字,参见V$LOCK视图介绍中的附表。

     

     

    二、队列标识

         我们以TM为例,它是DML队列锁。在对表作DML操作时,需要先在此排队,正式点的说法是:需要先获得TM队列锁。TM也被称作表锁,因为它主要是在对表作操作是获得的。如果数据库中有1000个表,针对这一千个表,并非只有一个队列,要是这样的话也不太合理。1000个表,就应该有1000TM队列,这样才附合常理。如果一千个队列都叫TM,将来操作时不好区分,因此,需要为这一千个TM队列分别名命,这个名字,也被称为队列标识。TM队列的命名格式为:TM-OID-0。其中OIDObject ID,即对象ID。最后一部分一般都是0。假如AA表的OID6636,它的队列标识就是TM-6636-0

         每种队列的命名格式各不相同,总的来说是“队列名-ID1-ID2”,ID1ID2分别是两个参数,对于TM队列来说,ID1OIDID20

     

     

    三、资源结构

         继续我们上面的假设,如数据库中有一千个表,这就要对应一千个TM队列。但只有当操作到哪个表了,才会为它建立相关的队列信息。比如会话发布了对AA表的更新操作,需要在SGA中为AA建立相关的TM队列信息。这些相关AATM信息,也被称为“资源结构”(KSQRSKSQ是内核服务队列的简写,RSResource Structure的简写,即资源结构)。每一个资源结构维持一个所有者、等待者和转换者的列表。如下图:

    资源结构前的即是队列标识,也可以作为资源结构标识(资源标识)。

    每一个所有者、等待者和转换者有一个锁结构(Ksqlk),简单点说每一个所有者、等待者和转换者有一个链表,此链表由会话、锁模式等信息构成,具体描述了什么会话以什么模式获得此资源结构。具体如下:

         1)如果会话获得锁,锁结构将在所有者列表上

         2)如果会话正在等待获得锁,锁结构将在等待者列表上

         3)如果锁已被获得,但会话正在等待它被转换到一种不同的模式,锁结构将在转换者列表上

         所有资源结构组成一个资源表,资源表和资源结构上的锁都被分配在SGA中。资源表中总的行数由初始化参数ENQUEUE_RESOURCES决定,且资源表中的行可以在X$KSQRS中被看到。正在被使用的将在V$RESOURCE中显示。还可以在v$resource_limit中看到资源结构数量的限制和使用情况:

    sid=9 pid=10> select * from v$resource_limit where resource_name = 'enqueue_resources';

    RESOURCE_NAME CURRENT_UTILIZATION MAX_UTILIZATION INITIAL_ALLOCATION   LIMIT_VALUE

    ------------------------------ ------------------- --------------- -------------------- -------------

    enqueue_resources          32              32        968            UNLIMITED

     

         可以看到,当前使用了32个资源结构,最多时使用了32个资源结构,初始化参数中分配了968个资源结构。最多使用是UNLIMITED,没有限制。由于Oracle 9i采用的算法,我们在X$KSQRS中看到的总行数并不是968,而是992。为确保重用,资源表中未用的资源结构被放置在一个连接列表,称为:Resource Free List。我们可以发布一些更新声明,不要提交,这样占用的TMTX资源结构一直不会释放。观察X$KSQRSTM资源结构的占用增多,但视图的总行数不变,还是992。新增的TMTX资源结构占用了其他已经释放的资源结构。

     

     

    四、资源结构哈希表

         为了在资源表中快速找到某一资源结构,Oracle当然还是要使用HASH算法。Oracle根据资源标识计算HASH值。当然,和Library cache一样,资源表中已被占用的资源结构的HASH值构成了一个个HASH Buckut

      上图就是HASH Bucket和资源结构的图,可以看到和Library cache中的很像。HASH算法吗,所有的HASH算法都会有很多共同点。从上图中可以看到,想访问Hash Bucket,需要Enqueue hash chain闩,它需要保护上图中的HASH表,和每个Hash Bucket后的Hash链。它的数量由隐含参数_enqueue_hash_chain_latches控制。Enqueue hash chain闩类似于Buffer cache chain闩。它们都是一个闩要管理多个哈希桶,不过Enqueue hash chain更特殊,在单CPU环境中,只有一个,却要管理所有的哈希桶,这是因为队列的争用,毕竞比Buffer要小的多。

      Oracle中所有关于HASH的算法,都要有HASH表、HASH链和保护HASH链的闩,HASH表不需要保护,这是因为HASH表是大小固定的数组。每一个数组元素就是一个Hash Bucket。每个哈希桶的哈希值也都是事先定好的。因此不存在对哈希桶的更改,如插入一个哈希桶、修改一个哈希桶的哈希值或删除一个未使用的哈希桶等等,这些操作都是不存在的。因此,既然不会有修改操作,哈希表就不需保护。需要保护的是每个哈希桶后的链。每个桶后的链中,都可以挂多个对象,我们可能向链上添加或删除对象,既然有修改,就需要保护。

      队列资源Hash表的长度由_enqueue_hash控制,其始值来源于SESSION参数,初始是375。我们的资源表共有992行,而哈希桶只有375个,这必然会有多个资源结构排在某一个哈希桶后面。如果曾经增加过ENQUEUE_RESOURCES的值,也就是说,资源结构比系统默认的还要更多一些,但控制哈希表长度的_enqueue_hash参数值如果不跟着增加。这就意味着每个哈希桶下要挂接更多的资源结构,这有可能因起Enqueue hash chain闩的竞争。如何观察闩的使用情况这是下一章节的内容,这里就不多说了。_enqueue_hash的初始值是根据Sessions参数来定的,计算公式如下:((sessions-10)*2)+55,默认 ((170-10)*2)+55,正好等于375,它并不随ENQUEUE_RESOURCES的增加而增加。

     

      队列、资源结构和锁结构的关系如上图。上图是分别在两个会话中发布如下声明后的结果:

      在会话10sid=10 pid=11> insert into a1 values(1,1,1);

    已创建 行。

      在会话12sid=12 pid=12> insert into a1 values(2,2,2);

    已创建 行。

      查看哈希表视图:

    sid=9 pid=10> select * from v$resource where type ='TM';

    ADDR     TY        ID1        ID2

    -------- -- ---------- ----------

    7B6D5C40 TM       6657          0

    可以看到,有一个TM队列,地址是7B6D5C40,对象ID6657,这个正是A1表。

    查看V$LOCK视图:

    sid=13 pid=13> select * from v$lock where sid>=8;

    ADDR  KADDR     SID   TY        ID1     ID2  LMODE    REQUEST      CTIME      BLOCK

    -------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------

    7AF661FC 7AF66308        10 TX     458765       2212          6          0        452          0

    7AF3A074 7AF3A088       10 TM       6657          0          3          0        452          0

    7AF837AC 7AF838B8       12 TX     327686       2355          6          0         84          0

    7AF3A17C 7AF3A190      12 TM       6657          0          3          0         84          0

      上面的结果中显示,TM-6657-0有两个锁,地址分别是7AF3A088、7AF3A190。

      说明,上图中的信息,部分来自于队列结构的DUMP,声明如下,有兴趣可以自己试试。

      sid=10 pid=11> alter session set events 'immediate trace name enqueues level 4';

      哈希表的长度,由_enqueue_hash设定,资源结构的数量(也称资源表的长度),由ENQUEUE_RESOURCES设定。锁结构的的数量,也可以由DBA控制,隐含参数_enqueue_locks就是设置锁结构数量的(也称队列锁:Enqueue Lock),默认值2230。可以被看到在X$KSQEQ中,正在被使用的在V$ENQUEUE_LOCK显示。但是,有关TMTX这两个队列的锁和其他情况的队列锁不一样,除非它们发生了Enqueue等待,否则它们并不在X$KSQEQ结构中显示,因此在X$KSQEQ之上的V$ENQUEUE_LOCK也没有正在使用中的TXTM队列锁的情况。Oracle使用不同的结构来管理TXTM排除。TXX$KTCXB,内核事务控制事务对象,V$TRANSACTION_ENQUEUE的基础视图。它的尺寸由transactions初始化参数控制。有关TX的我们下面专门再说。再看TMX$KTADM,内核事务访问定义DML锁。X$KTADM的尺寸由DML_LOCKS定义,也就是TM锁的数量。X$KTADMDBA意义不大,可以为我们提供锁的模式、加锁的时间、正在请求的模式、会话SID等信息,信息量并不比V$LOCK中多。通过上两个X$视图观察正在使用中的TMTX锁的最好办法是:

    set linesize 800

    col KTCXBNAM for a20

    select * from x$ktcxb where ktcxblkp in (select kaddr from v$lock where type='TX');

     

    select * from x$ktadm where ksqlkadr in ( select kaddr from v$lock where type='TM');

     

    我们也可以在V$RESOURCE_LIMIT中看到有关队列锁的使用情况:

    sid=9 pid=10> select * from v$resource_limit where resource_name like 'enqueue%';

    RESOURCE_NAME CURRENT_UTILIZATION MAX_UTILIZATION INITIAL_ALLOCATION   LIMIT_VALUE

    ------------------------------ ------------------- --------------- -------------------- -------------

    enqueue_locks                26              30       2230                 2230

    enqueue_resources             26              26       1200            UNLIMITED

    注意enqueue_locks和transactions、DML_LOCKS的关系,enqueue_locks是总的队列锁的数量,transactions定义了在总的队列锁中,TX锁的数量,DML_LOCKS是总队列锁中TM锁的数量。也就是说transactions和DML_LOCKSenqueue_locks的一部分。

  • 相关阅读:
    一行代码更改博客园皮肤
    fatal: refusing to merge unrelated histories
    使用 netcat 传输大文件
    linux 命令后台运行
    .net core 使用 Nlog 配置文件
    .net core 使用 Nlog 集成 exceptionless 配置文件
    Mysql不同字符串格式的连表查询
    Mongodb between 时间范围
    VS Code 使用 Debugger for Chrome 调试vue
    css权重说明
  • 原文地址:https://www.cnblogs.com/zengkefu/p/5840385.html
Copyright © 2011-2022 走看看