ITPub博客

首页 > 数据库 > Oracle > [20261106]光标跟踪事件11.txt

[20261106]光标跟踪事件11.txt

原创 Oracle 作者:lfree 时间:2026-11-08 20:39:37 0 删除 编辑

[20261106]光标跟踪事件11.txt

--//做一个补充测试:
--//1.确定链接https://www.0xchris.dev/posts/2026-06-08-child-cursor-scan-mechanics--an-investigation/里面提到的参数
--//  _xds_max_child_cursors指总的子光标数量,还是指链接里面的数量。
--//2.测试存在哈希冲突与不冲突的情况(pdbname与cdbname通过计算的哈希值的最后1位),两种情况下是否存在性能差异.

1.环境:
SYS@book> @ ver2
==============================
PORT_STRING                   : x86_64/Linux 2.4.xx
VERSION                       : 21.0.0.0.0
BANNER                        : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL                   : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY                 : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID                        : 0
PL/SQL procedure successfully completed.

SYS@book> @ hidez _xds_max_child_cursors
SYS@book> @ pr
==============================
NUM                           : 3633
N_HEX                         :   E31
CON_ID                        : 0
NAME                          : _xds_max_child_cursors
DESCRIPTION                   : Maximum number of XDS user-specific child cursors
DEFAULT_VALUE                 : TRUE
SESSION_VALUE                 : 100
SYSTEM_VALUE                  : 100
ISSES_MODIFIABLE              : FALSE
ISSYS_MODIFIABLE              : IMMEDIATE
PL/SQL procedure successfully completed.

SYS@book> show pdbs
    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       MOUNTED
         3 BOOK01P                        READ WRITE NO
--//pdbname与cdbname通过计算的哈希值的最后1位(16进制)不同。

2.建立测试脚本以及测试环境:
--//分别在cdb$root,book02p下建立表t.
--//cdb$root下以sys用户建立如下表。
SYS@book> create table t as select rownum id ,cast('test' as varchar2(10)) name from dual ;
Table created.

SYS@book> alter table t modify ( id  not null );
Table altered.

SYS@book> create unique index i_t_id on t(id);
Index created.

--//pdb=book01p下以scott用户建立表以及索引过程略。

$ cat m15.txt
connect / as sysdba
--alter session set session_cached_cursors=0;
set verify off
alter session set optimizer_index_cost_adj = &&2;
declare
v_id number;
v_d date;
l_count PLS_INTEGER;
begin
    for i in 1 .. &&1 loop
        SELECT COUNT(NAME) INTO v_id FROM T WHERE ID = 1;
    end loop;
end ;
/

connect scott/book@book01p
--alter session set session_cached_cursors=0;
set verify off
alter session set optimizer_index_cost_adj = &&2;
declare
v_id number;
v_d date;
l_count PLS_INTEGER;
begin
    for i in 1 .. &&1 loop
        SELECT COUNT(NAME) INTO v_id FROM T WHERE ID = 1;
    end loop;
end ;
/
quit
--//sql_id=494nuxkcrxsz3.

$ cat m15a.txt
alter session set session_cached_cursors=0;
set verify off
alter session set optimizer_index_cost_adj = &&2;
declare
v_id number;
v_d date;
l_count PLS_INTEGER;
begin
    for i in 1 .. &&1 loop
        SELECT COUNT(NAME) INTO v_id FROM T WHERE ID = 1;
    end loop;
end ;
/

3.测试:

$ seq 64 | xargs -IQ sqlplus -s -l /nolog  @m15.txt 6 Q >/dev/null

--//这样相当于建立128个子光标,con_id相互交错。

$ time sqlplus  -s -l / as sysdba  @m15a.txt 2e5 64 > /dev/null
real    0m10.091s
user    0m0.227s
sys     0m0.011s

$ time sqlplus  -s -l / as sysdba  @m15a.txt 2e5 50 > /dev/null
real    0m6.448s
user    0m0.216s
sys     0m0.008s

--//有点意外,选择optimizer_index_cost_adj = 50的最快,在链表开头.
--//这个参数_xds_max_child_cursors是指总的子光标数量超过100,插入链表结尾,小于等于时插入链接开头。

--//关闭pdb数据库。
SYS@book> ALTER PLUGGABLE DATABASE book01p CLOSE IMMEDIATE;
Pluggable database altered.

$ time sqlplus  -s -l / as sysdba  @m15a.txt 2e5 64 > /dev/null
real    0m10.094s
user    0m0.228s
sys     0m0.012s

$ time sqlplus  -s -l / as sysdba  @m15a.txt 2e5 50 > /dev/null
real    0m6.432s
user    0m0.261s
sys     0m0.013s
--//可以发现关闭pdbname=book01p的数据库,@m15a.txt 2e5 64 的执行时间与前面的测试一样。因为pdbname与cdbname经过
--//kpdbNameHash函数计算最后1位(16进制)不同,它们分别链接不同的链表上。

