このブログを検索

ラベル キャッシュ の投稿を表示しています。 すべての投稿を表示
ラベル キャッシュ の投稿を表示しています。 すべての投稿を表示

2011年7月1日金曜日

共有プールをクリアする

共有プールをインスタンス単位でクリアすることができます。
ただし、キャッシュヒット率が激減し、一時的にパフォーマンスダウンが予想されるのでタイミングに注意。
RACの場合は、一度に全ノードクリアするのではなく、クリア後ある程度キャッシュがたまってきてからの方がベターです。

共有プールのサイズが大きすぎるとエージアウトした際のロック(ラッチ)の時間が長くなり、DBサーバの応答が遅くなります。
この例のようにsql area(SQL数)が多いことが根本原因なのでアプリを直すべきですが、障害対応として紹介します。
(とはいえ、リスクの方が大きいので僕はめったにクリアしません)
共有プールのラッチは、CPU使用率もI/O負荷も上昇しないので検知しづらく潜在リスクは非常に高いと思っています。

まず、現状の共有プールの状況を確認します。
set pages 10000
set lines 120
set time on
col name for a40
select * from (
 select name, bytes from v$sgastat
 where pool = 'shared pool'
 order by bytes desc
) where rownum <= 20;
例えば、次のようにsql areaが3.5GBほどあるインスタンスをクリアすることにします。
NAME                                          BYTES
---------------------------------------- ----------
sql area                                 3690078544
free memory                               957169136
PCursor                                   637214224
CCursor                                   623044928
library cache                             499544096
sql area:PLSQL                            268971096
gcs resources                             233915744
gcs shadows                               140065792
kglsim object batch                       137342016
db_block_hash_buckets                      94371840
kglsim heap                                82446336
Cursor Stats                               64968688
ASH buffers                                30408704
transaction                                19464072
ges enqueues                               18813632
trace buffer                               16891904
ges big msg buffers                        15936168
KCL name table                             12582912
event statistics per sess                  12296000
FileOpenBlock                              11575096
共有プールのクリアはインスタンスごとにalter systemします。
$ sqlplus sys as sysdba
SQL> alter system flush shared_pool;
次のようにsql areaが消え、free memoryが増加します。
NAME                                          BYTES
---------------------------------------- ----------
free memory                              6376176928
gcs resources                             233915744
kglsim object batch                       191237088
library cache                             152614448
gcs shadows                               140065792
kglsim heap                               108622080
db_block_hash_buckets                      94371840
Cursor Stats                               85479368
sql area                                   44653328
ASH buffers                                30408704
transaction                                19490568
ges enqueues                               18813632
trace buffer                               16891904
ges big msg buffers                        15936168
KCL name table                             12582912
event statistics per sess                  12296000
FileOpenBlock                              11575096
CCursor                                    11276472
ges resource                               11221136

2011年4月3日日曜日

シーケンスキャッシュのサイズを変更する

STATSPACKや待機しているセッションを調べるでenq: SQ - contentionが目立つ場合、シーケンスキャッシュが不足している場合があります。

担当案件にてユーザプロセスが急増したことがありますが、その際、ユーザプロセスのIDキャッシュサイズが小さいためにenq: SQ - contentionが多発しました。
(そもそもの原因はアプリケーションでしたが、急場しのぎのために設定変更しました)

今回の例では、ユーザプロセスのID発行に関わるキャッシュのサイズを大きくします。
ただし、これは諸刃の剣なので十分注意してください。
理由は、キャッシュサイズが大きくなるということは、キャッシュを使いきってリフレッシュする時のロック時間が長くなるということです。

まず、現在の設定値CACHE_SIZEを確認します。
set pages 10000
set lines 120
col SEQUENCE_OWNER for a15
col SEQUENCE_NAME for a15
select * from dba_sequences where sequence_name in ('AUDSES$','IDGEN1$');

