欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

[20190507]sga_target=0注意修改_kghdsidx_count设置.txt

程序员文章站 2022-12-05 14:55:28
[20190507]sga_target=0注意修改_kghdsidx_count设置.txt--//昨天遇到一例视图定义太复杂导致长时间分析sql语句出现library cache lock等待事件的情况.--//加上大量使用非绑定变量语句,导致硬解析增加,导致问题更加严重.--//顺便解析当时同 ......

[20190507]sga_target=0注意修改_kghdsidx_count设置.txt

--//昨天遇到一例视图定义太复杂导致长时间分析sql语句出现library cache lock等待事件的情况.
--//加上大量使用非绑定变量语句,导致硬解析增加,导致问题更加严重.

--//顺便解析当时同事发现仅仅1个cpu特别忙.实际上因为仅仅1个shared pool latch在工作.

1.环境:
> @ ver1
port_string        version        banner
------------------ -------------- ----------------------------------------------------------------
ibmpc/win_nt-8.1.0 10.2.0.3.0     oracle database 10g enterprise edition release 10.2.0.3.0 - prod
--//注32位版本.

2.解析:

select addr
        ,latch#
        ,child#
        ,level#
        ,name
        ,gets
        ,sleeps
        ,immediate_gets
        ,immediate_misses
        ,spin_gets
    from v$latch_children
   where name like 'shared pool'
order by addr;

addr         latch#     child#     level# name              gets     sleeps immediate_gets immediate_misses  spin_gets
-------- ---------- ---------- ---------- ----------- ---------- ---------- -------------- ---------------- ----------
05aa3858        213          1          7 shared pool   25235287        182              0                0       7384
05aa38c0        213          2          7 shared pool        151          0              0                0          0
05aa3928        213          3          7 shared pool        151          0              0                0          0
05aa3990        213          4          7 shared pool        151          0              0                0          0
05aa39f8        213          5          7 shared pool        151          0              0                0          0
05aa3a60        213          6          7 shared pool        151          0              0                0          0
05aa3ac8        213          7          7 shared pool        151          0              0                0          0
7 rows selected.
--//仅仅1个shared pool latch在使用.

> show parameter sga_
name          type        value
------------- ----------- ------
sga_max_size  big integer 1200m
sga_target    big integer 1200m

> @ hide _kghdsidx_count
name            description        default_value          session_value          system_value
--------------- ------------------ ---------------------- ---------------------- ----------------------
_kghdsidx_count max kghdsidx count true                   1                      1

> @ hide _enable_shared_pool_durations
name                          description                            default_value session_value system_value
----------------------------- -------------------------------------- ------------- ------------- ------------
_enable_shared_pool_durations temporary to disable/enable kgh policy true          true          true

> show parameter cpu_count
name      type    value
--------- ------- ------
cpu_count integer 16
--//注:在任务管理器看到32个cpu.不过我发现图中下面一排16个cpu好像没有负载.

--//主要问题是参数_kghdsidx_count=1.仅仅1个subpool.看来这个版本按照每个子缓冲池至少为512mb设计的.
--//参数_kghdsidx_count大小由cpu数量以及共享池大小决定的.最大不过7个.
--//我仅仅知道的原则:
--//共享子缓冲池的分配的算法很简单:
--//·每个子缓冲池必须满足一定的内存约束;
--//·每4颗cpu可以分配一个子缓冲池,最多7个。

--//本来oracle这样做为了减少shared pool,但是带来另外的问题,如果每个子池太小,反而出现ora-04031错误.于是oracle限制每个子池
--//的大小,你可以发现一些blog提到减少参数_kghdsidx_count大小,限制每个子池避免出现子池太小的情况.

--//在oracle 9i中,每个subpool至少128mb,在oracle 10g中,每个子缓冲池至少为256mb,在oracle 11g中,每个子缓冲池至少为512mb.
--//oracle 10g会将单个缓冲池分割再细分4个子分区进行管理(这可能是因为通常4颗cpu才分配一个subpool),
--//分别是"instance", "session", "cursor", and "execution".

