zoukankan      html  css  js  c++  java
  • oracle 12.1.0.2中对象锁对系统的较大影响

    环境:oracle 12.1.0.2  rac ,4节点

    一、概述

    通常来说,如果是oltp应用,那么部署在rac上,是不错的注意。

    但实现情况中,往往是混合类型,既有OLTP也有OLAP。

    如果没有很好地进行资源管理和系统设计,那么系统的性能往往不如人意。

    造成系统慢的原因很多,其中一个就是oracle rac特有结构的负面作用。

    --

    例如如果一个过程或者包正在执行,且是一个长会话,需要很久才会释放,这个时候企图编译包,造成的一个大问题就是系统变慢,登录变慢。

    这是因为,编译会话企图获得执行包的排它锁,所以它需要不停地轮询各个实例,看这个对象是否被锁,结果毫无疑问,是被锁住,过了一会又会去查询。

    而我们知道,在多个实例之间查询对象的锁状态还是比较费时的,尤其是系统中有巨量锁的情况下,这个会耗费许多的CPU。

    最终就是系统变慢。

    二、方法

    那么是否有可以解决的办法了?

    oracle本身并不提供这样的工具,但作为dba只能取监测这样的监测过程。

    那么应该监视什么字典表呢?

    监视v$db_cache_object

    关键的问题是,这个视图不知道是哪个会话,所以即使知道了,也难于执行kill session的操作。

    监视dba_ddl_locks

    注:在这个视图中,不表明这个对象无法被编译,除非是排它的锁。

    dba_ddl_lock$的定义

    create or replace view sys.dba_ddl_locks as
    select  s.sid session_id,
              substr(ob.kglnaown,1,30) owner,
              substr(ob.kglnaobj,1,30) name,
        decode(ob.kglhdnsp, 0, 'Cursor', 1, 'Table/Procedure/Type', 2, 'Body',
               3, 'Trigger', 4, 'Index', 5, 'Cluster', 13, 'Java Source',
                 14, 'Java Resource', 32, 'Java Data', to_char(ob.kglhdnsp)) type,
        decode(lk.kgllkmod, 0, 'None', 1, 'Null', 2, 'Share', 3, 'Exclusive',
           'Unknown') mode_held,
        decode(lk.kgllkreq,  0, 'None', 1, 'Null', 2, 'Share', 3, 'Exclusive',
           'Unknown') mode_requested
       from v$session s, x$kglob ob, x$kgllk lk
       where lk.kgllkhdl = ob.kglhdadr
       and   lk.kgllkuse = s.saddr
       and   ob.kglhdnsp != 0;

    其中

    x$kgllk ---[K]ernel [G]eneric [L]ibrary Cache Manager object [L]oc[K]s   --核心库缓存管理对象锁

    x$kglob---[K]ernel [G]eneric [L]ibrary Cache Manager [OB]ject                --核心库缓存管理对象

    前者是后者的明细,双方通过

    --关于x$kgllk的定义
    http://blog.itpub.net/69265/viewspace-442931/

    SQL> desc x$kgllk;
    名称 类型
    ---------- -----------
    ADDR            RAW(4)
    INDX             NUMBER
    INST_ID        NUMBER
    KGLLKADR   RAW(4)  --
    KGLLKUSE   RAW(4)  ---会话地址(对应v$session的saddr)
    KGLLKSES   RAW(4)  ---owner地址
    KGLLKSNM   NUMBER ---SID
    KGLLKHDL   RAW(4) ---library cache object 句柄
    KGLLKPNC   RAW(4) ---the address of the call pin
    KGLLKPNS   RAW(4) ---对应跟踪文件中的session pin值
    KGLLKCNT   NUMBER
    KGLLKMOD   NUMBER ---持有锁的模式(0为no lock/pin held﹐1为null,2为share﹐3为exclusive)
    KGLLKREQ   NUMBER ---请求锁的模式(0为no lock/pin held﹐1为null,2为share﹐3为exclusive)
    KGLLKFLG   NUMBER ---cursor的状态﹐8(10g前)或2048(10g)表示这个sql正在运行﹐
    KGLLKSPN   NUMBER ---对应跟踪文件的savepoint的值
    KGLLKHTB   RAW(4)
    KGLNAHSH   NUMBER ---sql的hash值(对应v$session的sql_hash_value)
    KGLLKSQLID  VARCHAR2(13) ---sql ID,sql标识符
    KGLHDPAR   RAW(4) ---sql地址(对应v$session的sql_address)
    KGLHDNSP   NUMBER
    USER_NAME  VARCHAR2(30) ---会话的用戶名
    KGLNAOBJ   VARCHAR2(60) ---对象名称或者已分析并打开cursor的sql的前60个字符

    --关于x$kglob的定义

    参考:http://blog.itpub.net/11134237/viewspace-686353/

    具体略。

    在cdb-rac根中监视被锁定过程和会话

    原有的dba_ddl_locks视图只是适用于单实例,为了方便cdb-rac的监视,必须进行调整。

    create or replace view gv_ddl_locks as
    select    s.con_id,
              p."PDB_NAME",
              s.inst_id,
              s.sid session_id,
              s.serial#,
              substr(ob.kglnaown,1,128) owner,
              substr(ob.kglnaobj,1,1000) name,
        decode(ob.kglhdnsp, 0, 'Cursor', 1, 'Table/Procedure/Type', 2, 'Body',
               3, 'Trigger', 4, 'Index', 5, 'Cluster', 13, 'Java Source',
                 14, 'Java Resource', 32, 'Java Data', to_char(ob.kglhdnsp)) type,
        decode(lk.kgllkmod, 0, 'None', 1, 'Null', 2, 'Share', 3, 'Exclusive',
         'Unknown') mode_held,lk.kgllkmod,
        decode(lk.kgllkreq,  0, 'None', 1, 'Null', 2, 'Share', 3, 'Exclusive',
         'Unknown') mode_requested
       from  gv$session s, x$kglob ob, x$kgllk lk,cdb_pdbs p,GV$DB_OBJECT_CACHE GCO
       where lk.kgllkhdl = ob.kglhdadr and lk.con_id=ob.con_id and lk.inst_id=ob.inst_id
       and   lk.kgllkuse = s.saddr and lk.con_id=s.con_id and lk.inst_id=s.inst_id
       AND   GCO.INST_ID=OB.INST_ID AND GCO.CON_ID=OB.CON_ID AND GCO.ADDR=OB.KGLHDADR AND GCO.LOCKS<>0
       and   p."CON_ID"=s.con_id
       and   ob.kglhdnsp != 0;

    以上语句在cdb$root创建。

    这个视图有几个局限性:

    1. 由于需要使用动态视图,所以有些运行时间短的糊化根本无法查询到
    2. 由于动态视图的特性,判断对象是否被锁定并不是非常适合--尤其是那些运行时间短的
    3. 在大的cdb-rac中执行,会变更比较慢

    三、总结
    1.如果仅仅是想简单地知道什么对象被锁住,可以直接查询:

    select * from sys.gv_$db_object_cache x where x.owner='C##LUZHIFEI';

    2.如果还想知道是什么会话,需要执行前文的视图(以sys执行)

  • 相关阅读:
    HashMap的存储原理
    HashSet的存储原理
    ArrayList的底层实现原理
    $.getJSON()不执行回调函数
    JavaScript学习笔记(一)
    【转】日语口语简略型总结(更新中。。。)
    计算机常用符号(日文)更新中。。。
    异常
    注解
    多线程
  • 原文地址:https://www.cnblogs.com/lzfhope/p/8119351.html
Copyright © 2011-2022 走看看