stored procedure 收集session wait 信息(转)

来源:互联网 发布:mac画流程图软件 编辑:程序博客网 时间:2024/04/30 21:30
 

OWI --用 stored procedure 收集session wait 信息

包括对象如下:

event_seq: 序列,用于唯一标识每一条记录

dc_event_data: 表,用于存储session wait信息

dc_collect:存储过程,用于定期收集各个session wait信息,并保存到dc_event_data表中。根据建议,频率可保持在一分钟一次,而不影响系统性能。

dc_analyze: stored procedure. 用于分析和具体化表dc_event_data中的记录

--想法来源于<<Oracle Wait Interface A Practical Guide to Performance Diagnostics & Tuning>>


------------------------------------------
--SEQUENCE:
-- event_seq 这个序列其实不是很有必要,先留着,用于标识每一条记录
--USAGE:
-- As a unique ID for each collection

------------------------------------------
drop sequence event_seq
/

create sequence event_seq
start with 1
increment by 1
nocache
nocycle
nomaxvalue;

------------------------------------------
--TABLE:
-- DC_EVENT_DATA 用于保存各SESSION的性能信息

--USAGE:
-- To keep data collected by
-- procedure DC
------------------------------------------
drop table dc_event_data
/

create table DC_EVENT_DATA
(
event_seq number,
curr_time date,
sid number,
seq# number,
event varchar2(64),
p1text varchar2(64),
p1 number,
p1raw raw(8),
p2text varchar2(64),
p2 number,
p2raw raw(8),
p3text varchar2(64),
p3 number,
p3raw raw(8),
wait_time number,
seconds_in_wait number,
state varchar2(19),
serial# number,
username varchar2(30),
osuser varchar2(30),
paddr raw(8),
logon_time date,
process varchar2(12),
sql_hash_value number,
saddr raw(8),
module varchar2(48),
row_wait_obj# number,
row_wait_file# number,
row_wait_block# number,
row_wait_row# number,
sql_text varchar2(64)
);

------------------------------------------
--PROCEDURE:
-- DC_COLLECT 在某个时间点,检索V$SESSION_WAIT,收集需要关注的等待事件的session参数,将其保存至表DC_EVENT_DATA
--USAGE:
-- Collect performance data and keep
-- them in the tables as history data
------------------------------------------
drop procedure dc_collect
/

create or replace procedure DC_COLLECT
as
cursor current_event is
select a.sid sid,
a.seq# seq#,
a.event event,
a.p1text p1text,
a.p1 p1,
a.p1raw p1raw,
a.p2text p2text,
a.p2 p2,
a.p2raw p2raw,
a.p3text p3text,
a.p3 p3,
a.p3raw p3raw,
a.wait_time wait_time,
a.seconds_in_wait seconds_in_wait,
a.state state,
b.serial# serial#,
b.username username,
b.osuser osuser,
b.paddr paddr,
b.logon_time logon_time,
b.process process,
b.sql_hash_value sql_hash_value,
b.saddr saddr,
b.module module,
b.row_wait_obj# row_wait_obj#,
b.row_wait_file# row_wait_file#,
b.row_wait_block# row_wait_block#,
b.row_wait_row# row_wait_row#,
c.sql_text sql_text
from v$session_wait a,
v$session b,
v$sqltext c
where a.sid = b.sid
and b.sql_hash_value=c.hash_value
and b.username is not null
and b.type <> 'BACKGROUND'
and a.event in (
'db file sequential read',
'db file scattered read',
'latch free',
'direct path read',
'direct path write',
'enqueue',
'library cache pin',
'library cache load lock',
'buffer busy waits',
'free buffer waits');
begin
for c1 in current_event loop
insert into DC_EVENT_DATA
values(
event_seq.nextval,
sysdate,
c1.sid,
c1.seq#,
c1.event,
c1.p1text,
c1.p1,
c1.p1raw,
c1.p2text,
c1.p2,
c1.p2raw,
c1.p3text,
c1.p3,
c1.p3raw,
c1.wait_time,
c1.seconds_in_wait,
c1.state,
c1.serial#,
c1.username,
c1.osuser,
c1.paddr,
c1.logon_time,
c1.process,
c1.sql_hash_value,
c1.saddr,
c1.module,
c1.row_wait_obj#,
c1.row_wait_file#,
c1.row_wait_block#,
c1.row_wait_row#,
c1.sql_text);
commit;
end loop;
end;
/

------------------------------------------
--PROCEDURE:
-- DC_ANALYZE 对收集到的信息,根据sid,开始和结束时间,选取相关纪录,并将相关信息具体化。本存储过程对部分wait event的处理有待细化
--USAGE:
-- Analyze performance data
--ATTENTION:
-- input parameters start_time and
-- end_time must in format
-- 'yyyy-mm-dd hh:mi:ss am'
------------------------------------------
drop procedure dc_analyze
/

create or replace procedure DC_ANALYZE
(start_time varchar2, end_time varchar2, sid_no number)
as
cursor current_event is
select * from dc_event_data
where sid=sid_no
and curr_time>=to_date(start_time,'yyyy-mm-dd hh:mi:ss am')
and curr_time<=to_date(end_time,'yyyy-mm-dd hh:mi:ss am');

v_obj_name varchar2(128);
begin
dbms_output.put_line('USERNAME SID DATE_TIME EVENT OBJECT_NAME HASH_VALUE');
dbms_output.put_line('--------------- --- ---------------------- ------------------------------ --------------- ----------');

for c1 in current_event loop
if c1.event='db file sequential read' or c1.event='db file scattered read' then
select a.object_name into v_obj_name from dba_objects a, sys.x$bh b
where (a.object_id=b.obj or a.data_object_id=b.obj)
and b.file#=c1.p1
and b.dbablk=c1.p2;
elsif c1.event='direct path read' or c1.event='direct path write' or c1.event='buffer busy waits' then
select segment_name into v_obj_name from dba_extents
where c1.p2 between block_id and (block_id+blocks-1)
and file_id=c1.p1;
elsif c1.event='latch free' then
select name into v_obj_name from v$latchname where latch#=c1.p2;
elsif c1.event='' then
select object_name into v_obj_name from dba_objects where object_id=c1.row_wait_obj#;
else
v_obj_name := 'other events';
end if;

dbms_output.put_line(rpad(c1.username,15,' ')||' '||rpad(to_char(c1.sid),3,' ')||' '||to_char(c1.curr_time,'yyyymmdd hh:mi:ss am')||' '||rpad(c1.event,30,' ')||' '||rpad(v_obj_name,15,' ')||' '||to_char(c1.sql_hash_value));
end loop;
end;
/

原创粉丝点击