3.继续:
--//修改pdbname=book02p,这样pdbname与cdbname通过计算的哈希值的最后1位(16进制)相同.过程略.
SYS@book> alter system flush shared_pool;
System altered.

--//修改m15.txt 脚本的连接串.
$ cat m15.txt
connect / as sysdba
--alter session set session_cached_cursors=0;
set verify off
alter session set optimizer_index_cost_adj = &&2;
declare
v_id number;
v_d date;
l_count PLS_INTEGER;
begin
    for i in 1 .. &&1 loop
        SELECT COUNT(NAME) INTO v_id FROM T WHERE ID = 1;
    end loop;
end ;
/

connect scott/book@127.0.0.1:1521/book02p
--alter session set session_cached_cursors=0;
set verify off
alter session set optimizer_index_cost_adj = &&2;
declare
v_id number;
v_d date;
l_count PLS_INTEGER;
begin
    for i in 1 .. &&1 loop
        SELECT COUNT(NAME) INTO v_id FROM T WHERE ID = 1;
    end loop;
end ;
/
quit

--//重复前面的测试:

$ time sqlplus  -s -l / as sysdba  @m15a.txt 2e5 64 > /dev/null
real    0m12.432s
user    0m0.198s
sys     0m0.012s

$ time sqlplus  -s -l / as sysdba  @m15a.txt 2e5 50 > /dev/null
real    0m6.779s
user    0m0.205s
sys     0m0.007s
--//存在冲突的情况下差别并不是非常明显,不过执行@m15a.txt 2e5 64比原来慢了2秒多一点。

--//关闭pdb数据库。
SYS@book> ALTER PLUGGABLE DATABASE book02p CLOSE IMMEDIATE;
Pluggable database altered.

$ time sqlplus  -s -l / as sysdba  @m15a.txt 2e5 64 > /dev/null
real    0m12.344s
user    0m0.208s
sys     0m0.014s
--//即使关闭pdb数据库。cdb下的密集执行@m15a.txt 2e5 64并没有变化。
SYS@book> @ m15a.txt 1 64
Session altered.
Session altered.
PL/SQL procedure successfully completed.


3231 oracle_3231_boo -> kkscsSearchChildList: 0x7f5e0afaa060, 0x7fff52c572f0, xsc=0x7f5e059a0100, flag=0x108, ...
3231 oracle_3231_boo    kkscsSearchChildList: Parent ready for search (kglkdadr=0x6d8bc8c8, kglhdpar=0x63894490)
3231 oracle_3231_boo -> kpdbNameHash: 0x7e71c94c, 0x8 CDB$ROOT
3231 oracle_3231_boo -> kpdbNameHash: 0x7e71c94c, 0x8 CDB$ROOT
3231 oracle_3231_boo    kpdbNameHash: pdb_name is CDB$ROOT (hsh=0x1eee6512)
3231 oracle_3231_boo <- kpdbNameHash: 0x1eee6512 (518939922)
3231 oracle_3231_boo -> kkshGetNextChild: hsh=0x1eee6512, ht=0x6fc27410, cur_hbk=0x7fff52c56668, cs=0x7fff52c56670, ...
3231 oracle_3231_boo    kkshGetNextChild: *ht=0x6fc27430 (pdbuid=0)
3231 oracle_3231_boo    kkshGetNextChild: *cur_hbk=0x6fc27490
3231 oracle_3231_boo    kkshGetNextChild: cshsl=0x6da91610[0x6fc27490,0x6da90eb0]
3231 oracle_3231_boo    kkshGetNextChild: cshbk=0x6da90eb0
3231 oracle_3231_boo    kkshGetNextChild: prev: cs=0, cno=0
3231 oracle_3231_boo    kkshGetNextChild: curr: cs=0x6da915c0, cno=99
3231 oracle_3231_boo    kkshGetNextChild: next: cs=0x6da90e60, cno=98
3231 oracle_3231_boo <- kkshGetNextChild: ret=0x0 (0)

3231 oracle_3231_boo -> kkshGetNextChild: hsh=0x1eee6512, ht=0x6fc27410, cur_hbk=0x7fff52c56668, cs=0x7fff52c56670, ...
3231 oracle_3231_boo    kkshGetNextChild: *ht=0x6fc27430 (pdbuid=1)
3231 oracle_3231_boo    kkshGetNextChild: *cur_hbk=0x6fc27490
3231 oracle_3231_boo    kkshGetNextChild: cshsl=0x6da90eb0[0x6da91610,0x6ddc5f18]
3231 oracle_3231_boo    kkshGetNextChild: cshbk=0x6ddc5f18
3231 oracle_3231_boo    kkshGetNextChild: prev: cs=0x6da915c0, cno=99
3231 oracle_3231_boo    kkshGetNextChild: curr: cs=0x6da90e60, cno=98
3231 oracle_3231_boo    kkshGetNextChild: next: cs=0x6ddc5ec8, cno=97
3231 oracle_3231_boo <- kkshGetNextChild: ret=0x0 (0)