--//对方安装32位系统,不能设置很大sga,受限共享内存大小600m上下,这样仅仅1个shared pool latch.
--//这样在大量硬解析的情况下,特别在分析sql语句很长时间的情况下仅仅1个shared pool latch自然很忙.
--//也就是同事看到的情况,仅仅1个cpu在忙...而且sql语句中的视图关联的表太多,导致1条sql语句消耗共享池很大,我执行前面的语句,查看
--//v$sqlarea的sharable_mem达到512k.这样大量非绑定变量语句导致许多对象退出又再进入共享池.

--//这就好比一个宾馆的前台仅仅1名接待人员一样,客户入住登记少没有问题,一旦大量客户登记入住,1个人自然忙不过来,
--//而其他人根本插不上手.有时候非常像现实工作的场景,1个忙的要死,别人根本插不上手,只能在那干等^_^.

3.突然想起我以前1个测试:
--//[20190104]sga_target 的设置和ora-04031错误.txt => http://blog.itpub.net/267265/viewspace-2305567/
--//发现一个问题,就是设置sga_target=0,如果大量语句不使用绑定变量可能存在问题.参数_kghdsidx_count=1,仅仅1个shared pool latch.
--//这样情况应该适当增加_kghdsidx_count,通过测试说明问题:

$ export oracle_sid=xxxx
$ cat initxxxx.ora
db_name=xxxx
instance_name=xxxx
sga_target=0
sga_max_size=20g
--//设置sga_target=0.

sys@xxxx> startup nomount
oracle instance started.
total system global area 2.1379e+10 bytes
fixed size                  2262656 bytes
variable size            2.1206e+10 bytes
database buffers          134217728 bytes
redo buffers               36073472 bytes

select addr
        ,latch#
        ,child#
        ,level#
        ,name
        ,gets
        ,sleeps
        ,immediate_gets
        ,immediate_misses
        ,spin_gets
    from v$latch_children
   where name like 'shared pool'
order by addr;

addr                 latch#     child#     level# name        gets     sleeps immediate_gets immediate_misses  spin_gets
---------------- ---------- ---------- ---------- ----------- ---- ---------- -------------- ---------------- ----------
000000006010f288        336          1          7 shared pool 1397          0              0                0          5
000000006010f328        336          2          7 shared pool    0          0              0                0          0
000000006010f3c8        336          3          7 shared pool    0          0              0                0          0
000000006010f468        336          4          7 shared pool    0          0              0                0          0
000000006010f508        336          5          7 shared pool    0          0              0                0          0
000000006010f5a8        336          6          7 shared pool    0          0              0                0          0
000000006010f648        336          7          7 shared pool    0          0              0                0          0
7 rows selected.

sys@xxxx> @ hide _kghdsidx_count
old  10:  and lower(a.ksppinm) like lower('%&1%')
new  10:  and lower(a.ksppinm) like lower('%_kghdsidx_count%')
name            description        default_value session_value system_value
--------------- ------------------ ------------- ------------- ------------
_kghdsidx_count max kghdsidx count true          1             1

sys@xxxx> @ hide _enable_shared_pool_durations
old  10:  and lower(a.ksppinm) like lower('%&1%')
new  10:  and lower(a.ksppinm) like lower('%_enable_shared_pool_durations%')
name                          description                            default_value session_value system_value
----------------------------- -------------------------------------- ------------- ------------- ------------
_enable_shared_pool_durations temporary to disable/enable kgh policy true          false         false

--//注意_enable_shared_pool_durations参数,在sga_target=0的情况下,_enable_shared_pool_durations的缺省值等于false(实际上设
--//置为true也无效,看后面测试)
--//也就是仅仅1个subpool,下面仅仅一个子子池.

sys@xxxx> @ sgastatx.sql  'free memory'
-- all allocations:
subpool                             bytes         mb
------------------------------ ---------- ----------
shared pool (0 - unused):        67108864         64
shared pool (1):                268435456        256
shared pool (total):            335544320        320

