一直以來要作性能分析的自動化工做,可是久久沒有動筆,今天索性來更新一版。html
首先我但願獲得的一個基本效果就是後臺去掃描數據庫的DB time,若是超出了閾值,好比這裏我設置的爲400(即DB time爲400%),則會開啓自動診斷的任務。時間範圍是提早一個小時和當前時間。我對已有的腳本作了一些改動,加了一些邏輯,後續還會不斷完善。
sql
DBTIME_THRESHOLD=400
數據庫
DATE=`date '+%Y%m%d'`
BEGIN_HOUR=`date -d"1 hour ago" +"%H"`
END_HOUR=`date +"%H"`
下面的函數會獲得快照級別的DB time狀況
微信
function showsnap
下面的函數會獲得快照級別SQL的DB time佔比圖。
{
sqlplus -s $DB_CONN_STR@$SH_DB_SID <<EOF
break on db_name
set pages 0
set feedback off
set linesize 100
col snapdate format a20
select
begin_snap
,end_snap
,snapdate
,round(((END_INTERVAL_TIME+0)-(BEGIN_INTERVAL_TIME+0 ))*24*60) duration_mins
,round((select round((sum(e.value) -
sum(b.value)) / 1000000 /60,2) dbtime
FROM DBA_HIST_SYS_TIME_MODEL e, DBA_HIST_SYS_TIME_MODEL b
WHERE
e.STAT_NAME = 'DB time'
and b.snap_id=begin_snap
and e.snap_id =end_snap
AND b.STAT_NAME = 'DB time'
group by e.snap_id,b.snap_id)) dbtime
from
(
select
di.db_name db_name
, s.snap_id begin_snap
,lead(s.snap_id ,1,s.snap_id ) over(order by s.end_interval_time ) end_snap
, to_char(s.end_interval_time,'dd Mon YYYY HH24:mi') snapdate
, s.snap_level lvl
,s.end_interval_time
,s.begin_interval_time
from dba_hist_snapshot s
, dba_hist_database_instance di
where
( di.dbid,di.instance_number) in
(select d.dbid dbid
, i.instance_number inst_num
from v\$database d,
v\$instance i)
and di.dbid = s.dbid
and di.instance_number = s.instance_number
and di.startup_time = s.startup_time
and to_char(END_INTERVAL_TIME,'yyyymmdd')='$1'
and EXTRACT(HOUR FROM END_INTERVAL_TIME) between $2-1 and $3+1
order by instance_name, snap_id
);
EOF
}function showsnapsql
下面的函數會基於快照生成AWR報告。
{
sqlplus -s $DB_CONN_STR@$SH_DB_SID <<EOF
break on db_name
set pages 50
set linesize 100
col elapsed_time format a10
col per_total format a10
select snap_id,sql_id,EXECUTIONS_DELTA,max_elapsed elapsed_time,per_total||'%' per_total from
(select distinct snap_id,sql_id,EXECUTIONS_DELTA,trunc(max(ELAPSED_TIME_DELTA) OVER (PARTITION BY snap_id,sql_id )/1000000,0)||'s' max_elapsed,
trunc((max(ELAPSED_TIME_DELTA) OVER (PARTITION BY snap_id,sql_id))/(SUM(ELAPSED_TIME_DELTA) OVER (PARTITION BY snap_id )),2)*100 per_total
from dba_hist_sqlstat where snap_id=$1
order by 5 desc
) where rownum<=5;
EOF
}function genawrhtml
下面的是執行的主方法,固然還有待完善。
{
awr_inputs=`sqlplus -s ${DB_CONN_STR}@${SH_DB_SID} <<EOF
SET FEEDBACK OFF
SET HEAD OFF
SET PAGES 0
select d.dbid||','||i.instance_number||','||$1||','||$2||',0' text
from v\\\$database d,
v\\\$instance i ;
EOF`
sqlplus -s ${DB_CONN_STR}@${SH_DB_SID} <<EOF
set pages 0
set linesize 1500
set termout on;
spool awrrpt_$1_$2.lst
select output from table(dbms_workload_repository.awr_report_html( ${awr_inputs}));
#select output from table(dbms_workload_repository.awr_report_html( `cat awr_inputs.lst`));
spool off;
set termout off;
clear columns sql;
EOF
}#MAIN 主方法
函數
tmp_dbtime_snap=`showsnap $DATE $BEGIN_HOUR $END_HOUR|awk -v dbtime=$DBTIME_THRESHOLD '{if($8>=dbtime) print $0}' |tail -1`
上面的腳本執行很簡單,無需輸入任何參數。就會獲得一個完整的數據報告。後續會經過郵件的形式來發送。後面會繼續補充完善。
echo $tmp_dbtime_snap
dbtime_snap=`echo $tmp_dbtime_snap|awk '{print $1" " $2}'`
echo $dbtime_snap#獲得快照級別的SQL佔用DB time狀況
showsnapsql $dbtime_snap#生成基於DB time的AWR報告
genawrhtml $dbtime_snap
性能
本文分享自微信公衆號 - 楊建榮的學習筆記(jianrong-notes)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。學習