3231 oracle_3231_boo -> kkscsCheckCursor: 0x7f5e0afaa060, 0x7fff52c572f0, xsc=0x7f5e059a0100, 0x108, 0x0, 0x7fff52c57270, ...
3231 oracle_3231_boo    kkscsCheckCursor: next child is #98 (cs=0x6da90e60, pdbuid=1)
3231 oracle_3231_boo -> kkscsPruneChild: 0x7f5e0afaa060, xsc=0x7f5e059a0100, cs=0x6da90e60, flg=0x7fff52c572f0
3231 oracle_3231_boo    kkscsPruneChild: Child was pruned
3231 oracle_3231_boo <- kkscsPruneChild: ret=0x1 (1)
3231 oracle_3231_boo <- kkscsCheckCursor: ret=0x0 (0)

3231 oracle_3231_boo -> kkshGetNextChild: hsh=0x1eee6512, ht=0x6fc27410, cur_hbk=0x7fff52c56668, cs=0x7fff52c56670, ...
3231 oracle_3231_boo    kkshGetNextChild: *ht=0x6fc27430 (pdbuid=0)
3231 oracle_3231_boo    kkshGetNextChild: *cur_hbk=0x6fc27490
3231 oracle_3231_boo    kkshGetNextChild: cshsl=0x6ddc5f18[0x6da90eb0,0x6ddc57b8]
3231 oracle_3231_boo    kkshGetNextChild: cshbk=0x6ddc57b8
3231 oracle_3231_boo    kkshGetNextChild: prev: cs=0x6da90e60, cno=98
3231 oracle_3231_boo    kkshGetNextChild: curr: cs=0x6ddc5ec8, cno=97
3231 oracle_3231_boo    kkshGetNextChild: next: cs=0x6ddc5768, cno=96
3231 oracle_3231_boo <- kkshGetNextChild: ret=0x0 (0)
...
3231 oracle_3231_boo -> kkshGetNextChild: hsh=0x1eee6512, ht=0x6fc27410, cur_hbk=0x7fff52c56668, cs=0x7fff52c56670, ...
3231 oracle_3231_boo    kkshGetNextChild: *ht=0x6fc27430 (pdbuid=1)
3231 oracle_3231_boo    kkshGetNextChild: *cur_hbk=0x6fc27490
3231 oracle_3231_boo    kkshGetNextChild: cshsl=0x6b310568[0x6b7627b8,0x6b310cc8]
3231 oracle_3231_boo    kkshGetNextChild: cshbk=0x6b310cc8
3231 oracle_3231_boo    kkshGetNextChild: prev: cs=0x6b762768, cno=125
3231 oracle_3231_boo    kkshGetNextChild: curr: cs=0x6b310518, cno=126
3231 oracle_3231_boo    kkshGetNextChild: next: cs=0x6b310c78, cno=127
3231 oracle_3231_boo <- kkshGetNextChild: ret=0x0 (0)

3231 oracle_3231_boo -> kkscsCheckCursor: 0x7f5e0afaa060, 0x7fff52c572f0, xsc=0x7f5e059a0100, 0x108, 0x0, 0x7fff52c57270, ...
3231 oracle_3231_boo    kkscsCheckCursor: next child is #126 (cs=0x6b310518, pdbuid=1)
3231 oracle_3231_boo <- kkscsCheckCursor: ret=0x71212d20 (1897999648)

3231 oracle_3231_boo    kkscsSearchChildList: complete: inspected 64 children in 1303428 ns (1303 us)
3231 oracle_3231_boo <- kkscsSearchChildList: ret=0x71212d20 (1897999648)

--//虽然pdbname数据库已经关闭,但是对应的子光标还在,堆0,堆6已经不存在了,依旧探查导致执行时间并没有缩小。

4.补充:
--//顺便记录自己测试时打开bpftrace的脚本监测遇到的情况:

# ./kkscsSearchChildList.bt 3231 verbose
Attached 14 probes
Tracing... Hit ^C to stop.
^C
--//进程号3231已经不存在了。

$ time sqlplus  -s -l / as sysdba  @m15a.txt 2e5 64 > /dev/null
real    1m54.469s
user    0m0.202s
sys     0m0.010s

--//执行时间明显增加。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-3188149/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    4017
  • 访问量
    7991556