Sunday, April 25, 2010

Oracle Hang状態でActive Session Listを獲得しよう。

Maxgaugeのようなツールの最高のメリットはOracle Hang状態でもActive Session Listを得ることができるということです。待機イベントとSQL情報が含まれたActive Session Listこそがすべての性能トラブルシューティングの初めです。ここからすべてのトラブルシューティングが始まります。


MaxgaugeのようなツールがOracle Hang状況でもデータを収集できるのはDMA(Direct Memory Access)を使用するためです。この方法はOracleのCOE(Center of Expertise)チームが極限の状況、すなわちSQLで必要な情報を収集できない際使用していた方法です。これがMaxgaugeのようなツールのおかげで普遍化されたのです。


もしMaxgaugeのようなツールがなければどうすればいいでしょうか。Oracleが提供するASHDUMP機能をPreliminary Connectionとともに使えば同じ効果が得られます。


  • Preliminary ConnectionとはSQL*Net方式ではない、Direct Memory Access方式で接続することです。
  • ASHDUMPとはActive Session ListのメモリーバージョンであるASH(Active Session History)をテキストファイルに書き込む機能です。

従って、この二つの機能を一緒に使えばまるでDMA方式でActive Session Listを得るのは同じ効果があります。


簡単な例で説明します。


まずPreliminary Connectionを結びます。


#> sqlplus -prelim sys/oracle@ukja1106 as sysdba
SQL*Plus: Release 11.1.0.6.0 - Production on Mon Apr 26 09:43:35 2010
Copyright (c) 1982, 2007, Oracle. All rights reserved.

一般的なクエリは動きません。

alter session set nls_date_format='yyyy/mm/dd hh24:mi:ss'
*
ERROR at line 1:
ORA-01012: not logged on
Process ID: 0
Session ID: 0 Serial number: 0

Preliminary Connection状態でASHDUMPを行ないます。レベル(10)は10分を意味します。すなわち、過去の10分間のASHを意味します。

SYS@ukja1106> oradebug setmypid
Statement processed.
SYS@ukja1106> oradebug dump ashdump 10
Statement processed.
SYS@ukja1106> oradebug tracefile_name
c:\oracle\diag\rdbms\ukja1106\ukja1106\trace\ukja1106_ora_12152.trc

ダンプファイルの内容は次のようです。11gからはActive Session Listとともに該当リストをテーブルに格納するためのスクリプトまで提供します。ハングの悪夢が終わったあと(大部分リスタート)、正確な分析をする目的です。

