[20200212]使用DBMS_SHARED_POOL.MARKHOT與檢視v$open_cursor.txt

lfree發表於2020-02-13

[20200212]使用DBMS_SHARED_POOL.MARKHOT與檢視v$open_cursor.txt

--//中午午休時,有點不理解使用DBMS_SHARED_POOL.MARKHOT標識熱sql語句時,測試反而更慢。
--//我再想一般引數open_cursors是設定,執行3次以上,以後sql語句的執行都是軟軟解析,會不會v$open_cursor裡面記錄還是原來的
--//sql_id呢?這樣軟軟解析就失效了,這樣必須測試確定在使用DBMS_SHARED_POOL.MARKHOT標識熱sql語句時,生成的sql_id會與原來不
--//同,測試檢視v$open_cursor記錄那個sql_id.

1.環境:
SYS@book> @ ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

$ cat bb1.txt
SELECT name
      ,hash_value
      ,full_hash_value
      ,namespace
      ,child_latch
      ,property hot_flag
      ,executions
      ,invalidations
  FROM v$db_object_cache
 WHERE name = 'select * from dept where deptno=10';

2.測試:
--//session 1:
SCOTT@book> @ spid

       SID    SERIAL# PROCESS                  SERVER    SPID       PID  P_SERIAL# C50
---------- ---------- ------------------------ --------- ------ ------- ---------- --------------------------------------------------
        44        279 2359                     DEDICATED 2360        27        102 alter system kill session '44,279' immediate;

SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
--//sql_id='4xamnunv51w9j'
--//session 2:
SYS@book> select * from v$open_cursor where sid=44 and SQL_ID='4xamnunv51w9j'
  2  @ prxx
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DDC5CD8
HASH_VALUE                    : 911274289
SQL_ID                        : 4xamnunv51w9j
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : OPEN
PL/SQL procedure successfully completed.

--//首先使用DBMS_SHARED_POOL.MARKHOT標記。
--//session 2:
SYS@book> @ bb1.txt
NAME                                     HASH_VALUE FULL_HASH_VALUE                  NAMESPACE        CHILD_LATCH HOT_FLAG   EXECUTIONS INVALIDATIONS
---------------------------------------- ---------- -------------------------------- ---------------- ----------- ---------- ---------- -------------
select * from dept where deptno=10        911274289 1431c45dbddbb9e74eaa74d53650f131 SQL AREA                   0                     1             0
select * from dept where deptno=10        911274289 1431c45dbddbb9e74eaa74d53650f131 SQL AREA               61745                     1             0

SYS@book> exec dbms_shared_pool.markhot( hash=>'1431c45dbddbb9e74eaa74d53650f131', namespace=>0, global=>true);
PL/SQL procedure successfully completed.

SYS@book> @ bb1.txt
NAME                                     HASH_VALUE FULL_HASH_VALUE                  NAMESPACE        CHILD_LATCH HOT_FLAG   EXECUTIONS INVALIDATIONS
---------------------------------------- ---------- -------------------------------- ---------------- ----------- ---------- ---------- -------------
select * from dept where deptno=10        911274289 1431c45dbddbb9e74eaa74d53650f131 SQL AREA                   0 HOT                 1             0
select * from dept where deptno=10        911274289 1431c45dbddbb9e74eaa74d53650f131 SQL AREA               61745 HOT                 1             0

--//session 1:
SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

--//session 2:
SYS@book> select * from v$open_cursor where sid=44 and SQL_ID='4xamnunv51w9j';
no rows selected
--//原來記錄的sql_id已經找不到相應記錄在v$open_cursor中,這樣看來記錄新的sql_id.

SYS@book> @ bb1.txt
NAME                                     HASH_VALUE FULL_HASH_VALUE                  NAMESPACE        CHILD_LATCH HOT_FLAG   EXECUTIONS INVALIDATIONS
---------------------------------------- ---------- -------------------------------- ---------------- ----------- ---------- ---------- -------------
select * from dept where deptno=10        911274289 1431c45dbddbb9e74eaa74d53650f131 SQL AREA                   0 HOT                 1             0
select * from dept where deptno=10        911274289 1431c45dbddbb9e74eaa74d53650f131 SQL AREA               61745 HOT                 1             0
select * from dept where deptno=10       3263113834 f41d12549d8b4d0ebb9d55c9c27f2a6a SQL AREA                   0 HOTCOPY45           1             0
select * from dept where deptno=10       3263113834 f41d12549d8b4d0ebb9d55c9c27f2a6a SQL AREA               76394 HOTCOPY45           1             0
--//注:當前_kgl_hot_object_copies=101.所以出現HOTCOPY45. mod(sid,101)+1=mod(44,101)+1=45.

--//session 1:
SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

