• RAC上,对于buffer cache的全局锁,称为PCM锁,当然,对于enq,lc的锁,称为non-PCM锁


    RAC上,对于buffer cache的全局锁,称为PCM锁,当然,对于enq,lc的锁,称为non-PCM锁
    锁的资源在GRD(旧称DLM)中维护,PCM通过GCS在GRD中维护

    v$dlm_ress中,记录着GRD中的所有资源,对于PCM锁,其名称为[ID1][ID2][BL],第三位BL是固定的,代表buffer locks的意思
    v$lock_element中,记录了当前的锁对象,锁对象用于对资源加锁。
    这两个视图中,包含了PCM锁和non-PCM锁的所有信息

    例如,查看资源[0x7870][0x30000],[BL]对应的数据块

    SQL> SELECT * FROM GV$DLM_RESS WHERE resource_name  LIKE '%7870%[BL]%';

       INST_ID RESP     RESOURCE_NAME                  ON_CONVERT_Q ON_GRANT_Q PERSISTENT_RES MASTER_NODE NEXT_CVT_ VALUE_BLK_STATE
    ---------- -------- ------------------------------ ------------ ---------- -------------- ----------- --------- --------------------------------
    VALUE_BLK
    ----------------------------------------------------------------
             1 52CE1F84 [0x7870][0x30000],[BL]                    0          1              1           0 KJUSERNL  KJUSERVS_NOVALUE
    0x0

    资源名[0x7870][0x30000],[BL],对于非UNDO块的PCM锁
    第一位[0x7870]为lock_element_name,其是根据block number(BNO)和absolute file ID (AFN)计算出来的 => BNO bit-or’ed ( AFN << 22)
    第二位[0x30000]为(AFN>>10)<<15
    第三位[BL],对于PCM锁,其总为BL

    对于UNDO块
    id1 = ( BNO / _kcl_undo_grouping) % _kcl_undo_locks
    id2 = block class

    对于这个块,应该是由那个LMS进程处理,是通过如下公式计算 (id1+id2)%(number_of_LMS_procs)

    SQL> SELECT * FROM gv$lock_element WHERE LOCK_ELEMENT_NAME = 30832;

       INST_ID LOCK_ELE       INDX      CLASS LOCK_ELEMENT_NAME  MODE_HELD BLOCK_COUNT  RELEASING  ACQUIRING    INVALID       FLAGS
    ---------- -------- ---------- ---------- ----------------- ---------- ----------- ---------- ---------- ---------- ----------
             2 23FF8484          3     196608             30832          2           1          0          0          0          65

    LOCK_ELEMENT_NAME = 30832 = 0x7870,资源名的第一位
    CLASS = 196608 = 0x30000,资源名的第二位
    LOCK_ELEMENT_ADDR = 23FF8484,锁的地址

    SQL> SELECT * FROM gv$bh WHERE lock_element_addr='23FF8484';

       INST_ID      FILE#     BLOCK#     CLASS# STATUS         XNC FORCED_READS FORCED_WRITES LOCK_ELE LOCK_ELEMENT_NAME LOCK_ELEMENT_CLASS D T P S D N        OBJD        TS#
    ---------- ---------- ---------- ---------- ------- ---------- ------------ ------------- -------- ----------------- ------------------ - - - - - - ---------- ----------
             2          3      30832         14 xcur             0            0             0 23FF8484             30832              196608 N N N N N N       4226          2

    该锁保护的数据块为3,30832,object_id为4226
    该数据块的master节点(锁的master节点)为节点1,但是该数据的当前块在节点2上

    从gv$lock_element的BLOCK_COUNT列可以看到,一个锁其实可能覆盖多个数据块

    PCM锁的一点小测试

    SQL> desc ctais2.test
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     ID                                                 NUMBER

    SQL> select dbms_rowid.rowid_to_absolute_fno(rowid,'CTAIS2','TEST') file_id,dbms_rowid.rowid_block_number(rowid) block_id from ctais2.test;

       FILE_ID   BLOCK_ID
    ---------- ----------
             4         67
             4         67
             4         67
             4         67
             4         67
             4         67
             4         67
             4         67
             4         67
             4         67

    10 rows selected.

    两个实例都重启
    本库数据文件少,一般ID1就是block_id,所以只写了个简单的SQL

    --1-- file4block67 的资源,没有在节点1的GRD中
    SQL> @a
    Enter value for 1: 67
    old   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(&&1,'xxxx'))||']%BL%'
    new   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(67,'xxxx'))||']%BL%'

    no rows selected

    old   1: select * from v$lock_element where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$lock_element where LOCK_ELEMENT_NAME=67

    no rows selected

    old   1: select * from v$bh where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$bh where LOCK_ELEMENT_NAME=67

    no rows selected


    --2-- file4block67 的资源,也没有在节点1的GRD中,因为其还没有读入过buffer cache中
    SQL> @a
    Enter value for 1: 67
    old   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(&&1,'xxxx'))||']%BL%'
    new   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(67,'xxxx'))||']%BL%'

    no rows selected

    old   1: select * from v$lock_element where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$lock_element where LOCK_ELEMENT_NAME=67

    no rows selected

    old   1: select * from v$bh where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$bh where LOCK_ELEMENT_NAME=67

    no rows selected

    --1-- 节点1查询表后,可以看到在实例1上,已经有了这个对象的lock_element,其以模式2(X)持有对象.
    SQL> select count(*) from ctais2.test;

      COUNT(*)
    ----------
            10

    SQL> @a.sql
    old   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(&&1,'xxxx'))||']%BL%'
    new   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(67,'xxxx'))||']%BL%'

    no rows selected

    old   1: select * from v$lock_element where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$lock_element where LOCK_ELEMENT_NAME=67

    LOCK_ELE       INDX      CLASS LOCK_ELEMENT_NAME  MODE_HELD BLOCK_COUNT  RELEASING  ACQUIRING    INVALID      FLAGS
    -------- ---------- ---------- ----------------- ---------- ----------- ---------- ---------- ---------- ----------
    21BF3154       1143     262144                67          2           1          0          0          0         65

    old   1: select * from v$bh where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$bh where LOCK_ELEMENT_NAME=67

         FILE#     BLOCK#     CLASS# STATUS         XNC FORCED_READS FORCED_WRITES LOCK_ELE LOCK_ELEMENT_NAME LOCK_ELEMENT_CLASS D T P S D N       OBJD         TS#
    ---------- ---------- ---------- ------- ---------- ------------ ------------- -------- ----------------- ------------------ - - - - - - ---------- ----------
             4         67          1 xcur             0            0             0 21BF3154                67             262144 Y N N N N N      51837           4
             
    --2-- 节点1查询表后,在节点2的v$dlm_ress可以看到该块的锁资源。说明资源信息只在master节点上。grant队列就1个进程        
    SQL> @a.sql
    old   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(&&1,'xxxx'))||']%BL%'
    new   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(67,'xxxx'))||']%BL%'

    RESP     RESOURCE_NAME                  ON_CONVERT_Q ON_GRANT_Q PERSISTENT_RES MASTER_NODE NEXT_CVT_ VALUE_BLK_STATE
    -------- ------------------------------ ------------ ---------- -------------- ----------- --------- --------------------------------
    VALUE_BLK
    ----------------------------------------------------------------
    52D1E428 [0x43][0x40000],[BL]                      0          1              1           1 KJUSERNL  KJUSERVS_NOVALUE
    0x0


    old   1: select * from v$lock_element where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$lock_element where LOCK_ELEMENT_NAME=67

    no rows selected

    old   1: select * from v$bh where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$bh where LOCK_ELEMENT_NAME=67

    no rows selected

    --2-- 节点2也查询这个表,可以看到节点2上也有一个lock_element保护这个块,锁的级别为1,块的状态降为了scur
    SQL>  select count(*) from ctais2.test;

      COUNT(*)
    ----------
            10

    SQL> @a.sql
    old   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(&&1,'xxxx'))||']%BL%'
    new   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(67,'xxxx'))||']%BL%'

    RESP     RESOURCE_NAME                  ON_CONVERT_Q ON_GRANT_Q PERSISTENT_RES MASTER_NODE NEXT_CVT_ VALUE_BLK_STATE
    -------- ------------------------------ ------------ ---------- -------------- ----------- --------- --------------------------------
    VALUE_BLK
    ----------------------------------------------------------------
    52D1F310 [0x43][0x40000],[BL]                      0          1              1           1 KJUSERNL  KJUSERVS_NOVALUE
    0x0


    old   1: select * from v$lock_element where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$lock_element where LOCK_ELEMENT_NAME=67

    LOCK_ELE       INDX      CLASS LOCK_ELEMENT_NAME  MODE_HELD BLOCK_COUNT  RELEASING  ACQUIRING    INVALID      FLAGS
    -------- ---------- ---------- ----------------- ---------- ----------- ---------- ---------- ---------- ----------
    21BED954       1108     262144                67          1           1          0          0          0         65

    old   1: select * from v$bh where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$bh where LOCK_ELEMENT_NAME=67

         FILE#     BLOCK#     CLASS# STATUS         XNC FORCED_READS FORCED_WRITES LOCK_ELE LOCK_ELEMENT_NAME LOCK_ELEMENT_CLASS D T P S D N       OBJD         TS#
    ---------- ---------- ---------- ------- ---------- ------------ ------------- -------- ----------------- ------------------ - - - - - - ---------- ----------
             4         67          1 scur             0            0             0 21BED954                67             262144 N N N N N N      51837           4


    --1-- 在节点2也查询这个表后,可以看到节点1上,锁的模式变为1,这个块的状态也降级为scur

    SQL> @a.sql
    old   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(&&1,'xxxx'))||']%BL%'
    new   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(67,'xxxx'))||']%BL%'

    no rows selected

    old   1: select * from v$lock_element where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$lock_element where LOCK_ELEMENT_NAME=67

    LOCK_ELE       INDX      CLASS LOCK_ELEMENT_NAME  MODE_HELD BLOCK_COUNT  RELEASING  ACQUIRING    INVALID      FLAGS
    -------- ---------- ---------- ----------------- ---------- ----------- ---------- ---------- ---------- ----------
    21BEF4D4       1131     262144                67          1           1          0          0          0         65

    old   1: select * from v$bh where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$bh where LOCK_ELEMENT_NAME=67

         FILE#     BLOCK#     CLASS# STATUS         XNC FORCED_READS FORCED_WRITES LOCK_ELE LOCK_ELEMENT_NAME LOCK_ELEMENT_CLASS D T P S D N       OBJD         TS#
    ---------- ---------- ---------- ------- ---------- ------------ ------------- -------- ----------------- ------------------ - - - - - - ---------- ----------
             4         67          1 scur             0            0             0 21BEF4D4                67             262144 N N N N N N      51837           4


    --1-- 在节点1上更新一条记录,节点1重新以模式2获得块的锁,块的状态变为xcur
    SQL> update ctais2.test set id=99 where id=1;

    1 row updated.

    SQL> @a.sql
    old   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(&&1,'xxxx'))||']%BL%'
    new   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(67,'xxxx'))||']%BL%'

    no rows selected

    old   1: select * from v$lock_element where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$lock_element where LOCK_ELEMENT_NAME=67

    LOCK_ELE       INDX      CLASS LOCK_ELEMENT_NAME  MODE_HELD BLOCK_COUNT  RELEASING  ACQUIRING    INVALID      FLAGS
    -------- ---------- ---------- ----------------- ---------- ----------- ---------- ---------- ---------- ----------
    21BEF4D4       1131     262144                67          2           1          0          0          0         65

    old   1: select * from v$bh where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$bh where LOCK_ELEMENT_NAME=67

         FILE#     BLOCK#     CLASS# STATUS         XNC FORCED_READS FORCED_WRITES LOCK_ELE LOCK_ELEMENT_NAME LOCK_ELEMENT_CLASS D T P S D N       OBJD         TS#
    ---------- ---------- ---------- ------- ---------- ------------ ------------- -------- ----------------- ------------------ - - - - - - ---------- ----------
             4         67          1 xcur             0            0             0 21BEF4D4                67             262144 Y N N N N N      51837           4
             
    --2-- 在节点1上更新一条记录后,节点2上的块变为cr块,在锁上的模式为null
    SQL> @a.sql
    old   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(&&1,'xxxx'))||']%BL%'
    new   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(67,'xxxx'))||']%BL%'

    RESP     RESOURCE_NAME                  ON_CONVERT_Q ON_GRANT_Q PERSISTENT_RES MASTER_NODE NEXT_CVT_ VALUE_BLK_STATE
    -------- ------------------------------ ------------ ---------- -------------- ----------- --------- --------------------------------
    VALUE_BLK
    ----------------------------------------------------------------
    52D1F310 [0x43][0x40000],[BL]                      0          1              1           1 KJUSERNL  KJUSERVS_NOVALUE
    0x0


    old   1: select * from v$lock_element where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$lock_element where LOCK_ELEMENT_NAME=67

    LOCK_ELE       INDX      CLASS LOCK_ELEMENT_NAME  MODE_HELD BLOCK_COUNT  RELEASING  ACQUIRING    INVALID      FLAGS
    -------- ---------- ---------- ----------------- ---------- ----------- ---------- ---------- ---------- ----------
    21BED954       1108     262144                67          0           0          0          0          0         67

    old   1: select * from v$bh where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$bh where LOCK_ELEMENT_NAME=67

    no rows selected

    SQL> select * from v$bh where file#=4 and block#=67;

         FILE#     BLOCK#     CLASS# STATUS         XNC FORCED_READS FORCED_WRITES LOCK_ELE LOCK_ELEMENT_NAME LOCK_ELEMENT_CLASS D T P S D N       OBJD         TS#
    ---------- ---------- ---------- ------- ---------- ------------ ------------- -------- ----------------- ------------------ - - - - - - ---------- ----------
             4         67          1 cr               0            0             0 00                                    N N N Y N N      51837           4

    --2-- 节点2也更新一条数据,节点2重新以模式2持有块的xcur        
    SQL> update ctais2.test set id=999 where id=2;

    1 row updated.

    SQL> @a.sql
    old   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(&&1,'xxxx'))||']%BL%'
    new   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(67,'xxxx'))||']%BL%'

    RESP     RESOURCE_NAME                  ON_CONVERT_Q ON_GRANT_Q PERSISTENT_RES MASTER_NODE NEXT_CVT_ VALUE_BLK_STATE
    -------- ------------------------------ ------------ ---------- -------------- ----------- --------- --------------------------------
    VALUE_BLK
    ----------------------------------------------------------------
    52D1F310 [0x43][0x40000],[BL]                      0          1              1           1 KJUSERNL  KJUSERVS_NOVALUE
    0x0


    old   1: select * from v$lock_element where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$lock_element where LOCK_ELEMENT_NAME=67

    LOCK_ELE       INDX      CLASS LOCK_ELEMENT_NAME  MODE_HELD BLOCK_COUNT  RELEASING  ACQUIRING    INVALID      FLAGS
    -------- ---------- ---------- ----------------- ---------- ----------- ---------- ---------- ---------- ----------
    21BED954       1905     262144                67          2           1          0          0          0         65

    old   1: select * from v$bh where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$bh where LOCK_ELEMENT_NAME=67

         FILE#     BLOCK#     CLASS# STATUS         XNC FORCED_READS FORCED_WRITES LOCK_ELE LOCK_ELEMENT_NAME LOCK_ELEMENT_CLASS D T P S D N       OBJD         TS#
    ---------- ---------- ---------- ------- ---------- ------------ ------------- -------- ----------------- ------------------ - - - - - - ---------- ----------
             4         67          1 xcur             0            0             0 21BED954                67             262144 Y N N N N N      51837           4
             
    --1-- 在节点2也更新一条数据后,节点1的锁降级为null,块变为pi块
    SQL> @a.sql
    old   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(&&1,'xxxx'))||']%BL%'
    new   1: select * from v$dlm_ress where resource_name like '%[0x'||ltrim(to_char(67,'xxxx'))||']%BL%'

    no rows selected

    old   1: select * from v$lock_element where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$lock_element where LOCK_ELEMENT_NAME=67

    LOCK_ELE       INDX      CLASS LOCK_ELEMENT_NAME  MODE_HELD BLOCK_COUNT  RELEASING  ACQUIRING    INVALID      FLAGS
    -------- ---------- ---------- ----------------- ---------- ----------- ---------- ---------- ---------- ----------
    21BEF4D4       1131     262144                67          0           1          0          0          0         65

    old   1: select * from v$bh where LOCK_ELEMENT_NAME=&1
    new   1: select * from v$bh where LOCK_ELEMENT_NAME=67

         FILE#     BLOCK#     CLASS# STATUS         XNC FORCED_READS FORCED_WRITES LOCK_ELE LOCK_ELEMENT_NAME LOCK_ELEMENT_CLASS D T P S D N       OBJD         TS#
    ---------- ---------- ---------- ------- ---------- ------------ ------------- -------- ----------------- ------------------ - - - - - - ---------- ----------
             4         67          1 pi               0            0             0 21BEF4D4                67             262144 Y N N N N N      51837           4                

     

  • 相关阅读:
    virtualenv与virtualenvwrapper
    数据类型、变量定义、数据类型转换
    计算机存储单元、标识符
    html单页面中用angular js
    svn客户端访问失败,错误“请求的名称有效,但是找不到请求的类型”的解决
    php 获取某数组中出现次数最多的值(重复最多的值)与出现的次数
    数据库导入时出现“2006
    phpstorm 激活
    取消本地SVN文件夹与服务器的关联
    js实现倒计时函数
  • 原文地址:https://www.cnblogs.com/yaoyangding/p/13155621.html
Copyright © 2020-2023  润新知