-- allocations matching "free memory":
old  15:     and lower(ksmssnam) like lower('%&1%')
new  15:     and lower(ksmssnam) like lower('%free memory%')
subpool                        name                 sum(bytes)         mb
------------------------------ -------------------- ---------- ----------
shared pool (0 - unused):      free memory            67108864         64
shared pool (1):               free memory            30813880      29.39

--//仅仅1个子池.共享内存不足的情况下会从shared pool (0 - unused)分过来.

--//另外注意1个问题,有一些文章提示查询x$kghlu可以查询这些子缓冲池的分配,我的测试不行,当然我现在sga_target=0的情况下不存
--//在子子池的情况.
--//通过一个内部表x$kghlu([k]ernel [g]eneric memory [h]eap manager state of [l]r[u] of unpinned recreatable chunks)可以
--//查询这些子缓冲池的分配: (我的测试不行!!)

sys@xxxx> select * from x$kghlu;
addr                   indx    inst_id   kghluidx   kghludur kghlushrpool   kghlufsh   kghluops   kghlurcr   kghlutrn   kghlumxa   kghlumes   kghlumer   kghlurcn   kghlurmi   kghlurmz   kghlurmx   kghlunfu   kghlunfs
---------------- ---------- ---------- ---------- ---------- ------------ ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
00007f6d32e5eff0          0          1          1          0            1          0         64          3         43 2147483647          0          0          0          0          0          0          0          0

--//只能通过heapdump转储获取这方面信息.
sys@xxxx> alter session set events 'immediate trace name heapdump level 2';
session altered.

$ grep 'sga heap' /u01/app/oracle/diag/rdbms/xxxx/xxxx/trace/xxxx_ora_43866.trc
heap dump heap name="sga heap"  desc=0x60001190
heap dump heap name="sga heap(1,0)"  desc=0x6005c318

--//可以看出问题.仅仅1个子池,不细分子子池.也就是在sga_target=0的情况下,可能需要手工设置_kghdsidx_count的大小.
--//不然可能出现shared pool latch的争用,特别在应用没有绑定变量的情况下.

--//我个人建议sga_target=0的情况下手工设置shared_pool_size,db_cache_size.
--//或者sga_target<>0的情况下,也设置shared_pool_size,db_cache_size作为最小值,避免内存在这些组件中变换.

--//修改*._kghdsidx_count=3
$ cat initxxxx.ora
db_name=xxxx
instance_name=xxxx
#sga_target=20g
sga_target=0
sga_max_size=20g
#pre_page_sga=true
*._kghdsidx_count=3

sys@xxxx> startup nomount
ora-04031: unable to allocate 320032 bytes of shared memory ("shared pool","unknown object","kgsk scheduler","kgsk chg class latches")
--//shared_pool_size太小.仅仅320m.

--//测试增加*._kghdsidx_count=3,*.shared_pool_size=1600m,*._enable_shared_pool_durations=true的情况:
$ cat initxxxx.ora
db_name=xxxx
instance_name=xxxx
sga_target=0g
#sga_target=20g
sga_max_size=20g
#pre_page_sga=true
*._kghdsidx_count=3
*.shared_pool_size=1600m
*._enable_shared_pool_durations=true
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

sys@xxxx> startup nomount
oracle instance started.

total system global area 2.1379e+10 bytes
fixed size                  2262656 bytes
variable size            2.1206e+10 bytes
database buffers          134217728 bytes
redo buffers               36073472 by

sys@xxxx> @ hide _kghdsidx_count
old  10:  and lower(a.ksppinm) like lower('%&1%')
new  10:  and lower(a.ksppinm) like lower('%_kghdsidx_count%')
name            description        default_value session_value system_value
--------------- ------------------ ------------- ------------- ------------
_kghdsidx_count max kghdsidx count false         3             3

sys@xxxx> @ hide _enable_shared_pool_durations
old  10:  and lower(a.ksppinm) like lower('%&1%')
new  10:  and lower(a.ksppinm) like lower('%_enable_shared_pool_durations%')
name                                     description                            default_value session_value system_value
---------------------------------------- -------------------------------------- ------------- ------------- ------------
_enable_shared_pool_durations            temporary to disable/enable kgh policy false         true          true

