library cache: mutex X

library cache: mutex X

lcmx is an event which occur due to shared pool contention in SGA.

Shared pool is used to share the SQL area to be reused by multiple cursors. Every objects in shared pool are interrelated.

In order to understand any shared pool events, it is a prerequisite to understand CURSOR

cursor is an object in programming world to allocate a connection or pipeline to execute SQL queries or PLSQL. cursor can be used to create a connection, execute, fetch, pin, invalidate and reload etc.

To get an idea on the cursor, below example demonstrates a practical example,

Number of parse calls increase for sql statement as per the individual parameter or setting.

Child number increase as per the different settings used to execute the same sql.

kIsH@STAX<>alter session set "_hash_join_enabled"=false;

Session altered.

kIsH@STAX<>select count(*) from xtbl;

  COUNT(*)
----------
   1000000

kIsH@STAX<>alter session set "_hash_join_enabled"=true;

Session altered.

kIsH@STAX<>select count(*) from xtbl;

  COUNT(*)
----------
   1000000

kIsH@STAX<>SELECT sql_id from v$sql where sql_text like '%select count(*) from xtbl%';

SQL_ID
-------------
fmhv6xyq0tzg6
fmhv6xyq0tzg6

kIsH@STAX<>set lines 200 pages 1000
kIsH@STAX<>SELECT SQL_ID,VERSION_COUNT,LOADED_VERSIONS,LOADS,INVALIDATIONS,PARSE_CALLS from v$sqlarea WHERE sql_id='fmhv6xyq0tzg6';

SQL_ID        VERSION_COUNT LOADED_VERSIONS      LOADS INVALIDATIONS PARSE_CALLS
------------- ------------- --------------- ---------- ------------- -----------
fmhv6xyq0tzg6             2               2          2             0           2


kIsH@STAX<>SELECT SQL_ID,CHILD_NUMBER,LOADED_VERSIONS,LOADS,INVALIDATIONS,PARSE_CALLS from v$sql WHERE sql_id='fmhv6xyq0tzg6';

SQL_ID        CHILD_NUMBER LOADED_VERSIONS      LOADS INVALIDATIONS PARSE_CALLS
------------- ------------ --------------- ---------- ------------- -----------
fmhv6xyq0tzg6            0               1          1             0           1
fmhv6xyq0tzg6            1               1          1             0           1

kIsH@STAX<>alter session set optimizer_mode=first_rows;

Session altered.

kIsH@STAX<>select count(*) from xtbl;

  COUNT(*)
----------
   1000000

kIsH@STAX<>SELECT SQL_ID,CHILD_NUMBER,LOADED_VERSIONS,LOADS,INVALIDATIONS,PARSE_CALLS from v$sql WHERE sql_id='fmhv6xyq0tzg6';

SQL_ID        CHILD_NUMBER LOADED_VERSIONS      LOADS INVALIDATIONS PARSE_CALLS
------------- ------------ --------------- ---------- ------------- -----------
fmhv6xyq0tzg6            0               1          1             0           1
fmhv6xyq0tzg6            1               1          1             0           1
fmhv6xyq0tzg6            2               1          1             0           1

Example: Consider table X. This table has a column c. There are millions of rows r in X.

If there is a maintenance activity on column c. If c is either dropped or existing attributes are modified for the column, then all relational objects become invalid and SQL statements which rely on the column data are affected. When the cursor become invalid, they need to be recompiled and reloaded into the shared pool again which has to go through latch, pin and locks. Cursor should be compiled to make the object valid. During compilation process, the cursor is pinned and locked to prevent other process from modifying them which further leads to cursor pin events, if the process holds the lock for long time. Thus, concurrency is maintained.

https://alphaoragroup.com/?p=18617

Primary reason for lcmx is inefficient parsing of sql statements

  • Hard parse
  • High number of Child cursors
  • Cursor Invalidations
  • Cursor Recompilation and Reloads
WHO     PGM   W_CHAINS                                 SQL_ID             TOTAL CHART_WCLASS         STATE       TAASH       IAAS
------- ----- ---------------------------------------- ------------- ---------- -------------------- ---------- ------ ----------
SYS     TNS V library cache: mutex X                   11c4s0a35j48v    1506123  c/_\c/_\c/_\c/_\c/_ LONG_WAIT      20 .000077683
        1-V3                                                                    \c/_\c/_\c/_\c/_\c/_
                                                                                \c/_\c/_\c/_\c/_\c/_
                                                                                \c/_\c/_\c/_\c/_\c/_
                                                                                \c/_\c/_\c/_\c/_\c/_
                                                                                \c/_\c/_\c/_\c/_\c/_
                                                                                \c/_\c/_\c/_\c/_\c/_
                                                                                \c/_\c/_\c