SEQUENCE_OWNER  SEQUENCE_NAME    MIN_VALUE  MAX_VALUE INCREMENT_BY CYC ORD CACHE_SIZE LAST_NUMBER
--------------- --------------- ---------- ---------- ------------ --- --- ---------- -----------
SYS             IDGEN1$                  1 1.0000E+27           50 N   N         2000  3.9574E+10
SYS             AUDSES$                  1 2000000000            1 Y   N         2000  1448207982
次のように値を10倍にします。
SQL> ALTER SEQUENCE SYS.AUDSES$ CACHE 20000;
SQL> ALTER SEQUENCE SYS.IDGEN1$ CACHE 20000;

2011年2月25日金曜日

似て非なるSQLを探す

Oracleは意識的にプレースホルダを使わないと、共有プールのSQL領域を食いつぶしてSQLのキャッシュ率が悪くなります。
SGAを増やす手段もありますが、数ギガ規模にまで増やすとキャッシュの吐き出し(エージアウト)をしている間、SQLキャッシュ全体をロック(ラッチ)されて処理を何も受け付けなくなります。
そこで、リテラル値が含まれているSQLを定期的に探すといいでしょう。
この例では、SQL文を前方一致100文字だけで比較していますが、アプリケーションによっては50~150文字など調整するといいかと思います。
CNTが多いものを最優先に対応するといいでしょう。
select "Stmt",cnt,"Mem/count","Exec" from (
  SELECT row_number() over (order by count(*) desc) as rn,
      substr(sql_text,1,100) "Stmt", count(*) cnt,
      sum(sharable_mem)/count(*)    "Mem/count",
      sum(executions)      "Exec"
  FROM v$sqlstats
  GROUP BY substr(sql_text,1,100)
  HAVING count(*) > 10
) where rn<=100;
実行例は次の通り。
Stmt                                                                                    CNT  Mem/count       Exec
-------------------------------------------------------------------------------- ---------- ---------- ----------
    SELECT     msfr.free_rankavg_id,     msfr.free_rankavg_nm,     msfr.event_id       4308 36555.0975       4312
,     msfr.team_flg,

