31
JPOUG Presents なーんでだ at db tech showcase 2015 Tokyo #2 #dbts2015 #jpoug / Koji Shinkubo @kouji_s_0808

Jpoug presents なーんでだ2 db tech showcase 2015 tokyo

Embed Size (px)

Citation preview

JPOUG Presents

なーんでだat db tech showcase 2015 Tokyo

#2

#dbts2015 #jpoug

/ Koji Shinkubo @kouji_s_0808

実行計画と待機イベントの謎

例えば、これは、どんな状況か想像してみてください。

ある日、突然、バッチ処理が返ってこなくなった。

状況 実行時間普通の場合 5分何かおかしい場合 100分+

TAB_01

TAB_02

SQL文update tab_01 a1set col10 = nullwhere exists (select 1 from tab_02 a2 where a1.id = a2.id);

ID NUMBER COL1 VARCHAR2(100) COL2 VARCHAR2(100) COL3 VARCHAR2(100) COL4 VARCHAR2(100) COL5 VARCHAR2(100) COL6 VARCHAR2(100) COL7 VARCHAR2(100) COL8 VARCHAR2(100) COL9 VARCHAR2(100) COL10 VARCHAR2(100)

ID NUMBER COL1 VARCHAR2(100) COL2 VARCHAR2(100)

実行計画は?

普通の場合も、何かがおかしい場合も同じ実行計画­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­| Id | Operation | Name |­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­| 0 | UPDATE STATEMENT | || 1 | UPDATE | TAB_01 ||* 2 | HASH JOIN | || 3 | VIEW | VW_SQ_1 || 4 | SORT UNIQUE | || 5 | TABLE ACCESS FULL| TAB_02 || 6 | TABLE ACCESS FULL | TAB_01 |­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

同じ実行計画(基本的に同じデータ)でも、ものすごく遅い時がある

なーんでだ?

SQLトレース(の待機イベント)

を見てみますか?

普通の場合 Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ Waited ­­­­­­­­­­ ­­­­­­­­­­­­ Disk file operations I/O 16 0.00 0.00 db file sequential read 3 0.00 0.00 gc cr multi block request 37 0.00 0.00 db file scattered read 46 0.00 0.06 SQL*Net message to client 1 0.00 0.00

何かがおかしい場合 Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ Waited ­­­­­­­­­­ ­­­­­­­­­­­­ Disk file operations I/O 21 0.00 0.00 db file sequential read 2071 0.00 0.45 gc cr multi block request 37 0.00 0.00 db file scattered read 46 0.00 0.06 SQL*Net message to client 1 0.00 0.00

普通の場合

何かがおかしい場合

Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ Waited ­­­­­­­­­­ ­­­­­­­­­­­­ Disk file operations I/O 16 0.00 0.00 db file sequential read 3 0.00 0.00 gc cr multi block request 37 0.00 0.00 db file scattered read 46 0.00 0.06 SQL*Net message to client 1 0.00 0.00

Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ Waited ­­­­­­­­­­ ­­­­­­­­­­­­ Disk file operations I/O 21 0.00 0.00 db file sequential read 2071 0.00 0.45 gc cr multi block request 37 0.00 0.00 db file scattered read 46 0.00 0.06 SQL*Net message to client 1 0.00 0.00

少しまとめてみると、実行計画(FULL SCAN)は同じなのに、待機イベントが違いますね。

状況 待機イベントの状況普通の場合 db file sequential readはほとんどない何かおかしい場合 db file sequential readがとても多い

なーんでだ!?(再び)

ちなみ私が遭遇した時は、SQLトレースが取得できる状況ではなかったので、

ASHからこの状況を観察していました。

未整形のSQLトレースを見てみますか?

普通の場合

何かがおかしい場合

WAIT #140537630453352: nam='db file sequential read' ela= 2167 file#=10 block#=92248 blocks=1 obj#=76101 tim=1433731036128545

WAIT #139710261849704: nam='db file sequential read' ela= 283 file#=3 block#=9682 blocks=1 obj#=0 tim=1433731552208794WAIT #139710261849704: nam='db file sequential read' ela= 271 file#=3 block#=9681 blocks=1 obj#=0 tim=1433731552209277WAIT #139710261849704: nam='db file sequential read' ela= 272 file#=3 block#=9680 blocks=1 obj#=0 tim=1433731552211701WAIT #139710261849704: nam='db file sequential read' ela= 258 file#=3 block#=163 blocks=1 obj#=0 tim=1433731552214005WAIT #139710261849704: nam='db file sequential read' ela= 260 file#=3 block#=162 blocks=1 obj#=0 tim=1433731552215588...

db file sequential readで待機している対象のセグメントを特定select segment_namefrom dba_extentswhere file_id = :file#and :block# between block_id and block_id + blocks ­ 1and rownum = 1

db file sequential readで待機している対象セグメント

状況 対象ブロック 待機の対象オブジェクト普通の場合 file#=10,

block#=nnnTAB_01