SYS     TNS V latch free                               11c4s0a35j48v    1329348  OOOOOOOOOOOOOOOOOOO LONG_WAIT      20 .000088013
        1-V3                                                                    OOOOOOOOOOOOOOOOOOOO
                                                                                OOOOOOOOOOOOOOOOOOOO
                                                                                OOOOOOOOOOOOOOOOOOOO
                                                                                OOOOOOOOOOOOOOOOOOOO
                                                                                OOOOOOOOOOOOOOOOOOOO
                                                                                OOOOOOOOOOOO

SYS     TNS V library cache: mutex X                                     766025  c/_\c/_\c/_\c/_\c/_ LONG_WAIT      20 .000152737
        1-V3                                                                    \c/_\c/_\c/_\c/_\c/_
                                                                                \c/_\c/_\c/_\c/_\c/_
                                                                                \c/_\c/_\c/_\c/_

SYS     TNS V On CPU                                   11c4s0a35j48v     476114  ################### BURN_CPU       20 .000245739
        1-V3                                                                    ####################
                                                                                #######

SYS     TNS V |latch free [|]<~~~ latch free|          11c4s0a35j48v     391262  OOOOOOOOOOOOOOOOOOO LONG_WAIT      20 .000299032
        1-V3                                                                    OOOOOOOOOOOOOOOOOOO

SYS     TNS V On CPU                                   d8dxvkk7hxvq0     353550  ################### BURN_CPU       20 .000330929
        1-V3                                                                    ###############


6 rows selected.

kIsH@STAX<>alter session set tracefile_identifier='lbm1';

Session altered.

kIsH@STAX<>alter session set events 'immediate trace name library_cache level 12';

Session altered.

kIsH@STAX<>select count(*) from kish.xtbl;

  COUNT(*)
----------
   1000000

kIsH@STAX<>alter session set "_hash_join_enabled"=false;

Session altered.

kIsH@STAX<>select count(*) from kish.xtbl;

  COUNT(*)
----------
   1000000


kIsH@STAX<>alter session set events 'immediate trace name library_cache off';

Session altered.

Bucket: #=69360 Mutex=0x764078a8(777389080576, 6, 0, 6) 
  LibraryHandle:  Address=0x6cd99550 Hash=3970ef0 LockMode=0 PinMode=0 LoadLockMode=0 Status=VALD Subpool=1 
    ObjectName:  Name=CDB$ROOT.KISH.XTBL   
      FullHashValue=e2ae0aa2266ca38b5dd42deb03970ef0 Namespace=TABLE/PROCEDURE(01) Type=TABLE(02) ContainerId=1 ContainerUid=1 Identifier=74650 OwnerIdn=108 
    Statistics:  InvalidationCount=0 ExecutionCount=0 LoadCount=1 ActiveLocks=0 TotalLockCount=4 TotalPinCount=4 
    Counters:  BrokenCount=1 RevocablePointer=1 KeepDependency=0 Version=0 BucketInUse=1 HandleInUse=1 HandleReferenceCount=0 
    Concurrency:  DependencyMutex=0x6cd99600(0, 2, 0, 0) Mutex=0x6cd996a0(181, 47, 0, 6) 
    Flags=PIN/TIM/[00002801] Flags2=[0000] 
    WaitersLists:  
      Lock=0x6cd995e0[0x6cd995e0,0x6cd995e0] 
      Pin=0x6cd995c0[0x6cd995c0,0x6cd995c0] 
      LoadLock=0x6cd99638[0x6cd99638,0x6cd99638] 
    Timestamp:  Current=12-14-2022 17:26:06 
    HandleReference:  Address=0x6cd99720 Handle=0x6cd662f8 Flags=OWN[200] 
    ReferenceList:  
      Reference:  Address=0x6bef89b8 Handle=0x6c650728 Flags=DEP[01] 
        Timestamp=12-14-2022 17:26:06 InvalidatedFrom=0 
      Reference:  Address=0x76e4f428 Handle=0x6cdc58b0 Flags=DEP[01] 
        Timestamp=12-14-2022 17:26:06 InvalidatedFrom=0 
    LibraryObject:  Address=0x74631438 HeapMask=0000-0701-0701-0000 Flags=EXS/LOC[0004] Flags2=/CSO[8000000] Flags3=/DVC[0020] PublicFlags=[0000] 
      DataBlocks:  
        Block:  #='0' name=KGLH0^3970ef0 pins=0 Change=NONE   
          Heap=0x6ccd8ff8 Pointer=0x74631518 Extent=0x74631378 Flags=I/-/-/A/-/-/- 
          FreedLocation=0 Alloc=1.531250 Size=3.976562 LoadTime=01-24-2023 15:35:43 
        Block:  #='8' name=KGLS^3970ef0 pins=0 Change=NONE   
          Heap=0x74631810 Pointer=0x6a0d9440 Extent=0x6a0d8760 Flags=I/-/-/A/-/-/- 
          FreedLocation=0 Alloc=5.078125 Size=7.898438 LoadTime=01-24-2023 15:35:43 
        Block:  #='9' name=KGLS^3970ef0 pins=0 Change=NONE   
          Heap=0x74631968 Pointer=0x6a0d7590 Extent=0x6a0d6760 Flags=I/-/-/A/-/-/- 
          FreedLocation=0 Alloc=0.429688 Size=3.937500 LoadTime=01-24-2023 15:35:43 
        Block:  #='10' name=KGLS^3970ef0 pins=0 Change=NONE   
          Heap=0x74631a00 Pointer=0x6a0d6670 Extent=0x6a0d5760 Flags=I/-/-/A/-/-/- 
          FreedLocation=0 Alloc=4.601562 Size=7.898438 LoadTime=01-24-2023 15:35:43 