sys@xxxx> select * from x$kghlu;
addr                   indx    inst_id   kghluidx   kghludur kghlushrpool   kghlufsh   kghluops   kghlurcr   kghlutrn   kghlumxa   kghlumes   kghlumer   kghlurcn   kghlurmi   kghlurmz   kghlurmx   kghlunfu   kghlunfs
---------------- ---------- ---------- ---------- ---------- ------------ ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
00007fc432a52f70          0          1          3          0            1          0         20          0         14 2147483647          0          0          0          0          0          0          0          0
00007fc432a54640          1          1          2          0            1          0          9          0          7 2147483647          0          0          0          0          0          0          0          0
00007fc432a53ff0          2          1          1          0            1          0         14          0         10 2147483647          0          0          0          0          0          0          0          0
--//仅仅3个子池.看不出子子池.

sys@xxxx> alter session set events 'immediate trace name heapdump level 2';
session altered.

$ grep 'sga heap' /u01/app/oracle/diag/rdbms/xxxx/xxxx/trace/xxxx_ora_43949.trc
heap dump heap name="sga heap"  desc=0x60001190
heap dump heap name="sga heap(1,0)"  desc=0x6005c318
heap dump heap name="sga heap(2,0)"  desc=0x60065be0
heap dump heap name="sga heap(3,0)"  desc=0x6006f4a8
--//可以发现设置即使_enable_shared_pool_durations=true,在sga_target=0g的情况下也不会出现子子池的情况.

sys@xxxx> @ sgastatx.sql  'free memory'

-- all allocations:
subpool                             bytes         mb
------------------------------ ---------- ----------
shared pool (0 - unused):      1275068416       1216
shared pool (1):                134217728        128
shared pool (2):                134217728        128
shared pool (3):                134217728        128
shared pool (total):           1677721600       1600

-- allocations matching "free memory":
old  15:     and lower(ksmssnam) like lower('%&1%')
new  15:     and lower(ksmssnam) like lower('%free memory%')
subpool                        name                                     sum(bytes)         mb
------------------------------ ---------------------------------------- ---------- ----------
shared pool (0 - unused):      free memory                              1275068416       1216
shared pool (1):               free memory                                48797608      46.54
shared pool (2):               free memory                                34835672      33.22
shared pool (3):               free memory                                48306064      46.07

select addr
        ,latch#
        ,child#
        ,level#
        ,name
        ,gets
        ,sleeps
        ,immediate_gets
        ,immediate_misses
        ,spin_gets
    from v$latch_children
   where name like 'shared pool'
order by addr;

addr                 latch#     child#     level# name        gets     sleeps immediate_gets immediate_misses  spin_gets
---------------- ---------- ---------- ---------- ----------- ---- ---------- -------------- ---------------- ----------
000000006010f288        336          1          7 shared pool  732          0              1                0          0
000000006010f328        336          2          7 shared pool  673          0              1                0          0
000000006010f3c8        336          3          7 shared pool  903          0              1                0          1
000000006010f468        336          4          7 shared pool    1          0              0                0          0
000000006010f508        336          5          7 shared pool    1          0              0                0          0
000000006010f5a8        336          6          7 shared pool    1          0              0                0          0
000000006010f648        336          7          7 shared pool    1          0              0                0          0
7 rows selected.

--//总之,如果手工管理内存,设置sga_target=0g的情况下,适当设置_kghdsidx_count,shared_pool_size,db_cache_size值.

4.最后测试sga_target<>0的情况:
$ grep -v "^#" initxxxx.ora
db_name=xxxx
instance_name=xxxx
sga_target=20g
sga_max_size=20g

sys@xxxx> @ hide _kghdsidx_count
old  10:  and lower(a.ksppinm) like lower('%&1%')
new  10:  and lower(a.ksppinm) like lower('%_kghdsidx_count%')
name                                     description                             default_value session_value system_value
---------------------------------------- --------------------------------------- ------------- ------------- ------------
_kghdsidx_count                          max kghdsidx count                      true          6             6