何かがおかしい場合

file#=3 ,block#=nnn

_SYSSMU3_4004931649$

もう分かりましたね!

いや! まだ早い!

何かがおかしい場合

例えば、file#=3, block#=9682の

UNDOセグメント="_SYSSMU3_4004931649$"は、どのオブジェクトを格納しているUNDOセグメントか?

WAIT #139710261849704: nam='db file sequential read' ela= 283 file#=3 block#=9682 blocks=1 obj#=0 tim=1433731552208794WAIT #139710261849704: nam='db file sequential read' ela= 271 file#=3 block#=9681 blocks=1 obj#=0 tim=1433731552209277WAIT #139710261849704: nam='db file sequential read' ela= 272 file#=3 block#=9680 blocks=1 obj#=0 tim=1433731552211701WAIT #139710261849704: nam='db file sequential read' ela= 258 file#=3 block#=163 blocks=1 obj#=0 tim=1433731552214005WAIT #139710261849704: nam='db file sequential read' ela= 260 file#=3 block#=162 blocks=1 obj#=0 tim=1433731552215588...

DUMPalter system dump undo header '_SYSSMU3_4004931649$';

********************************************************************************Undo Segment: _SYSSMU26_3270072861$ (26)******************************************************************************** ... TRN TBL::

index state cflags wrap# uel scn dba parent­xid nub stmt_num cmt ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 0x00 9 0x00 0x062c 0x000d 0x0000.00c4ffaa 0x00c0013a 0x0000.000.00000000 0x00000001 0x00000000 1433908829 ^^^^^^^^^^ 0x01 9 0x00 0x062c 0x0005 0x0000.00c4fba5 0x00c00139 0x0000.000.00000000 0x00000001 0x00000000 1433907818 0x02 9 0x00 0x062c 0x0021 0x0000.00c4f514 0x00c00135 0x0000.000.00000000 0x00000001 0x00000000 1433905837 0x03 9 0x00 0x062c 0x000f 0x0000.00c4fcd9 0x00c00139 0x0000.000.00000000 0x00000001 0x00000000 1433908238 0x04 9 0x00 0x062c 0x0010 0x0000.00c4f885 0x00c00136 0x0000.000.00000000 0x00000001 0x00000000 1433906917 0x05 9 0x00 0x062c 0x001d 0x0000.00c4f018 0x00c00135 0x0000.000.00000000 0x00000001 0x00000000 1433904996 0x06 9 0x00 0x062c 0x001b 0x0000.00c4ee33 0x00c00134 0x0000.000.00000000 0x00000001 0x00000000 1433904396 0x07 9 0x00 0x062b 0x0014 0x0000.00c4ecd4 0x00c00134 0x0000.000.00000000 0x00000001 0x00000000 1433904036 0x08 9 0x00 0x062b 0x0018 0x0000.00c4f379 0x00c00135 0x0000.000.00000000 0x00000001 0x00000000 1433905528

UNDO BLOCKはどこ?select dbms_utility.data_block_address_file( to_number('00c0013a','xxxxxxxx')) file#, dbms_utility.data_block_address_block( to_number('00c0013a','xxxxxxxx')) block#from dual;

FILE# BLOCK#­­­­­­­­­­ ­­­­­­­­­­ 3 314

DUMP その2alter system dump datafile 3 block 314;

*­­­­­­­­­­­­­­­­­­­­­­­­­­­­­* Rec #0xc slt: 0x11 objn: 76102(0x00012946) objd: 76102 tblspc: 0(0x00000000) ^^^^^^^^^^^* Layer: 11 (Row) opc: 1 rci 0x0bUndo type: Regular undo User Undo Applied Last buffer split: NoTemp Object: NoTablespace Undo: Nordba: 0x00000000*­­­­­­­­­­­­­­­­­­­­­­­­­­­­­KDO undo record:KTB Redoop: 0x02 ver: 0x01compat bit: 4 (post­11) padding: 1op: C uba: 0x00c0013a.0085.0bKDO Op code: LKR row dependencies Disabled xtype: XA flags: 0x00000000 bdba: 0x00416dd9 hdba: 0x00416dd8itli: 3 ispac: 0 maxfr: 4863tabn: 0 slot: 2 to: 0

オブジェクトID=76102は誰?select object_name from dba_objects where object_id=76102;

OBJECT_NAME­­­­­­­­­­­TAB_02

やっと、分かりましたね!

少なくとも、このUPDATE文が実行された際、tab_02テーブルにはアクティブなトランザクションが

あったという事。

このUPDATE文による更新対象の行を検索する際に、UNDOからCRブロックを生成して読み取り一貫性を

保障しようとするのでUNDOブロックへのdb file sequential readが多発しているという事。

update tab_01 a1set col10=nullwhere exists (select 1 from tab_02 a2 where a1.id = a2.id);

実行計画だけで判断できないパターンもあります。

待機イベントとそのパラメーターの理解も大事ですね。

Finish!