【SQL 基礎】游標(curosr)(二)如何調查子游標的增加

  • 2020 年 3 月 26 日
  • 筆記

概述

本文主要通過例子介紹如何調查子游標的增加。

關於游標的基礎,大家可以參考前一篇【游標(curosr)】。

如何調查子游標的增加

下面我們通過例子來介紹如何調查子游標的增加。

0 .準備測試數據

SQL> conn scott/tiger  Connected.  SQL> var v1 varchar2(4);  SQL>  begin   :v1 := 'WARD';  end;  /  2    3    4  PL/SQL procedure successfully completed.SQL> select /* Cursor TEST */ * from emp where ENAME= :v1;    EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM    DEPTNO  ---------- ---------- --------- ---------- --------- ---------- ---------- ----------       7521 WARD       SALESMAN        7698 22-FEB-81       1250        500        30SQL> var v1 varchar2(100);  SQL> begin  :v1 := 'SMITH';  end;  /  2    3    4  PL/SQL procedure successfully completed.SQL> select /* Cursor TEST */ * from emp where ENAME= :v1;    EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO  ---------- ---------- --------- ---------- --------- ---------- ---------- ----------       7369 SMITH      CLERK           7902 17-DEC-80        800                    20

1 .通過v$sqlarea 視圖查看執行後的狀況

SQL> select sql_id,sql_text,version_count  from v$sqlarea  where sql_text like 'select /* Cursor TEST */ %';  2    3  SQL_ID  -------------  SQL_TEXT  ----------------------------------------------------  VERSION_COUNT  -------------  fawn2kwuxq1dq  select /* Cursor TEST */ * from emp where ENAME= :v1             2 ★VERSION_COUNT為2,產生了不同的子游標SQL> select SQL_ID,CHILD_NUMBER,EXECUTIONS from v$sql where sql_id='fawn2kwuxq1dq';SQL_ID        CHILD_NUMBER EXECUTIONS  ------------- ------------ ----------  fawn2kwuxq1dq            0          1  fawn2kwuxq1dq            1          1

我們可以看到相同的SQL文,產生了不同的子游標

方法1:v$sqlsharedcursor

2 .通過v$sqlsharedcursor 查看不能產生了不同子游標的原因

SQL> set linesize 500  SQL> select * from v$sql_shared_cursor where sql_id='fawn2kwuxq1dq';SQL_ID        ADDRESS          CHILD_ADDRESS    CHILD_NUMBER U S O O S L F E B P I S T A B D L T B I I R L I O E M U T N F A P T D L D B P C S C P T M B M R O P M F L P L A F L R L H P B U REASON  ------------- ---------------- ---------------- ------------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --------------------------------------------------------------------------------  fawn2kwuxq1dq 000000008B8644C8 000000008B864048            0 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N <ChildNode><ChildNumber>0</ChildNumber><ID>40</ID><reason>Bind mismatch(22)</rea  fawn2kwuxq1dq 000000008B8644C8 000000008A6415E0            1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N Y N <ChildNode><ChildNumber>1</ChildNumber><ID>40</ID><reason>Bind mismatch(22)</rea

通過v$sqlsharedcursor視圖我們看到,子游標(CHILD_NUMBER:1)產生的原因是BINDLENGTHUPGRADEABLE,即: 新執行SQL的綁定變數的長度超過了以前執行時的變數定義長度。

(倒數第三的B列的值為Y,通過查詢v$sqlsharedcursor視圖定義,我們知道代表著BINDLENGTHUPGRADEABLE)。

方法2:CURSORTRACE

雖然對於本次問題我們很容易能夠定義到原因,如果是10g以後的版本,對於某些情況或非常複雜的問題,我們可以使用CURSORTRACE 的功能來輔助調查。 CURSORTRACE 的使用方法如下:

10g以後的版本:<設定CURSORTRACE >  alter system set events 'immediate trace name cursortrace level <n>, address hash_value';<關閉CURSORTRACE>  alter system set events 'immediate trace name cursortrace level 2147483648, address 1';其中, <n>為跟蹤的級別,通常可以設的值 :(577=level 1, 578=level 2, 580=level 3);  hash_value為SQL文的Hash值。

※注意:CURSORTRACE 必須是在產生子游標的過程中有效,才能輸出一些有用的資訊。

下面我們接著上面的例子

3.1 定位SQL的HASH_VALUE