Processing Oradebug command 'dump ashdump 10'
ASH dump
<<>>
****************
SCRIPT TO IMPORT
****************
------------------------------------------
Step 1: Create destination table
------------------------------------------
CREATE TABLE ashdump AS
SELECT * FROM SYS.WRH$_ACTIVE_SESSION_HISTORY WHERE rownum < 0
----------------------------------------------------------------
Step 2: Create the SQL*Loader control file as below
----------------------------------------------------------------
load data
infile * "str '\n####\n'"
append
into table ashdump
fields terminated by ',' optionally enclosed by '"'
(
SNAP_ID CONSTANT 0 ,
DBID ,
INSTANCE_NUMBER ,
SAMPLE_ID ,
SAMPLE_TIME TIMESTAMP ENCLOSED BY '"' AND '"' "TO_TIMESTAMP(:SAMPLE_TIME ,'MM-DD-YYYY HH24:MI:SSXFF')" ,
SESSION_ID ,
SESSION_SERIAL# ,
SESSION_TYPE ,
USER_ID ,
SQL_ID ,
SQL_CHILD_NUMBER ,
SQL_OPCODE ,
FORCE_MATCHING_SIGNATURE ,
TOP_LEVEL_SQL_ID ,
TOP_LEVEL_SQL_OPCODE ,
SQL_PLAN_HASH_VALUE ,
SQL_PLAN_LINE_ID ,
SQL_PLAN_OPERATION# ,
SQL_PLAN_OPTIONS# ,
SQL_EXEC_ID ,
SQL_EXEC_START DATE 'MM/DD/YYYY HH24:MI:SS' ENCLOSED BY '"' AND '"' ":SQL_EXEC_START" ,
PLSQL_ENTRY_OBJECT_ID ,
PLSQL_ENTRY_SUBPROGRAM_ID ,
PLSQL_OBJECT_ID ,
PLSQL_SUBPROGRAM_ID ,
QC_INSTANCE_ID ,
QC_SESSION_ID ,
QC_SESSION_SERIAL# ,
EVENT_ID ,
SEQ# ,
P1 ,
P2 ,
P3 ,
WAIT_TIME ,
TIME_WAITED ,
BLOCKING_SESSION ,
BLOCKING_SESSION_SERIAL# ,
CURRENT_OBJ# ,
CURRENT_FILE# ,
CURRENT_BLOCK# ,
CURRENT_ROW# ,
CONSUMER_GROUP_ID ,
XID ,
REMOTE_INSTANCE# ,
TIME_MODEL ,
SERVICE_HASH ,
PROGRAM ,
MODULE ,
ACTION ,
CLIENT_ID
)
---------------------------------------------------
Step 3: Load the ash rows dumped in this trace file
---------------------------------------------------
sqlldr userid/password control=ashldr.ctl data= errors=1000000
---------------------------------------------------
<<>>
<<>>
####
58646642,1,12519562,"04-26-2010 09:44:01.822000000",160,1,2,0,
"",0,0,0,"",0,0,0,0,0,
0,"",0,0,0,0,0,0,0,
3213517201,9858,0,3,1,0,69788,4294967295,0,
4294967295,0,0,0,0,,0,0,165959219,
"ORACLE.EXE (CKPT)","",
"",""
####
58646642,1,12519486,"04-26-2010 09:42:45.808000000",160,1,2,0,
"",0,0,0,"",0,0,0,0,0,
0,"",0,0,0,0,0,0,0,
3213517201,9767,1,1,1,0,38825,4294967295,0,
4294967295,0,0,0,0,,0,0,165959219,
"ORACLE.EXE (CKPT)","",
"",""
####
58646642,1,12519416,"04-26-2010 09:41:35.770000000",160,1,2,0,
"",0,0,0,"",0,0,0,0,0,
0,"",0,0,0,0,0,0,0,
4078387448,9683,3,3,3,0,11083,4294967295,0,
4294967295,0,0,0,0,,0,0,165959219,
"ORACLE.EXE (CKPT)","",
"",""
####
58646642,1,12519384,"04-26-2010 09:41:03.774000000",163,1,2,0,
"",0,0,0,"",0,0,0,0,0,
0,"",0,0,0,0,0,0,0,
3176176482,40612,5,1,1000,999888,0,4294967291,0,
4294967295,0,0,0,0,,0,0,165959219,
"ORACLE.EXE (DIA0)","",
"",""
####
58646642,1,12519304,"04-26-2010 09:39:43.719000000",160,1,2,0,
"",0,0,0,"",0,0,0,0,0,
0,"",0,0,0,0,0,0,0,
3213517201,9551,1,1,1,0,38798,4294967295,0,
4294967295,0,0,0,0,,0,0,165959219,
"ORACLE.EXE (CKPT)","",
"",""
####
58646642,1,12519265,"04-26-2010 09:39:04.663000000",163,1,2,0,
"",0,0,0,"",0,0,0,0,0,
0,"",0,0,0,0,0,0,0,
3176176482,40493,5,1,1000,999941,0,4294967291,0,
4294967295,0,0,0,0,,0,0,165959219,
"ORACLE.EXE (DIA0)","",
"",""
####
58646642,1,12519183,"04-26-2010 09:37:42.554000000",160,1,2,0,
"",0,0,0,"",0,0,0,0,0,
0,"",0,0,0,0,0,0,0,
3213517201,9406,0,1,1,0,54077,4294967295,0,
4294967295,0,0,0,0,,0,0,165959219,
"ORACLE.EXE (CKPT)","",
"",""
####
<<>>

*** 2010-04-26 09:45:51.625
Oradebug command 'dump ashdump 10' console output:

事後分析用で使用したら有効であるはずです。ただし、Preliminary ConnectionとOradebugは非公式的な支援機能だから徹底なテストのあとに使用しなければならないし、可能な限りオラクル支援エンジニアの承認の上で使用しなければなりません。


もっと詳しい情報は次のリンクを参照してください。