• oracle latch


    (转载 : http://www.dbtan.com/2010/05/latch-free.html)

    Latch Free(闩锁释放):
    Latch Free通常被称为闩锁释放,这个名称常常引起误解,实际上我们应该在前面加上一个“等待”(wait),当数据库出现这个等待时,说明有进程正在等待某个Latch被释放,也就是waiting latch free。

    Latch是一种低级排队(串行)机制,用于保护SGA中共享内存结构。Latch就像是一种快速被获取和释放的内存锁,用于防止共享内存结构被多个用户同时访问。其实不必把Latch想得过于复杂,Latch通常就是操作系统利用内存中的某个区域,通过设置变量为0或非0,来表示Latch是否已经被取得,大多数操作系统,是使用TEST AND SET的方式来完成Latch检查或持有的。

    为了快速地获得一个直观认识,以下示例展现的了Latch的获取与释放过程。Latch在内存中的位置及名称可以通过下面的语句查询获得:

    sys@CCDB> select k.ksmfsadr,ksmfsnam,ksmfstyp,ksmfssiz,kslldnam,kslldlvl
      2  from x$ksmfsv k,x$kslld a
      3  where k.ksmfsnam = 'ksqeql_' and kslldnam = 'enqueues';
    KSMFSADR         KSMFSNAM        KSMFSTYP          KSMFSSIZ KSLLDNAM          KSLLDLVL
    ---------------- --------------- --------------- ---------- --------------- ----------
    000000006000CA68 ksqeql_         ksllt                  160 enqueues                 5

    得到这些信息之后,可以通过Latch的地址信息手工对Latch进行模拟的持有或释放,注意获取Latch使用了kslgetl过程,释放Latch使用了kslfre,也就是Latch Free过程,如下所示:

    sys@CCDB> select to_number('000000006000CA68','XXXXXXXXXXXXXXXX') from dual;
    TO_NUMBER('000000006000CA68','XXXXXXXXXXXXXXXX')
    ------------------------------------------------
                                          1610664552                                      
    sys@CCDB> oradebug setmypid
    Statement processed.
    sys@CCDB> oradebug call kslgetl 1610664552 1
    Function returned 1
    sys@CCDB> oradebug call kslfre 1610664552
    Function returned 0

    在这个Latch的短时持有前后,观察这个Latch的等待时间,可以发现大量的Latch等待已经发生,如下所示,这就是Latch、Latch Get和Latch Free的一个直观案例。

    sys@CCDB> select name,wait_time from v$latch where name = 'enqueues';
    NAME                                                          WAIT_TIME
    ------------------------------------------------------------ ----------
    enqueues                                                              0
    sys@CCDB> select name,wait_time from v$latch where name = 'enqueues';
    NAME                                                          WAIT_TIME
    ------------------------------------------------------------ ----------
    enqueues                                      8

    按获取和等待方式不同进行分类,Latch请求的类型可以分为willing-to-wait和immediate两类。

    ·willing-to-wait:是指如果所请求的Latch不能立即得到,请求进程将等待一段很短的时间后再次发出请求。进程一直重复此过程直到得到Latch。
    ·immediate:是指如果所请求的Latch不能立即得到,请求进程就不再等待,而是继续执行下去。

    这里简单介绍一下这两种机制。latch是一个轻量级的锁,它的获取释放通常都很快。如果没有willing-to-wait这种模式,也就是说进程申请不到latch就睡眠挂起,那么会造成很大的开销。Oracle认为让该进程spin下去稍等一下继续申请会更快捷。事实上大多数情况下也是这样的。讲到这里,你也应该意识到了willing-to-wait只在多CPU环境才有意义。如果不是多CPU环境,它没办法在别的进程占用CPU使用latch的时候还自己spin。 而immediate模式是指,如果进程申请不到一个latch它会继续申请同类别其它的latch。这种latch一般是有多个的,所以它可以不必spin不必挂起,直接申请其它的就好。

    在v$latch中以下字段记录了willing-to-wait请求。
    · GET:成功地以willing-to-wait请求类型请求一个Latch的次数。
    · MISSES:初始以willing-to-wait请求类型请求一个Latch不成功,而进程进入等待的次数。
    · SLEEPS:初始以willing-to-wait请求类型请求一个Latch不成功后,进程等待获取Latch时进入休眠的次数。

    在v$latch中以下字段记录了immediate类请求。
    · IMMEDIATE_GETS:以immediate请求类型成功地获得一个Latch的次数。
    · IMMEDIATE_MISSES:以immediate请求类型请求一个Latch不成功的次数。

    Oracle的Latch机制是竞争,其处理类似于网络里的CSMA/CD,所有用户进程争夺Latch,对于愿意等待类型(willing-to-wait)的Latch,如果一个进程在第一次尝试中没有获得Latch开始自旋(spin),如果经过_spin_count次争夺不能获得Latch,然后该进程转入睡眠状态,持续一段指定长度的时间,然后再次醒来,按顺序重复以前的步骤。这一过程可以下图来说明:

    用户进程争夺Latch的过程

    SPIN的次数受隐含参数_spin_count影响,该参数的缺省值为2000。以下数据取自Oracle 11gR1 + Linux环境,该系统存在4颗CPU:

    sys@CCDB> show parameter cpu_count
    NAME                                 TYPE            VALUE
    ------------------------------------ --------------- ---------
    cpu_count                            integer         4

    从以上过程可以看到,在spin的过程中,进程会一直持有CPU,spin的机制是假设Latch可以被快速释放(正常情况下,Latch的持有时间是微秒级,相对spin机制如果直接采用Sleep方式引起的上下文切换会相当昂贵,所以Oracle针对Latch引入了spin算法),如果其他CPU上的其他进程释放了Latch,SPIN进程就可以立即获得这个Latch。如果系统只有单CPU,那就谈不上SPIN了。另一方面也可以看到,Latch竞争是非常昂贵的,可能导致严重的CPU耗用,所以Latch竞争在任何时候都应该引起充分的重视。经过spin后成功获得Latch的次数被记录在v$latch.spin_gets字段。通过下图来说明一下Latch竞争的情况

    Latch竞争示意图

    继续来具体看一下willing-to-wait和immediate两类Latch的大致数量,以下查询来自Oracle 11gR1(同以上数据库):

    sys@CCDB> select count(*) from v$latch;
      COUNT(*)
    ----------
           496
    sys@CCDB> select count(*) from v$latch where IMMEDIATE_GETS + IMMEDIATE_MISSES > 0;
      COUNT(*)
    ----------
            26
    sys@CCDB> select count(*) from v$latch where IMMEDIATE_GETS + IMMEDIATE_MISSES = 0;
      COUNT(*)
    ----------
           470
    

    可以看到willing-to-wait类型的等待事件占了绝大部分,immediate类型的仅为少数:

    sys@CCDB> select name,immediate_gets,immediate_misses,spin_gets
      2  from v$latch
      3  where immediate_gets + immediate_misses > 0
      4  order by immediate_gets desc;
    NAME                           IMMEDIATE_GETS IMMEDIATE_MISSES  SPIN_GETS
    ------------------------------ -------------- ---------------- ----------
    cache buffers chains                    58212                1          9
    hash table column usage latch           34803                0          0
    cache buffers lru chain                 30936               92         17
    redo copy                                9646               11          0
    redo allocation                          9646                0          1
    JOX SGA heap latch                       2257                0          0
    space background task latch              2102                0          0
    checkpoint queue latch                   1712                0          0
    In memory undo latch                     1371                0          0
    simulator lru latch                      1312                1         17
    active service list                      1077                0          0
    Memory Management Latch                  1055                0          0
    SQL memory manager latch                 1045                0          0
    KTF sga latch                             980                0          0
    cache table scan latch                    394                1          0
    process queue reference                   131                1          1
    job workq parent latch                    114                0          0
    process allocation                        109                0          0
    MQL Tracking Latch                         63                0          0
    post/wait queue                             8                0          0
    SGA IO buffer pool latch                    4                0          0
    query server process                        3                0          0
    shared server configuration                 2                0          0
    object queue header heap                    2                0          0
    JOX JIT latch                               1                0          0
    object stats modification                   1                0          0
    26 rows selected.

    需要注意的是,immediate类型的Latch通常是因为存在多个可用Latch,最常见的如redo copy latch,当process想要取得redo copy latch时,它首先要求其中一个Latch,如果可以取得就持有该Latch,如果不能获取,它会立刻转向要求另一个redo copy latch,只有所有redo copy latch都无法取得时,才会sleep与wait。

    immediate的另外一种原因是每个Latch都有level的概念(level=1 - 14),当一个process需要取得一组Latches时,为避免死锁,取得Latches有一定的顺序,即process新请求的Latch的level,应该大于process目前所握有的Latch的level。所以如果process要求的新Latch的level小于目前所持有的Latch的level,正常情况下,Oracle要求process先释放目前所持有的所有Latch,再依次取得这些Latch。为节省时间,Oracle允许进程以no-wait方式要求较低level的Latch,如果成功取得,既可以避免deadlcok又可以节省时间。

    在Oracle 10g之前,Latch Free同Enqueue一样,是一个汇总等待。从Oracle 10g开始,这个等待被分解,现在可以更直接地通过会话等待得知具体的Latch发生在哪些资源上:

    sys@CCDB> select name,wait_class
      2  from v$event_name
      3  where name like '%latch%';
    NAME                                               WAIT_CLASS
    -------------------------------------------------- --------------------
    latch: cache buffers chains                        Concurrency
    latch: redo writing                                Configuration
    latch: redo copy                                   Configuration
    latch: Undo Hint Latch                             Concurrency
    latch: In memory undo latch                        Concurrency
    latch: MQL Tracking Latch                          Concurrency
    latch: row cache objects                           Concurrency
    latch: shared pool                                 Concurrency
    latch free                                         Other
    latch activity                                     Other
    wait list latch activity                           Other
    wait list latch free                               Other
    latch: session allocation                          Other
    latch: messages                                    Other
    latch: enqueue hash chains                         Other
    latch: ges resource hash list                      Other
    ges2 proc latch in rm latch get 1                  Other
    ges2 proc latch in rm latch get 2                  Other
    gcs remastering wait for write latch               Other
    gcs remastering wait for read latch                Other
    latch: gcs resource hash                           Other
    latch: cache buffers lru chain                     Other
    latch: checkpoint queue latch                      Other
    latch: cache buffer handles                        Other
    buffer latch                                       Other
    latch: object queue header operation               Other
    latch: redo allocation                             Other
    latch: gc element                                  Other
    latch: undo global data                            Other
    latch: Change Notification Hash table latch        Other
    latch: change notification client cache latch      Other
    latch: lob segment hash table latch                Other
    latch: lob segment query latch                     Other
    latch: lob segment dispenser latch                 Other
    waiting to get CAS latch                           Other
    waiting to get RM CAS latch                        Other
    latch: virtual circuit queues                      Other
    PX qref latch                                      Other
    latch: parallel query alloc buffer                 Other
    39 rows selected.
  • 相关阅读:
    halcon应用案例探究
    Halcon中模板匹配方法的总结归纳
    halcon开发必读
    全局Threshold和动态阈值分割Dyn_Threshold的应用场景
    halcon电路断裂检测
    halcon之 distance_transform
    VS调试不能进入断点,提示当前不会命中断点还未为文档加载任何符号
    .net reactor使用教程(一)——界面各功能说明(转)
    (转) 开运算opening_circle和闭运算closing_circle的异同
    Win10系统安装UEFI+GPT配置
  • 原文地址:https://www.cnblogs.com/kramer/p/3433753.html
Copyright © 2020-2023  润新知