Bucket: #=99385 Mutex=0x7652d370(777389080576, 9, 0, 6) 
  LibraryHandle:  Address=0x6f53e270 Hash=73218439 LockMode=0 PinMode=0 LoadLockMode=0 Status=VALD Subpool=1 
    ObjectName:  Name=select count(*) from kish.xtbl 
      FullHashValue=175ea436befe4c3153afc49073218439 Namespace=SQL AREA(00) Type=CURSOR(00) ContainerId=1 ContainerUid=1 Identifier=1931576377 OwnerIdn=0 
    Statistics:  InvalidationCount=0 ExecutionCount=4 LoadCount=3 ActiveLocks=0 TotalLockCount=4 TotalPinCount=1 
    Counters:  BrokenCount=1 RevocablePointer=1 KeepDependency=2 Version=0 BucketInUse=3 HandleInUse=3 HandleReferenceCount=0 
    Concurrency:  DependencyMutex=0x6f53e320(0, 2, 0, 0) Mutex=0x6f53e3c0(181, 50, 0, 6) 
    Flags=RON/PIN/TIM/PN0/DBN/[10012841] Flags2=[0000] 
    WaitersLists:  
      Lock=0x6f53e300[0x6f53e300,0x6f53e300] 
      Pin=0x6f53e2e0[0x6f53e2e0,0x6f53e2e0] 
      LoadLock=0x6f53e358[0x6f53e358,0x6f53e358] 
    Timestamp:  Current=01-24-2023 21:05:43 
    HandleReference:  Address=0x6f53e450 Handle=(nil) Flags=[00] 
    ReferenceList:  
      Reference:  Address=0x6bef7670 Handle=0x6c650300 Flags=ROD[21] 
      Reference:  Address=0x7463ac68 Handle=0x6cd99978 Flags=ROD[21] 
    LibraryObject:  Address=0x75f46708 HeapMask=0000-0001-0001-0000 Flags=EXS[0000] Flags2=[0000] Flags3=[0000] PublicFlags=[0000] 
      DataBlocks:  
        Block:  #='0' name=KGLH0^73218439 pins=0 Change=NONE   
          Heap=0x6f27f0e0 Pointer=0x75f467e8 Extent=0x75f46648 Flags=I/-/P/A/-/-/- 
          FreedLocation=0 Alloc=5.445312 Size=7.953125 LoadTime=01-24-2023 15:35:43 
      ChildTable:  size='16' 
        Child:  id='0' Table=0x75f47570 Reference=0x75f47108 Handle=0x6cdc58b0 
        Child:  id='1' Table=0x75f47570 Reference=0x6bef9768 Handle=0x6c650728 
    NamespaceDump:  
      Parent Cursor:  sql_id=57by4k1tk311t parent=0x75f467e8 maxchild=2 plk=n ppn=n prsfcnt=0 obscnt=0 
        CursorDiagnosticsNodes:  
          ChildNode:  ChildNumber=1 ID=3 reason=Optimizer mismatch(12) size=2x476 _hash_join_enabled= false                true                 
          ChildNode:  ChildNumber=0 ID=3 reason=Optimizer mismatch(12) size=2x476 _hash_join_enabled= true                 false             

