1. 程式人生 > >Oracle 效能問題排查自動化指令碼

Oracle 效能問題排查自動化指令碼

最近對Oracle資料庫的自動化運維比較感興趣,對資料庫效能問題的自動發現告警功能琢磨了一下。

廢話少說,進入 Oracle Performance troubleshooting automation scripts: Perfbot Maria

功能:定期執行該指令碼,對SQL執行超過n分鐘的SQL語句的等待事件以及相關的執行計劃和SQL monitor的資訊以郵件的形式發給運維者。

主要指令碼:pbm_wait.sh

#!/bin/bash
export ORACLE_SID=$1
export SQL='sqlplus / as sysdba'
export EXEC_MIN=5
export
ORACLE_HOME=/opt/app/oracle/product/11GR2 export PATH=$PATH:$ORACLE_HOME/bin export DIR=/home/oracle/dba/pb_maria #export MY_DATE=`date '+%d%b%y_%k%M'` export LOG=${DIR}/pbm_${ORACLE_SID}_wait.log export RESULT=pbm_${ORACLE_SID}_wait.result export TEMP_RESULT=pbm_${ORACLE_SID}_wait_temp.result export FINAL_RESULT=pbm_wait_${ORACLE_SID}
_final.result export GRACE=pbm_${ORACLE_SID}_grace.log export COUNT=1 export MAIL='mailx -s "Perfbot maria report of DB $ORACLE_SID"' cd $DIR $SQL > /dev/null << EOF spool ${LOG} @wait.sql spool off EOF sed -i '1d;2d;$d' $LOG awk '{if($3>ENVIRON["EXEC_MIN"]) {print $0} }' $LOG > $RESULT for
i in `awk '{print $2}' $RESULT` do array[$COUNT]=$i; COUNT=$(($COUNT+1)); done if [ $COUNT -ne 1 ] then for ((i=1; i<${COUNT}; i++)) do grep -q ${array[$i]} $GRACE; if [ $? -eq 1 ]; then echo ${array[$i]} >> $TEMP_RESULT fi done fi if [[ -e $TEMP_RESULT ]]; then sort -u $TEMP_RESULT > $FINAL_RESULT COUNT=1 for i in `awk '{print $1}' $FINAL_RESULT` do array[$COUNT]=$i COUNT=$(($COUNT+1)); done for ((i=1; i<${COUNT}; i++)) do $SQL > /dev/null << EOF spool ${DIR}/${ORACLE_SID}_${array[$i]}_sql.rpt @sm.sql ${array[$i]} spool off EOF sed -i '1d;$d' ${DIR}/${ORACLE_SID}_${array[i]}_sql.rpt done for ((i=1; i<${COUNT}; i++)) do export MAIL=$MAIL" -a "${DIR}/${ORACLE_SID}_${array[$i]}"_sql.rpt" done export MAIL=$MAIL" [email protected] < "${DIR}/$RESULT" " eval $MAIL mv *.rpt reports/ fi awk '{print $2}' $RESULT > $GRACE mv *.result results/

指令碼使用方法: /home/oracle/dba/pb_maria/pbm_wait.sh

其中 EXEC_MIN 引數控制著多少分鐘以上的SQL會被寫入郵件。

細心的朋友會發現,指令碼中加入了GRACE機制,即上一次告警過的SQL不會接連告警,可能會隔次告警,減少無謂的告警騷擾。

呼叫的sql 指令碼也附上:

wait.sql

set line 220 pages 50000
set heading off
set feedback off
col username for a10
col event for a35
col program for a35
COLUMN elapsed_min FORMAT 999999999.99
select username,sql_id, ROUND(( sysdate - SQL_EXEC_START)*1440 , 2) elapsed_min
,program,event
FROM V$SESSION
WHERE USERNAME IS NOT NULL
AND WAIT_CLASS NOT LIKE 'Idle'
AND SQL_ID IS NOT NULL
AND ROUND(( sysdate - SQL_EXEC_START)*1440 , 2) IS NOT NULL
order by elapsed_min desc;

sm.sql

set pagesize 50000
set long 20000
select dbms_sqltune.report_sql_monitor(SQL_ID=>'&&1',TYPE=>'text') from dual
/

注意點如下:

注意該指令碼必須放在/home/oracle/dba/pb_maria路徑使用;在該路徑下建立results和reports路徑來存放歷史的資訊。

cronjob我設定的是5分鐘一次。

這個指令碼需要Oracle資料庫伺服器能連上網際網路,才能發郵件。如果是私網的機器,則可以考慮加一臺私網公網都在的mail伺服器,將需要發的郵件的資訊傳送到這臺mail伺服器上,然後定時發出郵件。

閱讀原文