select substrb(dump(val,16,0,32),1,120) ep, cnt from (select /*+ no_parallel(t)         308 12900.4416       3365
no_parallel_index(t)

select TABLE_NAME,TABLESPACE_NAME,CLUSTER_NAME,PCT_FREE,PCT_USED,INI_TRANS,MAX_T        170 44840.8471        380
RANS,INITIAL_EXTENT/

select column_name,data_type,data_length,nullable,data_default,data_precision,da        127 48466.2047        310
ta_scale from user_t

 select /*+ no_parallel(t) no_parallel_index(t) dbms_stats cursor_sharing_exact         104 11319.4615       1182
use_weak_name_resl d

SELECT /*+ cursor_sharing_exact */ count(*) FROM  "SYS"."KUPC$DATAPUMP_QUETAB" T        100      12426          0
AB, SYS.DUAL WHERE t

select /*+ no_parallel(t) no_parallel_index(t) dbms_stats cursor_sharing_exact u         93 51273.5484       1069
se_weak_name_resl dy

SELECT /* OPT_DYN_SAMP */ /*+ ALL_ROWS IGNORE_WHERE_CLAUSE NO_PARALLEL(SAMPLESUB         91 17089.3187       1338
) opt_param('paralle

    SELECT     tau.user_id,     tau.aplus_level_no,     taf.appr_stat_cd    FROM         63 19573.8413        252
     aplus001iuser.t

select * from ( select rank() over ( order by last_access_dt desc , rownum) AS r         49 32231.8367        161
n, user_id,uid_2,car

insert into TBL_ObjectiveEventLog (regist_dt,event_id,objective_id,carrier_id,us         34 10804.2353        397
er_id,event_clear_co

SELECT COUNT(DISTINCT BAG_USER_ID), COUNT(DISTINCT CAP_USER_ID) FROM (SELECT CAS         32    22367.5       4622
E MBAG.BAG_KIND WHEN

SELECT COUNT(DISTINCT APL_USER_ID), COUNT(DISTINCT SMS_USER_ID) FROM (SELECT CAS         32   23160.75       4458
E MAPP.SMST_FLG WHEN

select item_id,category_id,item_nm,carrier_1_publish_flg,carrier_2_publish_flg,c         25   13244.16         88
arrier_3_publish_flg

SELECT * FROM (SELECT DISTINCT user_id, 1 as carrier_id, row_number() over( orde         22 17519.6364         65
r by last_adm_dt  )

SELECT alias000$."STYLESHEET" AS STYLESHEET FROM "SYS"."METASTYLESHEET" alias000         20      14730        992
$ WHERE 1 = 1 AND ((

select user_regist_kind1, TO_CHAR(last_adm_dt_kind1,'YYYY/MM/DD HH24:MI:SS') as          20    24929.2         93
last_adm_dt_kind1 fr

SELECT     user_id,     sum(prev_user_point_amt),      sum(user_point_result_amt         18 15337.3333         19
),     trunc(update_

    SELECT     mfri.free_rankavg_incentive_id,     mfri.free_rankavg_id,     mfr         18      15336         18
i.team_flg,     mfri

     sss01dbiuser.         17 22733.6471        291
tbl_usermyroom1

select * from (       select temp_.*, rownum as rownumber_ from (            SEL         16    35747.5        389
ECT         mwp.aplu

select * from (       select temp_.*, rownum as rownumber_ from (            sel         15    34043.2      13478
ect     user_id,

SELECT count(DISTINCT user_id) as datacount FROM MST_User1 WHERE user_id in (SEL         15    14788.8         42
ECT user_id FROM MST

SELECT AP001_ID,USER_ID,AP001_LEVEL_NO,MISSION_COMPLETE_PCT,TOTAL_GAME_CNT,TOTAL         13 27131.0769         87
_COIN_AMT,TOTAL_DECO

select user_id,nick_name,mail,mail_sec,mail_domain,user_name,user_zip,user_pref,         12 29984.6667       5073
user_address,to_char

SELECT AP001_ITEM_ID,AP001_ID,AP001_ITEM_CATEGORY_CD,CARRIER_1_PUBLISH_FLG,CARRI         12       9270         31
ER_1_PUBLISH_DT,CARR

2011年2月8日火曜日

ライブラリキャッシュの利用状況を確認する

SQLチューニングをほとんどしていない環境では、SQLの本数が多すぎることがあります。
その場合、データバッファキャッシュよりライブラリキャッシュがボトルネックになるかもしれません。

v$librarycacheのライブラリキャッシュ情報をウォッチするといいでしょう。

ヒット率は95%以上が理想です。
SQLの本数が多い場合、ラッチ(キャッシュのロック)がボトルネックになるのでgethitratioを注視すべきです。
gethitratio・・・ラッチの取得率
pinhitratio・・・キャッシュ(のデータ)の取得率。

set time on
set pages 10000
set lines 120
col namespace for a20
select namespace,gethitratio,pinhitratio from v$librarycache;

実行例は次の通り。
NAMESPACE            GETHITRATIO PINHITRATIO
-------------------- ----------- -----------
SQL AREA              .872027894  .981766737
TABLE/PROCEDURE       .994262842   .97704901
BODY                  .999516938  .998802497
TRIGGER               .915954808  .921656241
INDEX                 .692952564  .828487881
CLUSTER               .990343307  .990707854
OBJECT                         1           1
PIPE                           1           1
JAVA SOURCE           .194444444  .236842105
JAVA RESOURCE         .194444444  .236842105
JAVA DATA                      1           1


なお、10gR2(?)では、たまにhitratioが1000%を超えたりほぼ0%になる不具合(?)があります。