KGLH0 is a heap object which is connected to the Shared Pool’s SQL Area. KGLH0 is used by each child cursor.
When there are many of child cursors and the parent cursor is not shared, large allocation in KGLH0 can happen.

sqlplus /nolog
connect / as sysdba
oradebug setmypid
oradebug unlimit
oradebug dump heapdump 536870914
oradebug tracefile_name
oradebug close_trace

sqlplus /nolog
connect / as sysdba
alter system set events '10235 level 65536';
exit

Then wait a while for the ORA-4031 (or at least the memory allocations) to occur, and then execute:
sqlplus /nolog
connect / as sysdba
oradebug setmypid
oradebug unlimit
oradebug dump heapdump 536870914
oradebug tracefile_name
oradebug close_trace

once done you can disable the event using

alter system set events '10235 off';

kIsH@STAX<>SELECT NAMESPACE,sum(GETS),sum(PINS),sum(RELOADS),sum(INVALIDATIONS) from dba_hist_librarycache GROUP BY NAMESPACE ORDER BY sum(GETS) DESC;

NAMESPACE        SUM(GETS)  SUM(PINS) SUM(RELOADS) SUM(INVALIDATIONS)
--------------- ---------- ---------- ------------ ------------------
SQL AREA           1359605 1810760712         5253              10401
TABLE/PROCEDURE     511634  902108609         2282                  9
SCHEMA              247617          0            0                  0
DBLINK              170599          0            0                  0
BODY                164637  901113014           45                  0
SQL AREA STATS       84322      84322            0                  0
SQL AREA BUILD       83669          0            0                  0
TRIGGER              62821      62821            0                  0
EDITION              60946      60946            0                  0
CLUSTER              23775      27501            0                  0
INDEX                15179      12515            0                  0
FED APP               5481       5481            0                  0
CMP                   2787       2787            0                  0
OBJECT ID             2506          0            0                  0
DIRECTORY              621        657            0                  0
ACCOUNT_STATUS         549          0            0                  0
APP STATE              324          0            0                  0
PDB                    270          0            0                  0
QUEUE                  255        345            0                  0
PDBOPER                147          0            0                  0
DBINSTANCE              90          0            0                  0
SUBSCRIPTION            88         88            0                  0
RULESET                 45        135            0                  0
USER PRIVILEGE           2          4            0                  0
APP CONTEXT              2          4            0                  0
XML SCHEMA               1          0            0                  0

26 rows selected.

kIsH@STAX<>var x varchar2(10)
kIsH@STAX<>exec :x := 369

PL/SQL procedure successfully completed.

kIsH@STAX<>SELECT count(*) from t1 where N1=:x;

  COUNT(*)
----------
         1

kIsH@STAX<>select * from table(dbms_xplan.display_cursor());

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  93uqjw965fzpy, child number 0
-------------------------------------
SELECT count(*) from t1 where N1=:x

Plan hash value: 3724264953

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |       |       |     3 (100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |     3 |            |          |
|*  2 |   TABLE ACCESS FULL| T1   |     1 |     3 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("N1"=TO_NUMBER(:X))


19 rows selected.

kIsH@STAX<>var x varchar2(20)
kIsH@STAX<>exec :x := 369

PL/SQL procedure successfully completed.

kIsH@STAX<>SELECT count(*) from t1 where N1=:x;

  COUNT(*)
----------
         1

kIsH@STAX<>select * from table(dbms_xplan.display_cursor());

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  93uqjw965fzpy, child number 0
-------------------------------------
SELECT count(*) from t1 where N1=:x

Plan hash value: 3724264953

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |       |       |     3 (100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |     3 |            |          |
|*  2 |   TABLE ACCESS FULL| T1   |     1 |     3 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("N1"=TO_NUMBER(:X))


19 rows selected.

Leave a Reply

%d bloggers like this: