SQL> alter session set sql_trace = true;
세션이 변경되었습니다.
SQL> select count(1) from test_table2;
COUNT(1)
----------
11985
SQL> alter session set sql_trace = false;
세션이 변경되었습니다.
SQL> select r.value || '/' || lower(t.instance_name) || '_ora_'
2 || ltrim(to_char(p.spid)) || '.trc' trace_file
3 from v$process p, v$session s, v$parameter r, v$instance t
4 where p.addr = s.paddr
5 and r.name = 'user_dump_dest'
6 and s.sid = (select sid from v$mystat where rownum = 1);
TRACE_FILE
--------------------------------------------------------------------------
/backupdata/oracle/app/diag/rdbms/ora11g/ORA11G/trace/ora11g_ora_15737.trc
관련 parameter 확인
show parameter sql_trace
=> trace 여부
show parameter user_dump_dest
=> trace 파일 위치
show parameter timed_statistics
=> CPU시간, 실행시간 등 시간관련 통계 수집 여부
show parameter max_dump
=> trace 파일 사이즈
PARSING IN CURSOR #11529215044979333784 len=38 dep=0 uid=0 oct=3 lid=0 tim=16640210204849 hv=1919769748 ad='c0000002c75d4518' sqlid='cnpkwyjt6ur4n'
select count(1) from test_table2
END OF STMT
PARSE #11529215044979333784:c=0,e=1205,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=3110898069,tim=16640210204847
EXEC #11529215044979333784:c=0,e=32,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=3110898069,tim=16640210204967
FETCH #11529215044979333784:c=0,e=1990,p=0,cr=64,cu=0,mis=0,r=1,dep=0,og=1,plh=3110898069,tim=16640210206985
STAT #11529215044979333784 id=1 cnt=1 pid=0 pos=1 obj=0 op='SORT AGGREGATE (cr=64 pr=0 pw=0 time=1996 us)'
STAT #11529215044979333784 id=2 cnt=11985 pid=1 pos=1 obj=353490 op='INDEX FAST FULL SCAN TEST_TABLE2_PK (cr=64 pr=0 pw=0 time=2863 us cost=17 size=0 card=11985)'
FETCH #11529215044979333784:c=0,e=2,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,plh=3110898069,tim=16640210208042
*** SESSION ID:(21.6419) 2016-11-26 10:03:31.856
CLOSE #11529215044979333784:c=0,e=4,dep=0,type=0,tim=16640210216421
옵션 | 설명 |
---|---|
tracefile | input 파일 |
outputfile | output 파일 |
wait=yes/no | 대기 이벤트 포함 여부 |
sort=option | 보고서 정렬 순서 * prscnt 파싱 횟수 * prscpu 파싱 중 소모된 cpu time * prsela 파싱 중 소모된 실제 시간 * prsdsk 파싱 중 디스크 읽은 횟수 * prsqry 파싱 중 사용한 consistent block 수 * prscu 파싱 중 사용한 current block 수 * prsmis 파싱 중 발생한 library cache miss 건수 * execnt 실행 횟수 * execpu 실행 중 소모된 cpu 시간 * exeela 실행 중 소모된 실제 시간 * exedsk 실행 중 디스크 읽은 횟수 * exeqry 실행 중 사용한 consistent block 수 * execu 실행 중 사용한 current block 수 * exerow 실행 중 처리한 row 수 * exemis 실행 중 발생한 library cache miss 건수 * fchcnt 패치 횟수 * fchcpu 패치 중 소모된 cpu time * fchela 패치 중 소모된 실제 시간 * fchdsk 패치 중 디스크 읽은 횟수 * fchqry 패치 중 사용한 consistent block 수 * fchcu 패치 중 사용한 current block 수 * fchrow 패치된 row 수 |
print=integer | 지정된 수만큼의 SQL 분석결과를 output파일에 저장 |
aggregate=yes/no | 만약 aggregate=no를 하게 되면 여러 사용자가 수행한 동일 SQL를 통합하지 않음 |
insert=filename | 분석 결과를 데이터베이스에 저장할 SQL을 생성 |
sys=yes/no | sys 유저로 수행한 SQL 포함 여부 |
table=schema.tablename | output 파일을 만들기 전에 임시로 실행계획을 저장할 스키마와 테이블 지정 |
explain=user/password | 지정된 스키마 유저에 실행계획 생성 |
record=filename | 지정된 파일에 nonrecursive SQL 을 기록 |
width=number | outfile의 넓이 지정 |
********************************************************************************
SQL ID: cnpkwyjt6ur4n
Plan Hash: 3110898069
select count(1)
from test_table2
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 3 0.00 0.00 0 0 0 0
Execute 3 0.00 0.00 0 0 0 0
Fetch 6 0.00 0.00 0 192 0 3
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 12 0.00 0.00 0 192 0 3
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS
Rows Row Source Operation
------- ---------------------------------------------------
1 SORT AGGREGATE (cr=64 pr=0 pw=0 time=1996 us)
11985 INDEX FAST FULL SCAN TEST_TABLE2_PK (cr=64 pr=0 pw=0 time=2863 us cost=17 size=0 card=11985)(object id 353490)
********************************************************************************
항목 | 설명 | AutoTrace 항목과 비교 |
---|---|---|
call | 커서 상태에 따라 Parse, Execute, Fetch 세 개의 Call로 나누어 각각에 대한 통계정보를 보여준다. \-Parse : 커서를 파싱하고 실행계획을 생성하는 데 대한 통계 \-Execute : 커서의 실행단계에 대한 통계 \-Fetch : 레코드를 실제로 Fetch하는 데 대한 통계 | |
count | Parse, Execute, Fetch 각 단계가 수행된 횟수 | SQL*Net roundtrips to/from client = fetch count |
cpu | 현재 커서가 각 단계에서 사용한 cpu time | |
elapsed | 현재 커서가 각 단계를 수행하는 데 소요된 시간 | |
disk | 디스크로부터 읽은 블록수 | physical reads |
query | consistent 모드에서 읽은 버퍼 블록 수 | consistent gets |
current | current 모드에서 읽은 버퍼 블록 수 | db block gets |
rows | 각 단계에서 읽거나 갱신한 처리 건수 | fetch rows |
항목 | 설명 |
---|---|
rows | 각 수행단계에 출력된 row수 |
cr | consistent 모드 블록 읽기 |
pr® | 디스크 블록 읽기 |
pw(w) | 디스크 블록 쓰기 |
time | 소요시간 |
cost | Cost Based Optimizer(CBO)에서 예측한 비용 |
size | 리턴한 데이터 size(bytes) |
card | cardinality, Cost Based Optimizer(CBO)에서 예측한 row수 |
alter session set events '10046 trace name context forever, level 1';
alter session set events '10046 trace name context off';
이벤트 트레이스 테스트
--level별 테스트
--level4
SQL> alter session set events '10046 trace name context forever, level 4';
세션이 변경되었습니다.
SQL> var col17 varchar2(20);
SQL> exec :col17 := '642101930';
PL/SQL 처리가 정상적으로 완료되었습니다.
SQL> select a.col5
2 from test_table1 a
3 , test_table2 b
4 where a.col1 = '20160718578354013'
5 and a.col1 = b.col1
6 and b.col7 = :col17;
COL5
-------------------------------------------------------------------------------
테스트1857835
테스트1857835
SQL> alter session set events '10046 trace name context off';
--trace 파일 내용
PARSING IN CURSOR #11529215044982025096 len=149 dep=0 uid=0 oct=3 lid=0 tim=16830876425546 hv=1635187749 ad='c000000088bab468' sqlid='2hxjps9hrdz15'
select a.col5
from test_table1 a
, test_table2 b
where a.col1 = '20160718578354013'
and a.col1 = b.col1
and b.col7 = :col17
END OF STMT
PARSE #11529215044982025096:c=0,e=349,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=16830876425544
BINDS #11529215044982025096:
Bind#0
oacdty=01 mxl=128(40) mxlc=00 mal=00 scl=00 pre=00
oacflg=03 fl2=1000000 frm=01 csi=840 siz=128 off=0
kxsbbbfp=9fffffffbf3e0668 bln=128 avl=09 flg=05
value="642101930"
EXEC #11529215044982025096:c=0,e=1758,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=1594570479,tim=16830876427454
FETCH #11529215044982025096:c=0,e=98,p=0,cr=9,cu=0,mis=0,r=1,dep=0,og=1,plh=1594570479,tim=16830876427583
FETCH #11529215044982025096:c=0,e=160,p=0,cr=12,cu=0,mis=0,r=1,dep=0,og=1,plh=1594570479,tim=16830876428580
STAT #11529215044982025096 id=1 cnt=2 pid=0 pos=1 obj=0 op='NESTED LOOPS (cr=21 pr=0 pw=0 time=93 us cost=16 size=52 card=1)'
STAT #11529215044982025096 id=2 cnt=1 pid=1 pos=1 obj=353487 op='TABLE ACCESS BY INDEX ROWID TEST_TABLE1 (cr=3 pr=0 pw=0 time=26 us cost=2 size=26 card=1)'
STAT #11529215044982025096 id=3 cnt=1 pid=2 pos=1 obj=353488 op='INDEX UNIQUE SCAN TEST_TABLE1_PK (cr=2 pr=0 pw=0 time=17 us cost=1 size=0 card=1)'
STAT #11529215044982025096 id=4 cnt=2 pid=1 pos=2 obj=353489 op='TABLE ACCESS BY INDEX ROWID TEST_TABLE2 (cr=18 pr=0 pw=0 time=64 us cost=14 size=26 card=1)'
STAT #11529215044982025096 id=5 cnt=148 pid=4 pos=1 obj=353490 op='INDEX RANGE SCAN TEST_TABLE2_PK (cr=3 pr=0 pw=0 time=17 us cost=1 size=0 card=142)'
BINDS로 시작되는 정보가 추가되었다.
value="642101930" 부분을 보면 쿼리를 수행하며 입력하였던 bind 값을 확인할 수 있다.
--level8
alter session set events '10046 trace name context forever, level 8';
다음 내용이 추가되었다.
WAIT #11529215044982021216: nam='SQL*Net message to client' ela= 2 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=16833712920967
tkprof output 파일에 다음 내용이 추가되었다.
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 13.14 13.14
********************************************************************************
--level12
BIND 정보와 WAIT 정보가 추가되었다.
BIND 변수 내용은 트레스파일(trc}에만 나타나며 tkprof output 파일에는 해당 정보가 없다.
Level | trace 파일 포함정보 | tkprof output 파일 포함정보 |
---|---|---|
0 | 트레이스 안 함. sql_trace = false와 동일 | 트레이스 안 함. sql_trace = false와 동일 |
1 | 기본 trace 정보 sql_trace = true | 기본 trace 정보 sql_trace = true |
4 | 기본 trace 정보 + BIND 정보 | 기본 trace 정보 |
8 | 기본 trace 정보 + WAIT 정보 | 기본 trace 정보 + WAIT 정보 |
12 | 기본 trace 정보 + BIND + WAIT 정보 | 기본 trace 정보 + WAIT 정보 |
Level을 4 이상으로 설정하면 트레이스 파일이 매우 급격하게 커지므로 주의가 필요하다.
Elapsed time 테스트
SQL> set timing on
SQL> set arraysize 10
SQL> alter session set events '10046 trace name context forever, level 8';
세션이 변경되었습니다.
경 과: 00:00:00.00
SQL> select patname from acpatbat where resno1 like '81%';
PATNAME
--------------------------------------------------------------------------------
테스트0559111
테스트0294403
테스트0294417
테스트0497943
테스트0524114
테스트0669113
테스트0669225
테스트0669228
45790 개의 행이 선택되었습니다.
경 과: 00:00:23.66
SQL ID: cbdv9jruuwpcu
Plan Hash: 3743901090
select patname
from
acpatbat where resno1 like '81%'
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 4580 1.14 3.27 22558 27772 0 45790
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4582 1.14 3.27 22558 27772 0 45790
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS
Rows Row Source Operation
------- ---------------------------------------------------
45790 INDEX FAST FULL SCAN ACPATBAT_IDX1 (cr=27772 pr=22558 pw=0 time=965233 us cost=4011 size=1007391 card=47971)(object id 137687)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 4580 0.00 0.00
Disk file operations I/O 2 0.00 0.00
db file scattered read 237 0.10 2.41
SQL*Net message from client 4580 58.52 78.70
db file sequential read 3 0.00 0.00
=>
총 건수 45790개이고 arraysize를 10으로 해서 fetch count는 4580, DB 내부적으로는 총 3.27초 소요가 되었으나 경과 시간은 23.66초이다.
나머지 시간은 애플리케이션으로부터 추가 Call을 기다리면서 Idle 상태로 대기한 시간이다.
또한 cpu time은 1.14초이나 elapsed time은 3.27초이고 나머지 2.13초는 대기 상태에 빠졌던 것으로 이해하면 된다.
--------------------------------------------------------------------------------------------------------------------
그런데.. 대기이벤트에서 보면 80초가량이 대기인데.. 왜 실제 경과시간은 23초 정도이지??
arraysize 설정을 하지 않고 실행해보니 그래도 비슷한 대기 시간이 나왔다.
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 459 0.00 0.00
SQL*Net message from client 458 0.08 22.31
arraysize 관련해서 제대로 대기시간을 측정하지 못하는 것 같다.
--------------------------------------------------------------------------------------------------------------------
이벤트 종류 | 설명 |
---|---|
SQL*Net message from client | Idle 이벤트로서 오라클 서버 프로세스가 사용자에게 결과를 전송하고 다음 Fetch Call이 올 때까지 대기한 시간 |
SQL*Net message to client | 클라이언트에게 메시지를 보냈는데 클라이언트가 너무 바쁘거나 네트워크 부하 때문에 메시지를 잘 받았다는 신호가 정해진 시간보다 늦게 도착하는 경우 |
db file sequential read | Single Block Read 방식으로 디스크 블록을 읽을 때 발생 |
db file scattered read | Multi Block Read 방식으로 디스크 블록을 읽을 때 발생 |
SQL*Net more data to client | SDU 단위 패킷을 전송했는데 잘 받았다는 신호가 정해진 시간보다 늦게 도착할 때 발생 |
SQL*Net more data from client | 클라이언트에게 더 받을 데이터가 있는데 지연이 발생하는 경우 |
그밖의 자기 세션 trace 방법
그밖의 다른 세션 trace 방법
Trace 파일 획득 function 만들기
trace용 function 만들기
개발자에게 서버 파일 접근 권한이 없는 경우 아래 function을 만들어놓으면 특별한 서버 접근 권한 없이 trace 파일을 획들할 수 있다.
(sys 계정에 접속해야 하고 DIRECTORY 생성 권한이 없는 일반 사용자는 생성이 어려우므로 최초 생성시 DBA의 도움이 필요하겠지만..)
-- sys 계정 접속
CONN / AS SYSDBA
-- trace용 user 생성
CREATE USER trace_user IDENTIFIED BY trace_user ACCOUNT LOCK;
-- trace 파일을 담을 type 테이블 선언
CREATE TYPE trace_user.t_trace_tab AS TABLE OF VARCHAR2(32767);
CREATE OR REPLACE FUNCTION trace_user.get_trace_file (p_trace_file IN VARCHAR2)
RETURN trace_user.t_trace_tab PIPELINED
AS
l_file UTL_FILE.file_type;
l_text VARCHAR2(32767);
BEGIN
l_file := UTL_FILE.fopen('TRACE_DIR', p_trace_file, 'r', 32767);
BEGIN
LOOP
UTL_FILE.get_line(l_file, l_text);
PIPE ROW (l_text);
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
END;
UTL_FILE.fclose(l_file);
RETURN;
EXCEPTION
WHEN OTHERS THEN
PIPE ROW ('ERROR: ' || SQLERRM);
IF UTL_FILE.is_open(l_file) THEN
UTL_FILE.fclose(l_file);
END IF;
RETURN;
END;
-- PUBLIC 권한 주기
GRANT EXECUTE ON trace_user.t_trace_tab TO PUBLIC;
GRANT EXECUTE ON trace_user.get_trace_file TO PUBLIC;
CREATE PUBLIC SYNONYM get_trace_file FOR trace_user.get_trace_file;
-- 트레이스 directory 선언.
CREATE OR REPLACE DIRECTORY trace_dir AS '/backupdata/oracle/app/diag/rdbms/ora11g/ORA11G/trace/';
GRANT READ ON DIRECTORY trace_dir TO trace_user;
사용예제
SQL> alter session set sql_trace = true;
SQL> select count(1) from test_table1;
COUNT(1)
----------
41722
1개의 행이 선택되었습니다.
SQL> alter session set sql_trace = false;
세션이 변경되었습니다.
SQL> set pagesize 0 feedback off trimspool on tab off
SQL> spool c:\tracefile01.trc
SQL> select * from table(get_trace_file('ORA11G_ora_17815.trc'));
Trace file /backupdata/oracle/app/diag/rdbms/ora11g/ORA11G/trace/ORA11G_ora_17815.trc
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
ORACLE_HOME = /backupdata/oracle/app/product/11.2
System name: HP-UX
Node name: smart05
Release: B.11.31
Version: U
Machine: ia64
Instance name: ORA11G
Redo thread mounted by this instance: 1
Oracle process number: 0
Unix process pid: 17815, image: oracle@smart05
.....생략
SQL> spool off
SQL> set pagesize 14 feedback on
c:\tracefile01.trc 파일이 생성된다.
해당 파일에서 처음줄의 SQL> select * from table(get_trace_file('ORA11G_ora_17815.trc'));
부분을 제거하고 tkprof 툴을 쓰면 된다.
Service
SQL> show parameter service_name
NAME TYPE VALUE
------------------------------------ ---------------------- ------------------------------
service_names string ORA11G
SQL> select sid, service_name, module, action
2 from v$session
3 where service_name <> 'SYS$BACKGROUND';
SID SERVICE_NAME MODULE ACTION
----- ---------------- ------------------- -----------------------
~~ 생략
서비스별 trace
--설정
--dbms_monitor 패키지는 10g부터 사용 가능
exec dbms_monitor.serv_mod_act_trace_enable(service_name=>'ORA11G'
,module_name=>dbms_monitor.all_modules
,action_name=>dbms_monitor.all_actions
,waits=>true
,binds=>true
);
--실행중인 trace 확인
select primary_id service_name
, qualifier_id1 module
, qualifier_id2 action
, waits, binds
from dba_enabled_traces;
--해제
exec dbms_monitor.serv_mod_act_trace_disable(service_name=>'ORA11G'
,module_name=>dbms_monitor.all_modules
,action_name=>dbms_monitor.all_actions
);
모듈별 trace
--모듈 설정
exec dbms_application_info.set_module(module_name = > 'son manager', action_name => 'son select test');
--설정
exec dbms_monitor.serv_mod_act_trace_enable(service_name=>'ORA11G'
,module_name=>'son manager'
,action_name=>dbms_monitor.all_actions
,waits=>true
,binds=>true
);
--해제
exec dbms_monitor.serv_mod_act_trace_disable(service_name=>'ORA11G'
,module_name=>'son manager'
,action_name=>dbms_monitor.all_actions
);
액션별 trace
--액션 설정
exec dbms_application_info.set_action(action_name => 'son select test2');
--설정
exec dbms_monitor.serv_mod_act_trace_enable(service_name=>'ORA11G'
,module_name=>'son manager'
,action_name=>'son select test2'
,waits=>true
,binds=>true
);
--해제
exec dbms_monitor.serv_mod_act_trace_disable(service_name=>'ORA11G'
,module_name=>'son manager'
,action_name=>'son select test2'
);
client_indentifier별 trace
--client_identifier 설정
exec dbms_session.set_identifier('sontest');
--설정
exec dbms_monitor.client_id_trace_enable(client_id=>'sontest',waits=>false,binds=>false);
--해제
exec dbms_monitor.client_id_trace_disable(client_id=>'sontest');