--//session 2:
SYS@book> select * from v$open_cursor where sid=44 and SQL_ID='4xamnunv51w9j';
no rows selected
--//噢不能在這樣查詢,改寫如下.

SYS@book> select * from v$open_cursor where sid=44 and sql_text like 'select * from dept where deptno=10'
  2  @ prxx
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : OPEN
PL/SQL procedure successfully completed.
--//記錄的sql_id=br7apt717yama.不再是原來的sql_id=4xamnunv51w9j.

--//session 1:
SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

--//sesson 2:
SYS@book> select * from v$open_cursor where sid=44 and sql_text like 'select * from dept where deptno=10'
  2  @ prxx
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : OPEN
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : DICTIONARY LOOKUP CURSOR CACHED
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : DICTIONARY LOOKUP CURSOR CACHED
PL/SQL procedure successfully completed.
--//噢,出現奇特的現象,在檢視v$open_cursor 當前sid=44記錄了3條。

SYS@book> select distinct * from v$open_cursor where sid=44 and sql_text = 'select * from dept where deptno=10'
  2   @prxx
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : OPEN
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : DICTIONARY LOOKUP CURSOR CACHED
PL/SQL procedure successfully completed.
--//差異在CURSOR_TYPE,查詢CURSOR_TYPE有2個值DICTIONARY LOOKUP CURSOR CACHED,OPEN。

--//session 1:
SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        
--//session 2:
SYS@book> select  count(*) from v$open_cursor where sid=44 and sql_text = 'select * from dept where deptno=10';
  COUNT(*)
----------
         5
--//記錄了5條。
SYS@book> select distinct * from v$open_cursor where sid=44 and sql_text = 'select * from dept where deptno=10'
  2  @ prxx
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : OPEN
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : DICTIONARY LOOKUP CURSOR CACHED
PL/SQL procedure successfully completed.
--//ADDRESS記錄父遊標的地址。可以驗證卡看看。

SYS@book> @ sharepool/shp4 br7apt717yama 0
TEXT           KGLHDADR         KGLHDPAR         C40                                        KGLHDLMD   KGLHDPMD   KGLHDIVC KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16   N0_6_16        N20   KGLNAHSH KGLOBT03        KGLOBT09
-------------- ---------------- ---------------- ---------------------------------------- ---------- ---------- ---------- ---------------- ---------------- ---------- ---------- ---------- --------- ---------- ---------- ------------- ----------
子游標控制程式碼地址 000000007C0D1150 000000007DCA5958 select * from dept where deptno=10                1          0          0 000000007E258468 000000007BE93F00       4528      12144       3069     19741      19741 3263113834 br7apt717yama          0
父遊標控制程式碼地址 000000007DCA5958 000000007DCA5958 select * from dept where deptno=10                1          0          0 000000007C688068 00                     4720          0          0      4720       4720 3263113834 br7apt717yama      65535
--//父遊標控制程式碼地址=000000007DCA5958.

SYS@book> select CURSOR_TYPE from v$open_cursor where sid=44 and sql_text = 'select * from dept where deptno=10';
CURSOR_TYPE
----------------------------------------------------------------
OPEN
DICTIONARY LOOKUP CURSOR CACHED
DICTIONARY LOOKUP CURSOR CACHED
DICTIONARY LOOKUP CURSOR CACHED
DICTIONARY LOOKUP CURSOR CACHED
--//僅僅CURSOR_TYPE不同。

--//session 1:
SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

--//session 2:
SYS@book> select  count(*) from v$open_cursor where sid=44 and sql_text = 'select * from dept where deptno=10';
  COUNT(*)
----------
         7
--//增加了2條。

--//session 1:
SCOTT@book> select sysdate from dual ;
SYSDATE
-------------------
2020-02-12 16:26:44

SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

--//session 2:
SYS@book> select  count(*) from v$open_cursor where sid=44 and sql_text = 'select * from dept where deptno=10';
  COUNT(*)
----------
         8

--//很明顯在使用BMS_SHARED_POOL.MARKHOT標識熱sql語句時存在bug或者問題.也許正是這樣的情況導致出現library cache: mutex X。
--//我的測試很特別,沒有退出會話執行dbms_shared_pool.markhot標識熱sql語句,建立新會話看看。

3.繼續測試:
--//session 1:退出再登入。
SCOTT@book> @ spid
       SID    SERIAL# PROCESS                  SERVER    SPID       PID  P_SERIAL# C50
---------- ---------- ------------------------ --------- ------ ------- ---------- --------------------------------------------------
        44        283 2500                     DEDICATED 2501        27        104 alter system kill session '44,283' immediate;

--//sid=44,但是serial#發生變化。
--//session 2:
SYS@book> select  * from v$open_cursor where sid=44 and sql_text = 'select * from dept where deptno=10'
  2  @ prxx
PL/SQL procedure successfully completed.

--//session 1:
SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

--//session 2:
SYS@book> select  * from v$open_cursor where sid=44 and sql_text = 'select * from dept where deptno=10'
  2  @ prxx
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : OPEN
PL/SQL procedure successfully completed.

--//session 1:
SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

SYS@book> select  * from v$open_cursor where sid=44 and sql_text = 'select * from dept where deptno=10'
  2  @prxx
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : OPEN
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : DICTIONARY LOOKUP CURSOR CACHED
PL/SQL procedure successfully completed.

--//session 1:
SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

--//session 2:        
SYS@book> @prxx
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : OPEN
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : DICTIONARY LOOKUP CURSOR CACHED
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : DICTIONARY LOOKUP CURSOR CACHED
PL/SQL procedure successfully completed.
--//依舊出現問題。感覺這個是使用DBMS_SHARED_POOL.MARKHOT標識熱sql語句的bug。

4.取消DBMS_SHARED_POOL.MARKHOT標識熱sql語句看看。
--//session 2:
SYS@book> exec dbms_shared_pool.unmarkhot( hash=>'1431c45dbddbb9e74eaa74d53650f131', namespace=>0, global=>true);
PL/SQL procedure successfully completed.

--//session 1:
SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

--//session 2:
SYS@book> select  * from v$open_cursor where sid=44 and sql_text = 'select * from dept where deptno=10'
  2  @ prxx
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DDC5CD8
HASH_VALUE                    : 911274289
SQL_ID                        : 4xamnunv51w9j
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : OPEN
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : DICTIONARY LOOKUP CURSOR CACHED
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : DICTIONARY LOOKUP CURSOR CACHED
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DCA5958
HASH_VALUE                    : 3263113834
SQL_ID                        : br7apt717yama
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : DICTIONARY LOOKUP CURSOR CACHED
PL/SQL procedure successfully completed.
--//其它記錄依舊存在。但是增加1條sql_id=4xamnunv51w9j,注意看下劃線。

SYS@book> select  * from v$open_cursor where sid=44 and sql_text = 'select * from dept where deptno=10' and sql_id='4xamnunv51w9j'
  2  @ prxx
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DDC5CD8
HASH_VALUE                    : 911274289
SQL_ID                        : 4xamnunv51w9j
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : OPEN
PL/SQL procedure successfully completed.

--//session 1:
SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

SCOTT@book> select * from dept where deptno=10;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK

--//session 2:
SYS@book> @ prxx
==============================
SADDR                         : 000000008638EC10
SID                           : 44
USER_NAME                     : SCOTT
ADDRESS                       : 000000007DDC5CD8
HASH_VALUE                    : 911274289
SQL_ID                        : 4xamnunv51w9j
SQL_TEXT                      : select * from dept where deptno=10
LAST_SQL_ACTIVE_TIME          :
SQL_EXEC_ID                   :
CURSOR_TYPE                   : SESSION CURSOR CACHED
PL/SQL procedure successfully completed.
--//注意看CURSOR_TYPE='SESSION CURSOR CACHED'.而且僅僅1條記錄。
--//而前面的都是停留在CURSOR_TYPE='DICTIONARY LOOKUP CURSOR CACHED',並且多次出現.感覺是bug的可能性更大.
--//也許正是這個問題導致設定後反而更慢。

總結:
1.使用DBMS_SHARED_POOL.MARKHOT標識熱sql語句,v$open_cursor記錄的是變化的sql_id.
2.我個人認為這個是bug,不建議使用DBMS_SHARED_POOL.MARKHOT標識熱sql語句.

--//附上shp4.sql指令碼:
column N0_6_16 format 99999999
SELECT DECODE (kglhdadr,
               kglhdpar, '父遊標控制程式碼地址',
               '子游標控制程式碼地址')
          text,
       kglhdadr,
       kglhdpar,
       substr(kglnaobj,1,40) c40,
       KGLHDLMD,
       KGLHDPMD,
       kglhdivc,
       kglobhd0,
       kglobhd6,
       kglobhs0,kglobhs6,kglobt16,
       kglobhs0+kglobhs6+kglobt16 N0_6_16,
       kglobhs0+kglobhs1+kglobhs2+kglobhs3+kglobhs4+kglobhs5+kglobhs6+kglobt16 N20,
       kglnahsh,
       kglobt03 ,
       kglobt09  
  FROM x$kglob
 WHERE kglobt03 = '&1'  or kglhdpar='&1' or kglhdadr='&1' or KGLNAHSH= &2;

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2675362/,如需轉載,請註明出處,否則將追究法律責任。

相關文章