forked from tanelpoder/tpt-oracle
-
Notifications
You must be signed in to change notification settings - Fork 4
/
cbo_helper.sql
211 lines (165 loc) · 6.97 KB
/
cbo_helper.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
-- Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
begin
for i in (select value from v$parameter where name = 'user_dump_dest') loop
execute immediate 'create or replace directory e2sn_udump as '''||i.value||'''';
end loop;
end;
/
create or replace package e2sn_monitor as
function get_trace_file (file_name in varchar2) return dbms_debug_vc2coll pipelined;
function get_session_trace ( p_sid in number default sys_context('userenv','sid') ) return dbms_debug_vc2coll pipelined;
procedure cbo_trace_on;
procedure cbo_trace_off;
procedure sql_trace_on (p_waits in boolean default true, p_binds in boolean default true);
procedure sql_trace_off;
procedure set_tracefile_identifier(p_text in varchar2);
function trace_dump (p_exec_statement in varchar2) return dbms_debug_vc2coll pipelined;
function test (p_select_statement in varchar2 default 'select count(*) from dba_segments') return dbms_debug_vc2coll pipelined;
end e2sn_monitor;
/
create or replace package body e2sn_monitor as
procedure sql_trace_on (p_waits in boolean default true, p_binds in boolean default true)
as
begin
execute immediate 'alter session set events ''10046 trace name context forever, level 12''';
--dbms_monitor.session_trace_enable(waits=>p_waits, binds=>p_binds);
end; -- sql_trace_on
procedure sql_trace_off
as
begin
execute immediate 'alter session set events ''10046 trace name context off''';
--dbms_monitor.session_trace_disable;
end; -- sql_trace_off
procedure cbo_trace_on
as
begin
--dbms_output.put_line('setting 10053');
execute immediate 'alter session set events ''10053 trace name context forever, level 1''';
--execute immediate 'alter session set "_optimizer_trace"=all';
--dbms_output.put_line('event 10053 set');
end cbo_trace_on;
procedure cbo_trace_off
as
begin
execute immediate 'alter session set events ''10053 trace name context off''';
--execute immediate 'alter session set "_optimizer_trace"=none';
end cbo_trace_off;
procedure set_tracefile_identifier(p_text in varchar2)
as
begin
dbms_output.put_line('trci='||p_text);
execute immediate 'alter session set tracefile_identifier='||p_text;
end;
function trace_dump (p_exec_statement in varchar2) return dbms_debug_vc2coll pipelined
as
j number;
l_prefix varchar2(100);
begin
l_prefix := upper('CBOHELP_'||to_char(sysdate, 'YYYYMMDD_HH24_MI_SS'));
set_tracefile_identifier(l_prefix);
--cbo_trace_on;
--sql_trace_on;
execute immediate p_exec_statement ||' /* E2SN CBO helper: '||l_prefix||'*/ ';
dbms_output.put_line(j);
--sql_trace_off;
--cbo_trace_off;
for i in (select column_value from table(e2sn_monitor.get_session_trace)) loop
pipe row (i.column_value);
end loop;
end trace_dump;
function test (p_select_statement in varchar2 default 'select count(*) from dba_segments') return dbms_debug_vc2coll pipelined
as
j number;
l_prefix varchar2(100);
begin
l_prefix := upper('CBOHELP_'||to_char(sysdate, 'YYYYMMDD_HH24_MI_SS'));
set_tracefile_identifier(l_prefix);
--cbo_trace_on;
--sql_trace_on;
execute immediate p_select_statement ||' /* E2SN CBO helper: '||l_prefix||'*/ ' INTO j;
dbms_output.put_line(j);
--sql_trace_off;
--cbo_trace_off;
for i in (select column_value from table(e2sn_monitor.get_session_trace)) loop
pipe row (i.column_value);
end loop;
end test;
function get_trace_file (file_name in varchar2) return dbms_debug_vc2coll pipelined
as
invalid_file_op exception;
pragma exception_init(invalid_file_op, -29283);
f utl_file.file_type;
line varchar2(32767);
begin
dbms_output.put_line('opening file='||file_name);
f := utl_file.fopen('E2SN_UDUMP', file_name, 'R', 32767);
loop
begin
utl_file.get_line(f, line);
exception
when no_data_found then utl_file.fclose(f) ; exit;
when others then utl_file.fclose(f) ; raise;
end;
if length(line) > 1000 then
for i in 0..trunc(length(line)/1000) loop
pipe row(substr(line,i*1000+1,1000));
end loop;
else
pipe row(line);
end if;
end loop;
return;
exception
when invalid_file_op then raise_application_error(-20000, 'ERROR: Unable to open tracefile. Maybe it does not exist');
end get_trace_file;
function get_session_trace ( p_sid in number default sys_context('userenv','sid') ) return dbms_debug_vc2coll pipelined
as
tracefile_name varchar2(4000);
tracefile_name_lower varchar2(4000);
begin
begin
select par.value ||'/'||(select instance_name from v$instance) ||'_ora_'||s.suffix|| '.trc' into tracefile_name
from
v$parameter par
, (select spid||case when traceid is not null then '_'||traceid else null end suffix
from v$process where addr = (select paddr from v$session
where sid = p_sid
)
) s
where name = 'user_dump_dest';
select par.value ||'/'||(select lower(instance_name) from v$instance) ||'_ora_'||s.suffix|| '.trc' into tracefile_name_lower
from
v$parameter par
, (select spid||case when traceid is not null then '_'||traceid else null end suffix
from v$process where addr = (select paddr from v$session
where sid = p_sid
)
) s
where name = 'user_dump_dest';
exception
when no_data_found then raise_application_error(-20000, 'ERROR: No matching SID/SERIAL# combination found');
end;
begin
for i in (select column_value from table(get_trace_file( tracefile_name ))) loop
pipe row(i.column_value);
end loop;
return;
exception
when others then
begin
for i in (select column_value from table(get_trace_file( tracefile_name_lower ))) loop
pipe row(i.column_value);
end loop;
return;
exception
when others then raise_application_error(-20000, 'Unknown error: '||sqlerrm||chr(10)||dbms_utility.format_error_backtrace);
end;
end;
return;
end get_session_trace;
end e2sn_monitor;
/
show err;
-- grant execute on e2sn_monitor to public;
-- create public synonym e2sn_monitor for e2sn_monitor;