sys@xxxx> @ hide _enable_shared_pool_durations
old  10:  and lower(a.ksppinm) like lower('%&1%')
new  10:  and lower(a.ksppinm) like lower('%_enable_shared_pool_durations%')
name                                     description                             default_value session_value system_value
---------------------------------------- --------------------------------------- ------------- ------------- ------------
_enable_shared_pool_durations            temporary to disable/enable kgh policy  true          true          true

sys@xxxx> @ sgastatx.sql  'free memory'
-- all allocations:
subpool                             bytes         mb
------------------------------ ---------- ----------
shared pool (0 - unused):       469762048        448
shared pool (1):                268435456        256
shared pool (2):                335544320        320
shared pool (3):                335544320        320
shared pool (4):                335544320        320
shared pool (5):                268435456        256
shared pool (6):                335544320        320
shared pool (total):           2348810240       2240

8 rows selected.

-- allocations matching "free memory":
old  15:     and lower(ksmssnam) like lower('%&1%')
new  15:     and lower(ksmssnam) like lower('%free memory%')
subpool                        name                 sum(bytes)         mb
------------------------------ -------------------- ---------- ----------
shared pool (0 - unused):      free memory           469762048        448
shared pool (1):               free memory           207961376     198.33
shared pool (2):               free memory           224686568     214.28
shared pool (3):               free memory           270474992     257.95
shared pool (4):               free memory           234357448      223.5
shared pool (5):               free memory           206367112     196.81
shared pool (6):               free memory           239940912     228.83
7 rows selected.

sys@xxxx> select * from x$kghlu;
                                              sub       ssub                 flushed   lru list  recurrent  transient                                    reserved   reserved   reserved    reserved free unpin  last frunp
addr                   indx    inst_id       pool       pool kghlushrpool     chunks operations     chunks     chunks   kghlumxa   kghlumes   kghlumer      scans     misses  miss size miss max sz  unsuccess unsucc size
---------------- ---------- ---------- ---------- ---------- ------------ ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------- ---------- -----------
00007f78519f2e48          0          1          6          0            1          0         17          0         17 2147483647          0          0          0          0          0           0          0           0
00007f78519f27f8          1          1          5          0            1          0         27          0         17 2147483647          0          0          0          0          0           0          0           0
00007f78519f3e60          2          1          4          0            1          0         23          0         19 2147483647          0          0          0          0          0           0          0           0
00007f78519f3810          3          1          3          0            1          0         40          0         16 2147483647          0          0          0          0          0           0          0           0
00007f78519f4ee0          4          1          2          0            1          0         34          0         22 2147483647          0          0          0          0          0           0          0           0
00007f78519f4890          5          1          1          0            1          0         26          0         16 2147483647          0          0          0          0          0           0          0           0
6 rows selected.
--// 看不出子子池的分配情况.

sys@xxxx> alter session set events 'immediate trace name heapdump level 2';
session altered.

