技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> Oracle --> 深入理解Oracle中的Mutex

深入理解Oracle中的Mutex

浏览:2459次  出处信息

了解 Oracle Mutex

   虽然Mutex中文翻译为互斥锁,但为了和OS mutex充分的区别,所以我们在本文里称Oracle Mutex为Mutex。

   Oracle中的mutex,类似于Latch,是一种低级的串行机制,用以控制对SGA中部分共享数据结构的访问控制。  Oracle中的串行机制有不少,引入它们的目的是避免一个对象出现下述现象:

  • 当某些进程在访问该对象时,该资源被重新分配

  • 当某些进程在修改它时,被其他进程读取

  • 当某些进程在修改它时,被其他进程修改

  • 当某些进程在读取它时,被其他进程修改

  •    不同于Latch,Mutex的使用更灵活,用途更多,例如:

  • 哪些需要被mutex保护的共享数据结构可以有自己独立的mutex,即一个对象拥有自己独立的mutex,不像Latch往往一个需要保护大量对象,举例来说,每一个父游标有其对应的mutex, 而每一个子游标也有其对应的mutex

  • 每一个数据结构可能有一个或多个mutex保护,每一个mutex负责保护其结构的不同部分

  • 当然一个mutex也可以用来保护多于一个的数据结构

  •    理论上mutex即可以存放在其保护的结构本身中(其实是嵌入在结构里),也可以存放在其他地方。 一般情况下Mutex是在数据结构需要被保护时动态创建出来的。 如是嵌在需要保护结构体内的mutex,则当 所依附的数据结构被清理时 该mutex也将被摧毁。

    Mutex带来的好处

       虽然mutex和latch都是Oracle中的串行机制,但是mutex具有一些latch没有的好处

    更轻量级且更快

       Mutex作为Latch的替代品,具有更快速获得,更小等优势。 获取一个mutex进需要大约30~35个指令, 而Latch则需要150~200个指令。一个mutex结构的大小大约为16 bytes,而在10.2版本中一个latch需要112个bytes,在更早的版本中是200个bytes。 从200个bytes 精简到112个是通过减少不必要的统计指标 SLEEP1~SLEEP11、WAITERS_WOKEN, WAITS_HOLDING_LATCH等从而实现的。今后我们将看到更多关于Latch的代码优化。

    减少伪争用

       典型情况下一个Latch保护多个对象。 当一个Latch保护多个热对象时,并行地对这些对象的频繁访问让latch本身变成性能的串行点。 这也就是我们此处说的伪争用点, 因为争用是发生在这个串行保护的机制上,而不是进程去访问的对象本身。与latch不同, 使用mutex的情况下Oracle开发人员可以为每一个要保护的数据结构创建一个独立的mutex。 这意味着Latch的那种伪争用将大大减少,因为每一个对象均被自己独立拥有的mutex保护

    Mutex在一些地方替代了latch和PIN

       一个Mutex可供多个Oracle进程并行地参考,反过来说进程们可以以S(Shared 共享) mode模式参考一个Mutex。以S mode一起共享参考这个mutex的进程的总数成为参考总数reference count。Mutex自身结构中存放了这个ref count的数据。另一方面,mutex也可以被以X (Exclusive)mode排他模式被仅有一个进程所持有Held。

       Mutex有2种用途,一方面他们可以充当维护必要串行机制的结构,如同latch那样; 同时也可以充当pin,避免对象被age out。

       举例来说,mutex结构中包含的ref count信息可以用作替代library cache pin。 在mutex充当cursor pin之前,当一个进程要执行=>pin一个cursor时需要做的是针对性地创建library cache pin和删除这个library cache pin(均为S mode)。mutex充当cursor pin之后,进程只需要增加和减少mutex上的ref count即可。

       当某一个进程首次解析一个游标 Cursor,他将临时创建并移除一个library cache pin,但是该进程后续的解析或执行进要求增加或者减少ref count。注意在这个增加/减少ref count的过程中无需acquire latch,这是因为mutex自身能起到限制串行访问修改ref count的作用。 当一个进程要移除自己的mutex pin时,它减少ref count,同样的无需acquire 任何latch。

    Mutex和Latch的交互

       Latches和Mutex 是独立的串行机制, 举例来说一个进程可以同时持有latch和mutex。 在进程异常dead的情况下,一般latch要比Mutex更早被PMON清理。 一般情况下不存在mutex的死锁。 不像latch,在早期版本例如9i之前我们经常遇到latch死锁的问题。

    Mutex的用途

       在版本10.2中仅仅有 KKS 这个内核层是mutex的客户,KKS 意为 Kernel Kompile Shared, 它是Library Cache中的shared cursor游标共享部分层次的代码。 在之后的版本中,ORACLE开发部门更多地使用了Mutex,不局限于KKS。

    KKS游标共享如何使用Mutex

       kks 使用mutex以便保护对于下述基于parent cursor父游标和子游标child cursor的一系列操作。

    对于父游标parent cursor的操作:

  • 基于发生的不同操作,对应不同的等待事件:

  • 在某个父游标名下创建一个新的游标                     ==> cursor:mutex X

  • 检查一个父游标                                                            ==> cursor:mutex S

  • 绑定值捕获                                                                    ==> cursor:mutex X


  • 保护父游标的mutex嵌入在父游标结构内

  • 针对父游标parent cursor的Mutex类型为’Cursor Parent’ (kgx_kks2).

  •  针对父游标parent cursor的Mutex等待事件均为’ Cursor: mutex *’的形式

  • 针对游标统计信息的操作

  • 基于对不同的游标统计信息的操作有不同的等待事件:

  • 构造,更新游标相关的统计信息                                              ==> cursor:mutex X

  • 检测游标相关的统计信息,例如访问V$SQLSTATS            ==> cursor : mutex S


  • 相关的游标可能在父游标中,也可能在游标统计信息相关的hash table上

  • 针对游标统计信息的Mutex类型为Cursor Stat (kgx_kks1)

  • 针对游标统计信息的Mutex等待事件均为’ Cursor: mutex *’的形式

  • Mutex是如何替代library cache pin来保护cursor heap的?

  • 传统的’library cache pin’在10.2.0.2之后默认被取代, 此处PIN被Mutex及其ref count取代。 当进程执行游标语句时或者需要PIN,或者需要hard parse一个子游标heap。

  • 在版本10.2.0.1中, 使用mutex部分代码替代PIN的功能默认是不激活的,实际上这取决于隐藏参数_KKS_USE_MUTEX_PIN,在10.2.0.2之后_KKS_USE_MUTEX_PIN默认为TRUE。 换而言之在版本10.2中我们还是可以关闭KKS使用MUTEX替代PIN保护CURSOR的, 但是在版本11g中则几乎无法关闭MUTEX。 注意10.2中仅当KKS真正使用MUTEX时,library cache pin不再用作cursor pin。

  • 基于对不同的游标统计信息的操作有不同的等待事件:

  • 为执行某个SQL而PIN一个游标Cursor                        ==>Cursor: Pin S Wait on X

  • 当执行一个游标而PIN Cursor,而该Cursor正被其他进程以S mode检测             ==>  cursor:pin S


  • 当试图重建一个游标Cursor  ==> Cursor: pin X  该等待事件一般不太会看到,因为当一个游标正被执行,且其需要重建时会有另一个游标被创建

  • 保护游标的mutex嵌入在游标结构内

  • Mutex类型为’Cursor Pin’ (kgx_kks3)

  • 等待事件均为 ‘cursor: pin *’的形式

  • KKS使用MUTEX情况下SQL语句的 解析与执行的收益

       在版本10.2中, 以下是几个SQL解析与执行从MUTEX哪里获得主要收益:

  • 在某个父游标下构建一个新的子游标

  • 首先这种构建新子游标的操作更廉价了,  当时Maclean仍要告诫你 一个父游标下过多的子游标仍不是一件好事情


  • 对父游标的检测

  • 在找到一个合适的游标并执行前,父游标需要被适当检测。 对父游标的这种检测目前也使用mutex来保护了,所以这种检测更的成本更低了


  • 对于已经加载在Library Cache 中的SQL语句重复执行

  • 常规情况下,当一个进程要执行SQL游标前总是必须要先pin它

  • 不使用MUTEX的情况:若游标处于OPEN状态下以便今后的重复执行,且参数cursor_space_for_time(CSFT  目前已不推荐使用该参数)为TRUE,则每一次重复执行可以不需要library cache pin。 若游标处于OPEN状态下但是cursor_space_for_time=false,则进程在重复执行SQL游标前总是要先拿library cache pin

  • 使用MUTEX的情况: 相反,若使用mutex来替代library cache pin时,则无需关心cursor_space_for_time 。 仅第一个进程需要做一个PIN,其他后续进程都只需要简单地在对应保护cursor heap的mutex上拿一个共享reference 。


  • 查询SQL统计信息

       通过V$SQLSTAT视图(本质上是X$KKSSQLSTAT)访问SQL统计信息时,其所需要的CPu和获取的Latch数量要远远少于访问其他V$SQL视图。 在早期版本中, 并行地访问V$SQL或者V$SQLAREA视图会造成 library cache latch的争用。

    Mutex 的统计信息

       下面是一个AWR中的Mutex Sleep Statistics, 这些数据主要来源于V$MUTEX_SLEEP视图。

    Mutex Sleep Summary

  • ordered by number of sleeps desc

  • Mutex TypeLocationSleepsWait Time (ms)
    Library Cachekglhdgh1 642,3560
    Library Cachekglpnal2 912,3450
    Cursor Pinkkslce [KKSCHLPIN2]2,0840
    Library Cachekglpin1 49560
    Library Cachekglhdgn2 1067840
    Library Cachekglpndl1 956910
    Library Cachekglpnal1 906050
    Library Cachekgllkdl1 855800
    Library Cachekgllkal1 804040
    Library Cachekglllal3 1112820
    Library Cachekglllal1 1092180
    Library Cachekglhdgn1 621630
    Library Cachekgllldl2 1121560
    Library Cachekgllkc1 571050
    Library Cachekglget2 21000
    Library Cachekglini1 32530
    Library Cachekglget1 1310
    Cursor PinkksLockDelete [KKSCHLPIN6]220
    Library Cachekgllkal3 82180
    Library CachekglUnsetHandleReference 120100
    Cursor Pinkksxsccmp [KKSCHLPIN5]100
    Library Cachekglobld1 7580
    Cursor Pinkksfbc [KKSCHLPIN1]80
    Library CachekglUpgradeLock 11970
    Library Cachekglhdgc1 10220
    Cursor Pinkksfbc [KKSCHLFSP2]20
    Library Cachekgldtin1 4210
    Library Cachekglhbh1 6310
    Library Cachekgllkal5 8410
    Library Cachekglrdtin1 4410
    Cursor ParentkkscsPruneChild [KKSPRTLOC35]10

       Mutex的类型Mutex Type

       Mutex的类型其实就是 mutex对应的客户的名字,  在版本10.2中基本只有KKS使用Mutex,所以仅有3种:

  • Cursor Stat (kgx_kks1)

  • Cursor Parent (kgx_kks2)

  • Cursor Pin (kgx_kks3)

  •    在版本11g中扩展了对Mutex的使用,在Library Cache的HASH BUCKET中嵌入了mutex以保护hash bucket,所以多了一种mutex type : Library Cache

       哪些代码函数会申请Mutex?

       Oracle中哪些代码函数会申请Mutex? 例如KKSFBC等,其实很像 V$LATCH的location列

       10.2中最常见的下面的几个函数

       kkspsc0  -负责解析游标 - 检测我们正在解析的游标是否有对象的parent cursor heap 0存在

       kksfbc           -  负责找到合适的子游标 或者创建一个新的子游标

       kksFindCursorstat  

       11g开始有大量函数需要用到Mutex了

       SQL> select location from X$MUTEX_SLEEP_HISTORY;

       LOCATION

       —————————————-

       kkslce [KKSCHLPIN2]

       kksfbc [KKSCHLFSP2]

       kglhdgn2 106

       kglpin1 4

       kglhdgn2 106

       kglllal1 109

       kglpin1 4

       kglpndl1 95

       kglpin1 4

       kglpin1 4

       kksfbc [KKSCHLFSP2]

       kglhdgn1 62

       kglpnal1 90

       kglllal3 111

       kglpnal1 90

       kglpnal1 90

       kglget2 2

       kglllal3 111

       kglget2 2

       kglobld1 75

       kkslce [KKSCHLPIN2]

       kglpndl1 95

       kglpndl1 95

       kglpin1 4

       kkslce [KKSCHLPIN2]

       kglpin1 4

       kglget2 2

       kglllal1 109

       kgllkc1 57

       kglget2 2

       kglpnal1 90

       kglpin1 4

       kglpin1 4

       kglpin1 4

       kgllkdl1 85

       kglllal3 111

       kgllldl2 112

       kglpin1 4

       kglpndl1 95

       kkslce [KKSCHLPIN2]

       kksLockDelete [KKSCHLPIN6]

       kglpndl1 95

       kkslce [KKSCHLPIN2]

       kglpnal1 90

       kglpin1 4

       kglpin1 4

       kgllldl2 112

       kgllkdl1 85

       kglpin1 4

       kglhdgn2 106

       kglhdgn2 106

       kksLockDelete [KKSCHLPIN6]

       kglhdgn1 62

    Mutex的Get和Sleep

       当一个Mutex被申请时, 一般称为一个get request。 若初始的申请未能得到授权, 则该进程会因为此次申请而进入到255次SPIN中(255是在代码中用常量写死的),每次SPIN循环迭代过程中该进程都会去看看Mutex被释放了吗。

       若该Mutex在SPIN之后仍未被释放,则该进程针对申请的mutex进入对应的mutex wait等待事件中。 实际进程的等待事件和等待方式由mutex的类型锁决定,例如 Cursor pin、Cursor Parent。  举例来说,这种等待可能是阻塞等待,也可以是sleep。

       但是请注意在V$MUTEX_SLEEP_*视图上的sleep列意味着等待的次数。相关代码函数在开始进入等待时自加这个sleep字段。

       等待计时从进程进入等待前开始计算等待时间, 当一个进程结束其等待,则等待的时间加入都总和total中。  该进程再次尝试申请之前的Mutex,若该Mutex仍不可用,则它再次进入spin/wait的循环。

       V$MUTEX_SLEEP_HISTORY视图的GETS列仅在成功申请到一个Mutex时才增加。

       短期持有一个mutex:  spin 循环255次一般可以有效以S mode获得一个mutex, 前提是该Mutex 已经被以S mode持有。 简单来说若有2个进程同时以S mode去申请一个Mutex,则稍晚的一个申请者需要进入SPIN并等稍早一点的申请者完成它的例如创建针对该mutex的一个reference的操作,但这都是非常迅速的操作。

       长期持有一个Mutex: 如若一个Mutex已经被某进程以X mode持有, 则往往有其进程以SHRD模式去申请该mutex时仍发现该mutex 以X mode被其他进程所持有,则往往这个EXCL  持有是 LONG_EXCL(可以通过SSD DUMP发现),则后续的申请者往往要进入spin循环,甚至需要等待

       上面我讲了willing-to-wait的mutex, 实际上mutex 的申请也可以是 nowait的。进程以nowait申请mutex时不会进入spin-cycle也不sleep,它只继续常规处理。 当一个nowait get失败时,将增加一次miss,但是实际上V$MUTEX_SLEEP_*中记录的miss不是这样的miss, 视图中记录的miss是等待的次数, 对于真正的miss没有统计项。

       Wait Time等待时间

       类似于latch,spin time 不算做mutex的消耗时间,它只包含等待消耗的时间。

    真正理解Mutex相关的等待

       Mutex数据结构中存放了Holder id持有者ID , Ref Count,和其他Mutex相关的统计信息。 Holder id对应于持有该Mutex的session id (v$session.sid)  。 特别注意, Ref Count是进程并发以S mode参考该Mutex的进程数量(如下文的演示)。

       当一个Mutex被以X mode 持有,则Holder id 为对应持有该mutex的session id,而Ref Count为0。

       每一个共享S mode持有者仅仅增加mutex上的Ref Count。 可供大量session并发以S mode持有参考一个Mutex。 但是注意更新ref count的操作是串行的, 这是为了避免错漏并维护mutex中正确的ref count。

       下面我们详细介绍一个执行游标过程中对mutex share pin的过程:

  • 某进程以SHRD 模式申请一个Mutex,并尝试临时修改该Mutex的Holder ID

  • 若该Mutex正被他人更新,则该session会将Holder id设置为本session的sid,之后该进程将增加ref count,之后再清楚mutex上的Holder id。简单来说 这个Holder id是真正做了并行控制的功能。 若该Holder id 被设置了,则说明该Mutex要么被以EXCL模式持有,要么正有一个其他进程在以S mode申请该Mutex的过程中(例如更新Ref Count)。 当更新Ref Count时临时设置holder id的目的就是为了实现避免其他进程并发更新该Mutex的机制。 通过这些例子说明了 , Mutex既可以用作Latch并发控制, 也可用作pin。

  • 若Holder id已被设置,则申请进程将可能进入等待事件 。  例如若当前Mutex的持有者进程正以X mode更新该Mutex,则申请者的等待事件应为”cursor: pin S on X” 。  而若当持有者Holder并不是”真的要持有” 该Mutex,而仅仅是尝试更新其Ref Count,则第二个进程将等在’ Cursor :pin S’等待事件上; 实际正在更新Ref count的操作时很快的,是一种轻微的操作。 当第一个进程正在更新mutex,则后续的申请进程将进入spin 循环中255次等待前者结束。 当mutex上不再有 Holder id时(如前者的进程已经更新完Ref Count)时, 则申请者进程将Holder ID设为自身的SID,并更新Ref Count,并清除Holder id。 若在255次循环SPIN后mutex仍不被释放,则该进程进入等待并不再跑在CPU上。

  • Mutex相关的等待事件

       cursor: mutex * events等待事件

  • cursor: mutex * events等待事件用于Cursor Parent 和 Cursor stats类型的操作:

  • ‘cursor: mutex X’ , 某个进程申请以EXCL mode持有mutex时进入该等待, 该Mutex要么正被其他进程以SHRD模式参考,这导致X mode的申请必须要等待直到Ref count=0,  或者该mutex正被另一个进程以X mode持有。

  • 相关操作要求以EXCL X mode持有Mutex的:

  • 在一个父游标下创建一个新的子游标

  • 捕获SQL中的绑定变量

  • 更新或构件SQL统计信息V$SQLSTATS



  • ‘Cursor: Mutex S’ , 某个进程以SHRD S mode申请一个Mutex, 而该Mutex要么被其他进程已EXCL X mode所持有,要么其他进程正在更新mutex 上的Ref Count。

  • 相关类型的操作一般是检测父游标或者CURSOR统计信息数据, 此外查询V$SQLSTATS也会造成CURSOR statistics被查询


  •    ‘cursor: pin * events’等待事件

       该类等待事件一般是为了pin相关的子游标

  • cursor: pin S  当一个进程以共享pin模式申请一个Mutex,而不能立即获得时,进入cursor: Pin S等待事件。 Mutex Pin是以共享类型的操作,例如执行一个游标。

  • 当一个进程等在cursor: pin S上,说明该进程在对一个共享的mutex pin 参考或取消参考时,有其他的进程也正在为同样的cursor heap创建或者取消一个共享Mutex pin。 实际上cursor: pin S 等待事件应当很少见,因为更新共享Mutex pin 的reference 应当是很快的。 再重复一次,S mode的Mutex可以被并发持有, 但是更新Mutex的Ref Count仍需要串行地处理 。 一旦reference count被增加好,则后续进程将可以为同样的cursor heap增加reference count。 因此此处mutex 即可以扮演Latch的角色(串行控制ref count的更新),又可以扮演pin的角色(ref count本身)。


  • ‘cursor: pin X’  当一个进程需要以EXCL X mode获得mutex时, 这类需要EXCL X 模式的串行操作包括:

  • 构建一个子游标

  • 某个进程已经以X mode持有该Mutex

  • 一个或多个进程正在reference 该Mutex (shared mutex pin)


  • ‘Cursor: pin S on X’ 最常见的等待事件,  进程为了共享操作例如执行pin游标而以SHRD S mode申请mutex, 但是未立即获得。原因是该游标被其他进程以EXCL X mode 持有了。

  • Mutex的相关统计视图

       V$MUTEX_SLEEP

       shows the wait time, and the number of sleeps for each combination of mutex type and location.

    ColumnDatatypeDescription
    MUTEX_TYPEVARCHAR2(32)Type of action/object the mutex protects
    LOCATIONVARCHAR2(40)The code location where the waiter slept for the mutex
    SLEEPSNUMBERNumber of sleeps for this MUTEX_TYPE and LOCATION
    WAIT_TIMENUMBERWait time in microseconds

       V$MUTEX_SLEEP_HISTORY

       displays time-series data. Each row in this view is for a specific time, mutex type, location, requesting session and blocking session combination. That is, it shows data related to a specific session (requesting session) that slept while requesting a specific mutex type and location, because it was being held by a specific blocking session. The data in this view is contained within a circular buffer, with the most recent sleeps shown.

    ColumnDatatypeDescription
    SLEEP_TIMESTAMPTIMESTAMP(6)The last date/time this MUTEX_TYPE and LOCATION was slept for by theREQUESTING_SESSION, while being held by the BLOCKING_SESSION.
    MUTEX_TYPEVARCHAR2(32)Type of action/object the mutex protects
    GETSNUMBERThe number of times the mutex/location was requested by the requesting session while being held by the blocking session. GETS is only incremented once per request, irrespective of the number of sleeps required to obtain the mutex.
    SLEEPSNUMBERThe number of times the requestor had to sleep before obtaining the mutex
    REQUESTING_SESSIONNUMBERThe SID of a session requesting the mutex
    BLOCKING_SESSIONNUMBERThe SID of a session holding the mutex
    LOCATIONVARCHAR2(40)The code location where the waiter slept for the mutex
    MUTEX_VALUERAW(4)If the mutex is held in exclusive (X) mode, this column shows the SID of the blocking session, else it shows the number of sessions referencing the mutex in S mode.
    P1NUMBERInternal use only
    P1RAWRAW(4)Internal use only
    P2NUMBERInternal use only
    P3NUMBERInternal use only
    P4NUMBERInternal use only
    P5VARCHAR2(64)Internal use only

       接着我们会在环境中模拟cursor pin S wait on X的场景,并通过systemstate dump和v$mutex_sleep , v$mutex_sleep_history等视图观察这一现象

       session A:

       SQL> select * from v$version;

       BANNER

       —————————————————————-

       Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi

       PL/SQL Release 10.2.0.5.0 - Production

       CORE 10.2.0.5.0 Production

       TNS for Linux: Version 10.2.0.5.0 - Production

       NLSRTL Version 10.2.0.5.0 - Production

       www.askmaclean.com

       SQL> show parameter kks

       SQL>

       SQL> create table mac_kks tablespace users nologging as select * from dba_objects;

       Table created.

       SQL> insert /*+ append */ into mac_kks select * from mac_kks;

       77386 rows created.

       SQL> commit;

       Commit complete.

       SQL> insert /*+ append */ into mac_kks select * from mac_kks;

       154772 rows created.

       SQL> commit;

       Commit complete.

       SQL> insert /*+ append */ into mac_kks select * from mac_kks;

       309544 rows created.

       SQL> commit;

       Commit complete.

       SQL> insert /*+ append */ into mac_kks select * from mac_kks;

       619088 rows created.

       SQL> commit;

       Commit complete.

       SQL> insert /*+ append */ into mac_kks select * from mac_kks;

       1238176 rows created.

       SQL> commit;

       Commit complete.

       

       

       SQL> oradebug setmypid

       Statement processed.

       SQL> oradebug tracefile_name

       Statement processed.

       SQL> alter table mac_kks add t2 char(2000) default ‘MACLEAN’;

       

       

       session B:

       SQL> oradebug setospid 32424

       Oracle pid: 17, Unix process pid: 32424, image: oracle@vrh8.oracle.com (TNS V1-V3)

       SQL> oradebug suspend;

       Statement processed.

       

       session C:

       select * from mac_kks where rownum=1; ==> hang

       session D:

       select * from mac_kks where rownum=1; ==> hang

       

       session E:

       SQL> select sid,event from v$session where wait_class!=’Idle’;

       SID EVENT

       ———- —————————————————————-

        141 SQL*Net message to client

        145 library cache lock

        149 cursor: pin S wait on X

        159 log buffer space

       SQL> oradebug setmypid

       Statement processed.

       SQL> oradebug dump systemstate 266;

       Statement processed.

       SQL> oradebug tracefile_name

       /s01/admin/G10R25/udump/g10r25_ora_32537.trc

       Object Names

       ~~~~~~~~~~~~

       LOCK: handle=a7115ef0

       Mutex 7fff7abadecf

       

       KGX Atomic Operation Log 0x8d88a8d8

        Mutex 0x954eaff8(145, 0) idn 7fff7abadecf oper EXCL

        Cursor Pin uid 145 efd 0 whr 1 slp 0

        opr=3 pso=0x97951af0 flg=0

        pcs=0x954eaff8 nxt=(nil) flg=35 cld=0 hd=0xa7864b08 par=0x9523a9e0

        ct=0 hsh=0 unp=(nil) unn=0 hvl=9595c3d8 nhv=1 ses=0xa8416738

        hep=0x954eb078 flg=80 ld=1 ob=0x95ac6128 ptr=0x8fd90128 fex=0x8fd8f438

       0x954eaff8(145, 0) ==> sid和 ref count

       pso ==> parent state object

       hd=0xa7864b08 ==>cursor 对应的handle address

       par ==> 父游标的heap 0 pointer

       ses=0xa8416738 ==》 一般 EXCL是才有 session address v$session.saddr

        SID=145 对Mutex 0x954eaff8 oper EXCL以X mode Hold 该Mutex, SID=145 在等 SYS.MAC_KKS表的library cache lock,该表被X mode pin和lock,而解析SQL要求以S mode lock该表

        SID=149 对Mutex 0x954eaff8 申请 oper GET_SHRD, SID=149在等cursor: pin S wait on X

        KGX Atomic Operation Log 0x8db79798

        Mutex 0x954eaff8(145, 0) idn 7fff7abadecf oper GET_SHRD

        Cursor Pin uid 149 efd 0 whr 5 slp 13893

        opr=2 pso=0x8e6bd518 flg=0

        pcs=0x954eaff8 nxt=(nil) flg=35 cld=0 hd=0xa7864b08 par=0x9523a9e0

        ct=0 hsh=0 unp=(nil) unn=0 hvl=9595c3d8 nhv=1 ses=0xa8416738

        hep=0x954eb078 flg=80 ld=1 ob=0x95ac6128 ptr=0x8fd90128 fex=0x8fd8f438

        SO: 0xa841bd18, type: 4, owner: 0xa830cf98, flag: INIT/-/-/0×00

        (session) sid: 149 trans: (nil), creator: 0xa830cf98, flag: (80000041) USR/- BSY/-/-/-/-/-

        DID: 0001-0019-00000066, short-term DID: 0000-0000-00000000

        txn branch: (nil)

        oct: 0, prv: 0, sql: 0x8d88bf90, psql: (nil), user: 0/SYS

        service name: SYS$USERS

        O/S info: user: oracle, term: pts/5, ospid: 32510, machine: vrh8.oracle.com

        program: sqlplus@vrh8.oracle.com (TNS V1-V3)

        application name: sqlplus@vrh8.oracle.com (TNS V1-V3), hash value=543908804

        waiting for ‘cursor: pin S wait on X’ wait_time=0, seconds since wait started=0

        idn=7abadecf, value=9100000000, where|sleeps=500003645

        blocking sess=0x(nil) seq=13901

        Dumping Session Wait History

        for ‘cursor: pin S wait on X’ count=1 wait_time=0.266596 sec

        idn=7abadecf, value=9100000000, where|sleeps=500003644

        for ‘cursor: pin S wait on X’ count=1 wait_time=0.010679 sec

        idn=7abadecf, value=9100000000, where|sleeps=500003643

        for ‘cursor: pin S wait on X’ count=1 wait_time=0.010633 sec

        idn=7abadecf, value=9100000000, where|sleeps=500003642

        for ‘cursor: pin S wait on X’ count=1 wait_time=0.010843 sec

        idn=7abadecf, value=9100000000, where|sleeps=500003641

        for ‘cursor: pin S wait on X’ count=1 wait_time=0.011008 sec

        idn=7abadecf, value=9100000000, where|sleeps=500003640

        for ‘cursor: pin S wait on X’ count=1 wait_time=0.010406 sec

       

       

       SO: 0xa8416738, type: 4, owner: 0xa830bfa8, flag: INIT/-/-/0×00

        (session) sid: 145 trans: (nil), creator: 0xa830bfa8, flag: (80000041) USR/- BSY/-/-/-/-/-

        DID: 0001-0017-0000008E, short-term DID: 0000-0000-00000000

        txn branch: (nil)

        oct: 3, prv: 0, sql: 0x8d88bf90, psql: (nil), user: 0/SYS

        service name: SYS$USERS

        O/S info: user: oracle, term: pts/4, ospid: 32485, machine: vrh8.oracle.com

        program: sqlplus@vrh8.oracle.com (TNS V1-V3)

        application name: sqlplus@vrh8.oracle.com (TNS V1-V3), hash value=543908804

        waiting for ‘library cache lock’ wait_time=0, seconds since wait started=165

        handle address=a7115ef0, lock address=978def20, 100*mode+namespace=c9

        blocking sess=0x(nil) seq=9

        Dumping Session Wait History

        for ‘library cache lock’ count=1 wait_time=3.297287 sec

        handle address=a7115ef0, lock address=978def20, 100*mode+namespace=c9

        for ‘library cache lock’ count=1 wait_time=2.930321 sec

        handle address=a7115ef0, lock address=978def20, 100*mode+namespace=c9

        for ‘library cache lock’ count=1 wait_time=2.930856 sec

        handle address=a7115ef0, lock address=978def20, 100*mode+namespace=c9

        for ‘library cache lock’ count=1 wait_time=2.930698 sec

        handle address=a7115ef0, lock address=978def20, 100*mode+namespace=c9

        for ‘library cache lock’ count=1 wait_time=2.931518 sec

        handle address=a7115ef0, lock address=978def20, 100*mode+namespace=c9

        SO: 0x978def20, type: 53, owner: 0xa8456058, flag: INIT/-/-/0×00

        LIBRARY OBJECT LOCK: lock=978def20 handle=a7115ef0 request=S

        call pin=(nil) session pin=(nil) hpc=0005 hlc=0000

        htl=0x978defa0[0x8e4a8950,0x8e4a8950] htb=0x8e4a8950 ssga=0x8e4a7a88

        user=a8416738 session=a8416738 count=0 flags=RES/[0010] savepoint=0x1f

        LIBRARY OBJECT HANDLE: handle=a7115ef0 mtx=0xa7116020(0) lct=8 pct=10 cdp=0

        name=SYS.MAC_KKS

        hash=c066b9b9c6c80736a15f5ba325563fdb timestamp=04-14-2013 00:43:14

        namespace=TABL flags=KGHP/TIM/SML/[02000000]

        kkkk-dddd-llll=0000-0701-0201 lock=X pin=X latch#=3 hpc=0006 hlc=0004

        lwt=0xa7115f98[0x978def50,0x978def50] ltm=0xa7115fa8[0xa7115fa8,0xa7115fa8]

        pwt=0xa7115f60[0xa7115f60,0xa7115f60] ptm=0xa7115f70[0xa7115f70,0xa7115f70]

        ref=0xa7115fc8[0xa7115fc8,0xa7115fc8] lnd=0xa7115fe0[0x9cc2c260,0xa79fd198]

        LIBRARY OBJECT: object=95f0e5b0

        type=TABL flags=EXS/LOC/UPD[0905] pflags=[0000] status=VALD load=0

        DATA BLOCKS:

        data# heap pointer status pins change whr

        —- ——- ——- ——— —- —— —

        0 a78d3840 95f0e708 I/P/A/-/- 0 NONE 00

        8 957a6ad8 94461f88 I/P/A/-/- 1 UPDATE 00

       Mutex 0x954eaff8 被 SID=145 oper EXCL以X mode Hold 该Mutex

       体现为 子游标child cursor被以 X mode pin

        SO: 0x8e6bd518, type: 53, owner: 0xa841bd18, flag: INIT/-/-/0×00

        LIBRARY OBJECT LOCK: lock=8e6bd518 handle=a7864b08 mode=N

        call pin=(nil) session pin=(nil) hpc=0000 hlc=0000

        htl=0x8e6bd598[0x8e542f60,0x979da4d0] htb=0x979da4d0 ssga=0x979d96c8

        user=a841bd18 session=a841bd18 count=1 flags=CBK[0020] savepoint=0×0

        LIBRARY OBJECT HANDLE: handle=a7864b08 mtx=0xa7864c38(0) lct=2 pct=3 cdp=0

        namespace=CRSR flags=RON/KGHP/PN0/EXP/[10010100]

        kkkk-dddd-llll=0000-0001-0001 lock=N pin=X latch#=3 hpc=0002 hlc=0002

        lwt=0xa7864bb0[0xa7864bb0,0xa7864bb0] ltm=0xa7864bc0[0xa7864bc0,0xa7864bc0]

        pwt=0xa7864b78[0xa7864b78,0xa7864b78] ptm=0xa7864b88[0xa7864b88,0xa7864b88]

        ref=0xa7864be0[0x954eb320,0x954eb320] lnd=0xa7864bf8[0xa7864bf8,0xa7864bf8]

        LIBRARY OBJECT: object=95ac6128

        type=CRSR flags=EXS[0001] pflags=[0000] status=VALD load=0

        DATA BLOCKS:

        data# heap pointer status pins change whr

        —- ——- ——- ——— —- —— —

        0 8d81aa70 95ac6240 I/P/A/-/- 0 NONE 00

        6 954eb0f0 8fd90128 I/P/A/-/E 0 NONE 00

        并行执行6个SQL语句 并做systemstate dump :

       

       [oracle@vrh8 ~]$ grep SHRD /s01/admin/G10R25/udump/g10r25_ora_32716.trc |grep 0×95987388

        Mutex 0×95987388(0, 6) idn 7fff8f32fff6 oper SHRD

        Mutex 0×95987388(0, 6) idn 7fff8f32fff6 oper SHRD

        Mutex 0×95987388(0, 6) idn 7fff8f32fff6 oper SHRD

        Mutex 0×95987388(0, 6) idn 7fff8f32fff6 oper SHRD

        Mutex 0×95987388(0, 6) idn 7fff8f32fff6 oper SHRD

        Mutex 0×95987388(0, 6) idn 7fff8f32fff6 oper SHRD

建议继续学习:

  1. Memcache mutex设计模式    (阅读:3760)
  2. Pthreads并行编程之spin lock与mutex性能对比分析    (阅读:2445)
  3. Oracle Mutex实现机制    (阅读:2009)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:Oracle数据恢复专题
后一篇:PL/SQL的那些事儿 >>
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1