SQL> select sql_id, sql_text, hash_value from v$sqlarea where sql_text like 'select /* Cursor TEST */ %';SQL_ID  -------------  SQL_TEXT  -----------------------------------------------------  HASH_VALUE  ----------  fawn2kwuxq1dq  select /* Cursor TEST */ * from emp where ENAME= :v1  903546294 ★hash_value

3.2 設定CURSORTRACE 為level 1。

SQL> alter system set events 'immediate trace name cursortrace level 577, address 903546294';System altered.

3.3 產生一個新的子游標。

SQL> var v1 varchar2(800);  SQL> begin  :v1 := 'MILLER';  end;  /  2    3    4  PL/SQL procedure successfully completed.SQL> select /* Cursor TEST */ * from emp where ENAME= :v1;    EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO  ---------- ---------- --------- ---------- --------- ---------- ---------- ----------       7934 MILLER     CLERK           7782 23-JAN-82       1300                    10

3.4 查看執行情況

SQL> select SQL_ID,CHILD_NUMBER,EXECUTIONS from v$sql where sql_id='fawn2kwuxq1dq';SQL_ID        CHILD_NUMBER EXECUTIONS  ------------- ------------ ----------  fawn2kwuxq1dq            0          1  fawn2kwuxq1dq            1          1  fawn2kwuxq1dq            2          1 ★產生了新的子游標

3.5 關閉CURSORTRACE

SQL> alter system set events 'immediate trace name cursortrace level 2147483648, address 1';System altered.

3.6 輸出的CURSORTRACE例:

CUR#1 XSC 0x2b613f6f25d0 CHILD#-1 CI (nil) CTX (nil)  PARSING SQLTEXT=select /* Cursor TEST */ * from emp where ENAME= :v1  SQLHASH=35db05b6  Checking for already pinned child. fbcflg 108  No valid child pinned  Parent 0x8a7f5940(0x8a7ea7d0) ready for search  kksCheckCursor: next child is #1  kksCheckCursor: pinning child #1 in shared mode 0x8a7f5840 0x8a7dad48  Compilation environment difference Failed sharing : 0  SQL pgadep:0 pgapls:0 user  Calling for auth  Checking for already pinned child. fbcflg 102  Object is invalid  No valid child pinned  Parent 0x8a7f5940(0x8a7ea7d0) ready for search  kksCheckCursor: next child is #1  kksCheckCursor: pinning child #1 in shared mode 0x8a7f5840 0x8a7dad48  Compilation environment difference Failed sharing : 0  SQL pgadep:0 pgapls:0 user  Calling for auth  kksUnlockChild: releasing child  Failed sharing : 4000000000000000★查找失敗的原因4000000000000000  kksSearchChildList: no suitable child found (hash_match=1)  SearchChildList failed ctx=(nil) xscflg=100432 ctxflg=0 flg=102  allocated new child slot bi=0x8a96c048 flg=1 cld=2 hsh=35db05b6  kkshinins insert child into incomplete list bi=0x8a96c048 cld=2 flg=25  Created new child obj #2 dsfl=2002011 8003c00 xsc=0x2b613f6f25d0 chd=0x8a660b20 clk=0x91eb2710 ★追加了一個新的子游標  Pin new child obj #2 dsfl=2002011 xsc=0x2b613f6f25d0 chd=0x8a660b20 clk=0x91eb2710 cpn=(nil)  kksLoadChild: reload 0 path 2  kksLoadChild: reload 0 path 3  Compilation environment difference Failed sharing : 0  Change in cursor environment  SQL pgadep:0 pgapls:0 user  Compilation environment difference Failed sharing : 0  Change in cursor environment  SQL pgadep:0 pgapls:0 user  Compilation environment difference Failed sharing : 0  Change in cursor environment  SQL pgadep:0 pgapls:0 user  Compilation environment difference Failed sharing : 0  Change in cursor environment  SQL pgadep:0 pgapls:0 user  Child creation successful xsc=0x2b613f6f25d0 chd=0x8a660b20 cpn=0x8bba3680 sta=0 bi=0x8a96c048 cld=2  Add new child to parent list pi=0x8abad150 psn=2 bi=0x8a96c048 cld=2 flg=35 ★  kkshindel remove child from incomplete list bi=0x8a96c048 cld=2 flg=30  kkshhcins insert child into hash table bi=0x8a96c048 cld=2 flg=38  Downgrading child pin to share  Cursor about get executed  Checking for already pinned child. fbcflg 1  Checking for already pinned child. fbcflg 1  Cursor#1 mapped  Cursor unmapped*** 2016-07-19 13:35:10.907  CUR#1 XSC 0x2b613f6f25d0 CHILD#2 CI 0x8a96b150 CTX (nil)  Cursor#1 mapped  Closing cursor

根據上面的 輸出我們可以看到查找失敗的原因是4000000000000000,即:bind length upgradeable (當游標共享失敗時,Oracle會更新位向量(bit vector)的值,來表明失敗的原因。如下面的值。)

Failed sharing : 4000000000000000★

方法3:cursordump

在11.2以後的環境中還可以通過cursordump來查看子游標產生的原因:

cursordump的取得方法:

alter system set events 'immediate trace name cursordump level 16'

4 .輸出的cursordump例:

Bucket: #=66998 Mutex=0x8e099ca0(0, 14, 0, 6)   LibraryHandle:  Address=0x8a7ea7d0 Hash=35db05b6 LockMode=0 PinMode=0 LoadLockMode=0 Status=VALD     ObjectName:  Name=select /* Cursor TEST */ * from emp where ENAME= :v1       FullHashValue=a89535ce44458f11e572829735db05b6 Namespace=SQL AREA(00) Type=CURSOR(00) Identifier=903546294 OwnerIdn=83     Statistics:  InvalidationCount=0 ExecutionCount=3 LoadCount=4 ActiveLocks=0 TotalLockCount=3 TotalPinCount=1     Counters:  BrokenCount=1 RevocablePointer=1 KeepDependency=3 Version=0 BucketInUse=2 HandleInUse=2 HandleReferenceCount=0     Concurrency:  DependencyMutex=0x8a7ea880(0, 3, 0, 0) Mutex=0x8a7ea910(125, 91, 0, 6)     Flags=RON/PIN/TIM/PN0/DBN/[10012841]     WaitersLists:       Lock=0x8a7ea860[0x8a7ea860,0x8a7ea860]       Pin=0x8a7ea840[0x8a7ea840,0x8a7ea840]       LoadLock=0x8a7ea8b8[0x8a7ea8b8,0x8a7ea8b8]     Timestamp:  Current=07-19-2016 13:33:05     HandleReference:  Address=0x8a7ea9b0 Handle=(nil) Flags=[00]     LibraryObject:  Address=0x8abad0b0 HeapMask=0000-0001-0001-0000 Flags=EXS[0000] Flags2=[0000] PublicFlags=[0000]       ChildTable:  size='16'         Child:  id='0' Table=0x8abadf60 Reference=0x8abad9a0 Handle=0x8a7ea350         Child:  id='1' Table=0x8abadf60 Reference=0x8abadd38 Handle=0x8a7dad48         Child:  id='2' Table=0x8abadf60 Reference=0x8a96c2e8 Handle=0x8a660b20     NamespaceDump:       Parent Cursor:  sql_id=fawn2kwuxq1dq parent=0x8abad150 maxchild=3 plk=n ppn=n piflg=82 pflg=10008100 oct=03 psn=3 app(hash)=SQL*Plus(3669949024) act(hash)=(0) caller obj#=0 line#=0         CursorDiagnosticsNodes:           ChildNode:  ChildNumber=1 ID=40 reason=Bind mismatch(22) size=4x4 bind_position=0 original_oacflg=3 original_oacmxl=2000 upgradeable_new_oacmxl=32 ★           ChildNode:  ChildNumber=0 ID=40 reason=Bind mismatch(22) size=4x4 bind_position=0 original_oacflg=3 original_oacmxl=32 upgradeable_new_oacmxl=2000 ★

可以看到上面ChildNumber=1和ChildNumber=0產生的原應都是由於Bind mismatch(22)。

其他

和游標相關的視圖:

V$OPEN_CURSOR  V$SESSION_CURSOR_CACHE  V$SYSTEM_CURSOR_CACHE  V$SQL_CURSOR  V$SQL_SHARED_CURSOR

和游標相關的初始化參數:

(11.2.0.4)  SQL> show parameter cursorNAME                                 TYPE        VALUE  ------------------------------------ ----------- ------------------------------  cursor_bind_capture_destination      string      memory+disk  cursor_sharing                       string      EXACT  cursor_space_for_time                boolean     FALSE  open_cursors                         integer     300  session_cached_cursors               integer     50

版權聲明:本文為訂閱號TeacherWhat原創文章,轉載必須註明出處,作者保留一切相關權力!