$ egrep "sga heap|total heap size" /u01/app/oracle/diag/rdbms/xxxx/xxxx/trace/xxxx_ora_44083.trc
heap dump heap name="sga heap"  desc=0x60001190
heap dump heap name="sga heap(1,0)"  desc=0x6005c318
total heap size    = 67108776
heap dump heap name="sga heap(1,1)"  desc=0x6005db70
total heap size    = 67108776
heap dump heap name="sga heap(1,2)"  desc=0x6005f3c8
total heap size    = 67108776
heap dump heap name="sga heap(1,3)"  desc=0x60060c20
total heap size    = 67108776
--// 67108776*4/1024/1024 = 255.99966430664062500000 ,接近256m.
heap dump heap name="sga heap(2,0)"  desc=0x60065be0
total heap size    =134217552
heap dump heap name="sga heap(2,1)"  desc=0x60067438
total heap size    = 67108776
heap dump heap name="sga heap(2,2)"  desc=0x60068c90
total heap size    = 67108776
heap dump heap name="sga heap(2,3)"  desc=0x6006a4e8
total heap size    = 67108776
--//(134217552+67108776+67108776+67108776)/1024/1024 = 319.99958038330078125000,接近320m.
heap dump heap name="sga heap(3,0)"  desc=0x6006f4a8
total heap size    =134217552
heap dump heap name="sga heap(3,1)"  desc=0x60070d00
total heap size    = 67108776
heap dump heap name="sga heap(3,2)"  desc=0x60072558
total heap size    = 67108776
heap dump heap name="sga heap(3,3)"  desc=0x60073db0
total heap size    = 67108776
heap dump heap name="sga heap(4,0)"  desc=0x60078d70
total heap size    =134217552
heap dump heap name="sga heap(4,1)"  desc=0x6007a5c8
total heap size    = 67108776
heap dump heap name="sga heap(4,2)"  desc=0x6007be20
total heap size    = 67108776
heap dump heap name="sga heap(4,3)"  desc=0x6007d678
total heap size    = 67108776
heap dump heap name="sga heap(5,0)"  desc=0x60082638
total heap size    = 67108776
heap dump heap name="sga heap(5,1)"  desc=0x60083e90
total heap size    = 67108776
heap dump heap name="sga heap(5,2)"  desc=0x600856e8
total heap size    = 67108776
heap dump heap name="sga heap(5,3)"  desc=0x60086f40
total heap size    = 67108776
heap dump heap name="sga heap(6,0)"  desc=0x6008bf00
total heap size    =134217552
heap dump heap name="sga heap(6,1)"  desc=0x6008d758
total heap size    = 67108776
heap dump heap name="sga heap(6,2)"  desc=0x6008efb0
total heap size    = 67108776
heap dump heap name="sga heap(6,3)"  desc=0x60090808
total heap size    = 67108776
--//这样可以看到每个子池有几个子子池,并且每个的大小.

总结:
--//总之注意,如果手工管理内存,设置sga_target=0g的情况下,适当设置_kghdsidx_count,shared_pool_size,db_cache_size值.避免
--//shared pool latch仅仅1个的情况.
--//我个性喜欢手工管理内存设置sga_target=sga_max_size,设置shared_pool_size,db_cache_size基本不会转换.

--//附上sgastatx.sql脚本.
$ cat sgastatx.sql
--------------------------------------------------------------------------------
--
-- file name:   sgastatx
-- purpose:     show shared pool stats by sub-pool from x$ksmss
--
-- author:      tanel poder
-- copyright:   (c) http://www.tanelpoder.com
--
-- usage:       @sgastatx <statistic name>
--              @sgastatx "free memory"
--              @sgastatx cursor
--
-- other:       the other script for querying v$sgastat is called sgastat.sql
--
--
--
--------------------------------------------------------------------------------

col sgastatx_subpool head subpool for a30

prompt
prompt -- all allocations:

select
    'shared pool ('||nvl(decode(to_char(ksmdsidx),'0','0 - unused',ksmdsidx), 'total')||'):'  sgastatx_subpool
  , sum(ksmsslen) bytes
  , round(sum(ksmsslen)/1048576,2) mb
from
    x$ksmss
where
    ksmsslen > 0
--and ksmdsidx > 0
group by rollup
   ( ksmdsidx )
order by
    sgastatx_subpool asc
/

break on sgastatx_subpool skip 1
prompt -- allocations matching "&1":

select
    subpool sgastatx_subpool
  , name
  , sum(bytes)
  , round(sum(bytes)/1048576,2) mb
from (
    select
        'shared pool ('||decode(to_char(ksmdsidx),'0','0 - unused',ksmdsidx)||'):'      subpool
      , ksmssnam      name
      , ksmsslen      bytes
    from
        x$ksmss
    where
        ksmsslen > 0
    and lower(ksmssnam) like lower('%&1%')
)
group by
    subpool
  , name
order by
    subpool    asc
  , sum(bytes) desc
/

break on sgastatx_subpool dup