|
#!/bin/bash |
|
# ################################################################################################################################################################## |
|
# Database Server Monitoring Script [dbalarm]. |
|
VER="[8.0]" |
|
SCRIPT_NAME="dbalarm${VER}" |
|
# Features: |
|
# Report ERRORS in DB, ASM Instance, GRID INFRASTRUCTURE, GOLDENGATE and LISTENERS ALERTLOG plus dmesg DEVICE DRIVER OS log. |
|
# Report TABLESPACES, ASM DISKGROUPS and FRA when reach %USED THRESHOLD. |
|
# Report OFFLINE databases. |
|
# Report CPU, FILESYSTEM, TABLESPACES When hit the THRESHOLD. |
|
# Report LONG RUNNING operations/Active SESSIONS on DB when the CPU hits the THRESHOLD. |
|
# Report BLOCKING SESSIONS in the database. |
|
# Report Failed RMAN Backup Jobs. |
|
# Report User Defined DATABASE SERVICES when they go OFFLINE. |
|
# Notes: |
|
# Most of THRESHOLD and CONTROLS in this script located under THRESHOLDS section. Please adjust them to meet your needs. |
|
# ################################################################################################################################################################## |
|
# # # # |
|
# Author: Mahmmoud ADEL # # # # ### |
|
# Created: 22-12-13 # # # # # |
|
# |
|
# Modified: 23-12-13 Handled non exist logs 1run |
|
# 14-05-14 Handled non existance of LOG_DIR directory. |
|
# 18-05-14 Add Filsystem monitoring. |
|
# 19-05-14 Add CPU monitoring. |
|
# 03-12-14 Add Tablespaces monitoring |
|
# 08-09-15 mpstat output change in Linux 6 |
|
# 02-04-16 Using dba_tablespace_usage_metrics To calculate MAXSIZE (11g onwards) Recommended by Satyajit Mohapatra. |
|
# 10-04-16 Add Flash Recovery Area monitoring. |
|
# 10-04-16 Add ASM Disk Groups monitoring. |
|
# 15-09-16 Add "DIG MORE" feature to report.long running operations, queries |
|
# and active sessions on DB side when CPU hits the pre-defined threshold. |
|
# 29-12-16 Enhanced ORACLE_HOME search criteria. |
|
# 02-01-17 Added EXL_DB parameter to allow the user to exclude DBs from having dbalarm script run against. |
|
# 04-05-17 Added the ability to disable Database Down Alert through CHKOFFLINEDB variable. |
|
# 11-05-17 Added the option to exclude tablespace/ASM Diskgroup from monitoring. |
|
# 11-05-17 Tuned the method of reporting OFFLINE databases & checking listener log. |
|
# 20-07-17 Modified COLUMNS env variable to fully display top command output. |
|
# Neutralize login.sql if found in Oracle user home directory due to bugs. |
|
# 19-10-17 Added the function of checking goldengate logfile. |
|
# 11-04-18 Added the feature of monitoring the availability of specific service. |
|
# 28-04-18 Added the function of printing the script progress. |
|
# 30-04-18 Added Paranoid mode, to report EXPORT/IMPORT, ALTER SYSTEM, ALTER DATABASE |
|
# instance STARTUP/SHUTDOWN, other DB Major activities. |
|
# 05-09-18 Modified the wait in seconds column (Blocking Sessions section) for 11gr2 compatibility, |
|
# Added WAIT_FOR_LOCK_THRES threshold to control reporting of sessions blocked for more than N mintes. |
|
# 09-10-18 Enclosing OS Network Failure Statistics (Dropped Packets) whenever TIMOUT error get reported by DB or Listener. |
|
# 15-10-18 Added RMAN Backup Failure Check. [Recommended by: Rahul Malode] |
|
# 22-10-18 Added the Checking of Running RMAN Backup when CPU hit the threshold. |
|
# 01-11-18 Fixing a bug in Monitored Services section. |
|
# 08-11-18 Show the exist restore points if FRA hits the threshold. |
|
# 27-12-18 Checking if another session is running dbalarm script [to avoid performance degradation]. |
|
# 14-01-19 Avoid Monitoring the Services if more than one DB instance is running. |
|
# 15-01-19 Added the feature of monitoring the ASM instance ALERTLOG. |
|
# 15-01-18 Added the feature of monitoring the GRID INFRASTRUCTURE ALERTLOG. |
|
# 16-01-19 Added the feature of monitoring Device Driver OS log "dmesg". |
|
# 04-02-19 Added HTML feature to send the alert in HTML format [If sendmail installed, otherwise will use TEXT format automatically]. |
|
# 24-03-19 Enhanced the DB Service Monitoring Feature to monitor service availability on RAC setup Locally wise. |
|
# 26-03-19 Listing the Master Blocking Sessions When a Blocking Lock get detected. |
|
# 27-03-19 Used RULE Based Optimizer against all "checking locks" queries for a better performance on RAC instances. |
|
# 15-05-19 Replacement of "bc" function for CPU utilization calculation with "awk". |
|
# 20-05-19 When "unable to extend temp segment" error get detected the Email alert will show the top temp space consumers in the DB. |
|
# 09-04-20 Added Monitoring filesystem inodes features. |
|
# 22-08-20 Exclude reporting error "ORA-235 occurred during an un-locked control file" as advised by MOS 2312580.1. |
|
# 21-03-22 Removed IDLE sessions from Locking report and changed the lock wait time from minutes to seconds. |
|
# 03-06-22 Extracting more info related to sessions distribution on the DB when ORA-00020: maximum number of processes () exceeded is detected |
|
# 28-07-22 Enhance the way of finding Goldengate ggserr logfile. |
|
# 29-07-22 Notify the user if WARNING messages detected in the DB ALERTLOG if PARANOID mode is enabled. |
|
# 15-08-22 Modified the Average CPU Check command. |
|
# 07-09-22 Added new feature: Monitor the number of ACTIVE SESSIONS on the DB through ACTIVE_SESSIONS_THRES variable [0 means disable]. |
|
# 19-09-22 Workaround Bugs [28821847 & 24445571] which conceal UNDO Tablespace details on dba_tablespace_usage_metrics on 12c+. |
|
# 19-10-22 Fixing the bug of not showing the server name in the Email subject putting a space between [$. |
|
# 28-10-22 Excluded Patch errors description from the reporting when the alertlog create new log segment. |
|
# 02-11-22 Excluded "ORA-16038 log X sequence# X cannot be archived" from getting reported. |
|
# 08-06-23 Added new feature: cleanup Flashback Logs when FRA reach the defined THRESHOLD, to avail it set FLASHBACK_RESET=Y in THRESHOLDS section. |
|
# |
|
# |
|
# |
|
# ################################################################################################################################################################## |
|
EMAIL="youremail@yourcompany.com" |
|
|
|
export SRV_NAME="`uname -n`" |
|
|
|
# Check if MAIL_LIST parameter is not set notify the user and exit: |
|
case ${EMAIL} in "youremail@yourcompany.com") |
|
echo |
|
echo "******************************************************************" |
|
echo "Buddy! You forgot to edit line# 80 in dbalarm.sh script." |
|
echo "Please replace youremail@yourcompany.com with your E-mail address." |
|
echo "******************************************************************" |
|
echo |
|
echo "Script Terminated !" |
|
echo |
|
exit;; |
|
esac |
|
|
|
# Check if there is another session of dbalarm is running: [Avoid performance impact] |
|
DBALARMCNT=`ps -ef|grep -v grep|grep -v vi|grep dbalarm|wc -l` |
|
if [[ ${DBALARMCNT} -gt 2 ]] |
|
then |
|
echo -e "\033[32;5mdbalarm.sh script is currently running by another session.\033[0m" |
|
echo "" |
|
echo "Please make sure the following sessions are completed before running dbalarm script: [ps -ef|grep -v grep|grep -v vi|grep dbalarm]" |
|
ps -ef|grep -v grep|grep -v vi|grep dbalarm.sh |
|
echo "Script Terminated !" |
|
echo |
|
exit |
|
fi |
|
|
|
# In case your company Emails go through specific SMTP server. Specify it in the below line and UN-HASH it: |
|
#export smtp="mailrelay.mycompany.com:25" # Set it to the SMTP NAME:PORT your company is using. [If exist] |
|
|
|
export MAIL_LIST="${EMAIL}" |
|
#export MAIL_LIST="-r ${SRV_NAME} ${EMAIL}" |
|
|
|
echo |
|
echo "[dbalarm Script Started ...]" |
|
|
|
# ######################### |
|
# THRESHOLDS: |
|
# ######################### |
|
# Modify the THRESHOLDS to the value you prefer: |
|
|
|
HTMLENABLE=Y # Enable HTML Email Format [DB] |
|
FSTHRESHOLD=95 # THRESHOLD FOR FILESYSTEM %USED [OS] |
|
FSITHRESHOLD=95 # THRESHOLD FOR FILESYSTEM INODES %USED [OS] |
|
CPUTHRESHOLD=95 # THRESHOLD FOR CPU %BUSY [OS] |
|
INTERVAL_SEC=2 # mpstat/iostat command Interval duration in seconds for checking the average CPU utilization [OS] |
|
COUNT=3 # mpstat/iostat command number of Intervals for checking the average CPU utilization [OS] |
|
TBSTHRESHOLD=95 # THRESHOLD FOR TABLESPACE %USED [DB] |
|
FRATHRESHOLD=95 # THRESHOLD FOR FRA %USED [DB] |
|
FLASHBACK_RESET=N # Turn FLASHBACK feature OFF & ON, to DELETE all FLASHBACK logs to free up FRA if FRATHRESHOLD is hit [DB] |
|
ASMTHRESHOLD=95 # THRESHOLD FOR ASM DISK GROUPS %USED [DB] |
|
BLOCKTHRESHOLD=1 # THRESHOLD FOR THE NUMBER OF BLOCKED SESSIONS [DB] |
|
WAIT_FOR_LOCK_THRES=60 # THRESHOLD FOR THE LOCK TIME OF BLOCKED SESSIONS IN SECONDS [DB] |
|
CHKRMANBKP=Y # Enable/Disable Checking of RMAN Backup FAILURE. [Default Enabled] [DB] |
|
LAST_MIN_BKP_CHK=5 # REPORT RMAN Backup FAILURE in the last N MINUTES. Should be same as the interval of dbalarm script execution in crontab. [DB] |
|
CHKLISTENER=Y # Enable/Disable Checking Listeners: [Default Enabled] [DB] |
|
CHKOFFLINEDB=Y # Enable/Disable Database Down Alert: [Default Enabled] [DB] |
|
CHKGOLDENGATE=Y # Enable/Disable Goldengate Alert: [Default Enabled] [GG] |
|
CPUDIGMORE=Y # Break down to DB Active sessions when CPU hit the threshold: [RECOMMENDED TO SET=N on VERY BUSY systems] [Default Enabled] [DB] |
|
TIMEOUTDIGMORE=Y # Enable/Disable the display of Network Errors when TIMEOUT error get detected. [Default Enabled] [OS] |
|
TEMPSPACEDIGMORE=Y # Enable/Disable the display of TOP Temporary space consumers when ORA-1652 get detected. [Default Enabled] [DB] |
|
SERVICEMON="" # Monitor Specific Named DB Services. e.g. SERVICEMON="'ORCL_RO','ERP_SRVC','SAP_SERVICE'" [DB] |
|
PARANOIDMODE=N # Enable/Disable Paranoid mode will report more events like export/import, instance shutdown/startup. [Default Disabled] [DB] |
|
CHKASMALERTLOG=Y # Enable/Disable Monitoring ASM instance ALERTLOG. [Default Enabled] [DB] |
|
CHKCLSALERTLOG=Y # Enable/Disable Monitoring GRID INFRASTRUCTURE ALERTLOG. [Default Enabled] [GI] |
|
DEVICEDRIVERLOG=Y # Enable/Disable Check "dmesg" Device Driver log for errors. [Default Enabled] [OS] |
|
REPORT_MAX_SESSIONS=Y # REPORT SESSIONS distribution connected to the DB when ORA-00020: maximum number of processes () exceeded is detected. [DB] |
|
ACTIVE_SESSIONS_THRES=0 # Monitor ACTIVE SESSIONS NUMBER and send notification when crossed [0 Means don't monitor] [Default Disabled]. [DB] |
|
ACTIVE_TIME=5 # Session Active Time in seconds to be considered as ACTIVE SESSION if ACTIVE_SESSIONS_THRES variable is set. [DB] |
|
REMOVE_JUNK_MSGS=Y # Remove JUNK MESSAGES from the DB ALERT log. i.e. "XDB initialized" message resulted by bug 29845449. [DB] |
|
|
|
SQLLINESIZE=200 # The LINE SIZE for SQLPLUS outputs. [DB] |
|
OSLINESIZE=300 # The LINE SIZE for OS Commands outputs. [Default is 167] [OS] |
|
|
|
|
|
# ####################################### |
|
# Excluded INSTANCES: |
|
# ####################################### |
|
# Here you can mention the instances dbalarm will IGNORE and will NOT run against: |
|
# Use pipe "|" as a separator between each instance name. |
|
# e.g. Excluding: -MGMTDB, ASM instances: |
|
EXL_DB="\-MGMTDB|ASM|APX" #Excluded INSTANCES [Will not get reported offline]. |
|
|
|
|
|
# ######################### |
|
# Excluded TABLESPACES: |
|
# ######################### |
|
# Here you can exclude one or more tablespace if you don't want to be alerted when they hit the threshold: |
|
# e.g. to exclude "UNDOTBS1" modify the following variable in this fashion without removing "donotremove" value: |
|
# EXL_TBS="donotremove|UNDOTBS1" |
|
EXL_TBS="donotremove" #Exclude TABLESPACES from being checked. |
|
|
|
|
|
# ######################### |
|
# Excluded ASM Diskgroups: |
|
# ######################### |
|
# Here you can exclude one or more ASM Disk Groups if you do NOT want to be alerted when they hit the threshold: |
|
# e.g. to exclude "FRA" DISKGROUP modify the following variable in this fashion without removing "donotremove" value: |
|
# EXL_DISK_GROUP="donotremove|FRA" Please DO NOT REMOVE/REPLACE the value "dontremove". Good boy ;-) |
|
EXL_DISK_GROUP="donotremove" #Exclude ASM DISKGROUPS from being checked. |
|
|
|
|
|
# ######################### |
|
# Excluded ERRORS: |
|
# ######################### |
|
# Here you will tell the script to ignore the ERRORS you don't want to be alerted when they come in the logs: |
|
# Use pipe "|" between each error. |
|
|
|
EXL_DB_ALERT_ERR="Patch|ORA-2396|ORA-235|ORA-16401|ORA-16038|TNS-00507|TNS-12502|TNS-12560|TNS-12537|TNS-00505" #Excluded ALERTLOG ERRORS [Will not get reported]. |
|
EXL_LSNR_ERR="TNS-00507|TNS-12502|TNS-12560|TNS-12537|TNS-00505" #Excluded LISTENER ERRORS [Will not get reported]. |
|
EXL_GRID_ALERT_ERR="donotremove" #Excluded GRID INFRA ERRORS [Will not get reported]. |
|
EXL_GG_ERR="donotremove" #Excluded GoldenGate ERRORS [Will not get reported]. |
|
EXL_DMESG_ERR=="donotremove|scsmd" #Excluded OS DEVICE DRIVERS ERRORS [Will not get reported]. |
|
|
|
|
|
# ################################# |
|
# Excluded FILESYSTEM/MOUNT POINTS: |
|
# ################################# |
|
# Here you can exclude specific filesystems/mount points from being reported by dbalarm: |
|
# e.g. Excluding: /dev/mapper, /dev/asm mount points: Remember to put a forward Slash / before each Backslash \ |
|
|
|
EXL_FS="\/dev\/mapper\/|\/dev\/asm\/" #Excluded mount points [Will be skipped during the check]. |
|
|
|
|
|
# ######################################## |
|
# The Great Export of the Above Variables: |
|
# ######################################## |
|
|
|
export HTMLENABLE |
|
export FSTHRESHOLD |
|
export FSITHRESHOLD |
|
export CPUTHRESHOLD |
|
export INTERVAL_SEC |
|
export COUNT |
|
export TBSTHRESHOLD |
|
export FRATHRESHOLD |
|
export ASMTHRESHOLD |
|
export BLOCKTHRESHOLD |
|
export WAIT_FOR_LOCK_THRES |
|
export CHKRMANBKP |
|
export LAST_MIN_BKP_CHK |
|
export CHKLISTENER |
|
export CHKOFFLINEDB |
|
export CHKGOLDENGATE |
|
export CPUDIGMORE |
|
export TIMEOUTDIGMORE |
|
export TEMPSPACEDIGMORE |
|
export SERVICEMON |
|
export PARANOIDMODE |
|
export CHKASMALERTLOG |
|
export CHKCLSALERTLOG |
|
export DEVICEDRIVERLOG |
|
export REPORT_MAX_SESSIONS |
|
export SQLLINESIZE |
|
export OSLINESIZE |
|
export EXL_DB |
|
export EXL_TBS |
|
export EXL_DISK_GROUP |
|
export EXL_DB_ALERT_ERR |
|
export EXL_LSNR_ERR |
|
export EXL_GRID_ALERT_ERR |
|
export EXL_GG_ERR |
|
export EXL_DMESG_ERR |
|
export EXL_FS |
|
|
|
# ########################### |
|
# Check the Linux OS version: |
|
# ########################### |
|
export PATH=${PATH}:/usr/local/bin |
|
FILE_NAME=/etc/redhat-release |
|
export FILE_NAME |
|
if [[ -r ${FILE_NAME} ]] |
|
then |
|
LNXVER=`cat /etc/redhat-release | grep -o '[0-9]'|head -1` |
|
export LNXVER |
|
# Workaround df command output bug "`/root/.gvfs': Permission denied" |
|
export DF='df -hPx fuse.gvfs-fuse-daemon' |
|
export DFI='df -iPx fuse.gvfs-fuse-daemon' |
|
else |
|
export DF='df -h' |
|
export DFI='df -o i' |
|
fi |
|
|
|
|
|
# ######################### |
|
# Checking The FILESYSTEM: |
|
# ######################### |
|
echo "" |
|
echo "Checking FILESYSTEM Utilization ..." |
|
|
|
# Report Partitions that reach the threshold of Used Space: |
|
|
|
FSLOG=/tmp/filesystem_DBA_BUNDLE.log |
|
echo "[Reported By ${SCRIPT_NAME} Script]" > ${FSLOG} |
|
echo "" >> ${FSLOG} |
|
${DF} >> ${FSLOG} |
|
${DF} | grep -v "^Filesystem" |awk '{print substr($0, index($0, $2))}'| egrep -v "${EXL_FS}"|awk '{print $(NF-1)" "$NF}'| while read OUTPUT |
|
do |
|
PRCUSED=`echo ${OUTPUT}|awk '{print $1}'|cut -d'%' -f1` |
|
FILESYS=`echo ${OUTPUT}|awk '{print $2}'` |
|
if [[ ${PRCUSED} -ge ${FSTHRESHOLD} ]] |
|
then |
|
echo "Filesystem [ ${FILESYS} ] has reached ${PRCUSED}% of USED space. Reporting the problem." |
|
mail -s "ALARM: Filesystem [ ${FILESYS} ] on Server [ ${SRV_NAME} ] has reached ${PRCUSED}% of USED space" ${MAIL_LIST} < ${FSLOG} |
|
fi |
|
done |
|
|
|
echo "Checking FILESYSTEM Inodes Utilization ..." |
|
FSILOG=/tmp/filesystem_inodes_DBA_BUNDLE.log |
|
echo "[Reported By ${SCRIPT_NAME} Script]" > ${FSILOG} |
|
echo "" >> ${FSILOG} |
|
${DFI} >> ${FSILOG} |
|
${DFI} | grep -v "^Filesystem" | grep -v "not applicable"| awk '{print substr($0, index($0, $2))}'| egrep -v "${EXL_FS}"|awk '{print $(NF-1)" "$NF}'| while read OUTPUT |
|
do |
|
PRCUSED=`echo ${OUTPUT}|awk '{print $1}'|cut -d'%' -f1` |
|
FILESYS=`echo ${OUTPUT}|awk '{print $2}'` |
|
if [[ ${PRCUSED} -ge ${FSITHRESHOLD} ]] |
|
then |
|
echo "INODES of Filesystem [ ${FILESYS} ] has reached ${PRCUSED}%. Reporting the problem." |
|
mail -s "ALARM: INODES of Filesystem [ ${FILESYS} ] on Server [ ${SRV_NAME} ] has reached ${PRCUSED}%" ${MAIL_LIST} < ${FSILOG} |
|
fi |
|
done |
|
|
|
|
|
rm -f ${FSLOG} |
|
rm -f ${FSILOG} |
|
|
|
|
|
# ############################# |
|
# Checking The CPU Utilization: |
|
# ############################# |
|
|
|
# LOGFILE PATH: |
|
# ############ |
|
export PATH=${PATH}:${ORACLE_HOME}/bin |
|
export LOG_DIR=/tmp |
|
|
|
export LOGFILE=${LOG_DIR}/dbalarm.part.log |
|
export CPULOG=${LOG_DIR}/CPU_DBA_BUNDLE.log |
|
export MPSTATLOG=${LOG_DIR}/mpstat_DBA_BUNDLE.log |
|
export VMSTATLOG=${LOG_DIR}/vmstat_DBA_BUNDLE.log |
|
export TOPLOG=${LOG_DIR}/top_DBA_BUNDLE.log |
|
export UPTIMELOG=${LOG_DIR}/uptime_DBA_BUNDLE.log |
|
export CPULOGCONV=${LOG_DIR}/top_processes_DBA_BUNDLE_CONV.log |
|
export CPULOGHTML=${LOG_DIR}/top_processes_DBA_BUNDLE_HTML.log |
|
|
|
touch ${LOGFILE} |
|
|
|
if [[ -r ${CPULOGHTML} ]] |
|
then |
|
rm ${CPULOGHTML} |
|
fi |
|
|
|
# ######################### |
|
# HTML Preparation: |
|
# ######################### |
|
case ${HTMLENABLE} in |
|
y|Y|yes|YES|Yes|ON|On|on) |
|
if [[ -x /usr/sbin/sendmail ]] |
|
then |
|
export SENDMAIL="/usr/sbin/sendmail -t" |
|
export MAILEXEC="echo #" |
|
export HASHHTML="" |
|
export HASHHTMLOS="" |
|
export ENDHASHHTMLOS="" |
|
export HASHNONHTML="--" |
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
export SENDMAILARGS |
|
else |
|
export SENDMAIL="echo #" |
|
export MAILEXEC="mail -s" |
|
export HASHHTML="--" |
|
export HASHHTMLOS="echo #" |
|
export ENDHASHHTMLOS="" |
|
export HASHNONHTML="" |
|
fi |
|
;; |
|
*) |
|
export SENDMAIL="echo #" |
|
export HASHHTML="--" |
|
export HASHHTMLOS="echo #" |
|
export ENDHASHHTMLOS="" |
|
export HASHNONHTML="" |
|
export MAILEXEC="mail -s" |
|
;; |
|
esac |
|
|
|
# SQLPLUS HTML SETTINGS: |
|
#export HTMLTITLE="SET MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type=\"text/css\"> table { background: #eee; } -th { font:bold 10pt Arial,Helvetica,sans-serif; color:#b7ceec; background:#151b54; padding: 5px; align:center; } td { font:10pt Arial,Helvetica,sans-serif; color:Blue; background:#f7f7e7; padding: 5px; align:center; } </style>' TABLE \"border='3' align='left'\" ENTMAP OFF" |
|
|
|
#export HTMLTABLE="SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type=\"text/css\"> table { background: #eee; } -th { font:bold 10pt Arial,Helvetica,sans-serif; color:#b7ceec; background:#151b54; padding: 5px; align:center; } td { font:10pt Arial,Helvetica,sans-serif; color:Blue; background:#f7f7e7; padding: 5px; align:center; } </style>' TABLE \"border='2' align='left'\" ENTMAP OFF" |
|
|
|
echo "Checking CPU Utilization ..." |
|
|
|
# Report CPU Utilization if reach >= CPUTHRESHOLD: |
|
OS_TYPE=`uname -s` |
|
CPUUTLLOG=/tmp/CPULOG_DBA_BUNDLE.log |
|
|
|
# Getting CPU utilization in last 5 seconds: |
|
case `uname` in |
|
Linux ) |
|
export PROGRAM=mpstat |
|
if ! command -v ${PROGRAM} &> /dev/null |
|
then |
|
export PROGRAM=iostat |
|
CPU_REPORT_SECTIONS=`${PROGRAM} -c 1 1 | sed -e 's/,/./g' | tr -s ' ' ';' | sed '/^$/d' | tail -1 | grep ';' -o | wc -l` |
|
if [[ ${CPU_REPORT_SECTIONS} -ge 6 ]] |
|
then |
|
CPU_IDLE=`${PROGRAM} -c ${INTERVAL_SEC} ${COUNT} | sed -e 's/,/./g' | tr -s ' ' ';' | sed '/^$/d' | tail -1| cut -d ";" -f 7` |
|
else |
|
CPU_IDLE=`${PROGRAM} -c ${INTERVAL_SEC} ${COUNT} | sed -e 's/,/./g' | tr -s ' ' ';' | sed '/^$/d' | tail -1| cut -d ";" -f 6` |
|
fi |
|
else |
|
CPU_IDLE=`${PROGRAM} ${INTERVAL_SEC} ${COUNT} | grep 'Average:' | awk '{print $NF}'` |
|
fi |
|
#echo program: $PROGRAM |
|
#echo cpu_idle: $CPU_IDLE |
|
;; |
|
AIX ) CPU_IDLE=`iostat -t $INTERVAL_SEC $NUM_REPORT | sed -e 's/,/./g'|tr -s ' ' ';' | tail -1 | cut -d ";" -f 6` |
|
CPU_COUNT=`lsdev -C|grep Process|wc -l` |
|
;; |
|
SunOS ) CPU_IDLE=`iostat -c $INTERVAL_SEC $NUM_REPORT | tail -1 | awk '{ print $4 }'` |
|
CPU_COUNT=`psrinfo -v|grep "Status of processor"|wc -l` |
|
;; |
|
HP-UX) SAR="/usr/bin/sar" |
|
CPU_COUNT=`lsdev -C|grep Process|wc -l` |
|
if [[ ! -x $SAR ]]; then |
|
echo "sar command is not supported on your environment | CPU Check ignored"; CPU_IDLE=99 |
|
else |
|
CPU_IDLE=`/usr/bin/sar ${INTERVAL_SEC} ${COUNT} | grep Average | awk '{ print $5 }'` |
|
fi |
|
;; |
|
*) echo "uname command is not supported on this environment | CPU Check ignored"; CPU_IDLE=99 |
|
;; |
|
esac |
|
|
|
# Getting Utilized CPU (100-%IDLE): |
|
#CPU_UTL_FLOAT=`echo "scale=2; 100-($CPU_IDLE)"|bc` |
|
CPU_UTL_FLOAT=`awk "BEGIN {print 100-($CPU_IDLE)}"` |
|
|
|
# Convert the average from float number to integer: |
|
CPU_UTL=${CPU_UTL_FLOAT%.*} |
|
|
|
echo "CPU utilizations is: $CPU_UTL" |
|
if [[ -z ${CPU_UTL} ]] |
|
then |
|
CPU_UTL=1 |
|
fi |
|
|
|
# Compare the current CPU utilization with the Threshold: |
|
|
|
if [[ ${CPU_UTL} -ge ${CPUTHRESHOLD} ]] |
|
then |
|
export COLUMNS=${OSLINESIZE} #Increase the COLUMNS width to display the full output [Default is 167] |
|
echo "*******" > ${MPSTATLOG} |
|
echo "mpstat" >> ${MPSTATLOG} |
|
echo "*******" >> ${MPSTATLOG} |
|
mpstat 1 5|tail -7 >> ${MPSTATLOG} |
|
|
|
echo "" > ${VMSTATLOG} |
|
echo "******" >> ${VMSTATLOG} |
|
echo "vmstat" >> ${VMSTATLOG} |
|
echo "******" >> ${VMSTATLOG} |
|
#echo "[If_the_runqueue_number_in_the_(r)_column_exceeds_the_number_of_CPUs_[ ${CPU_COUNT} ]_this_indicates_a_CPU_bottleneck_on_the_system]." >> ${VMSTATLOG} |
|
vmstat 2 5 >> ${VMSTATLOG} |
|
|
|
echo "" > ${TOPLOG} |
|
echo "****************" >> ${TOPLOG} |
|
echo "Top10Processes" >> ${TOPLOG} |
|
echo "****************" >> ${TOPLOG} |
|
top -c -b -n 1|head -17|tail -11 >> ${TOPLOG} |
|
|
|
echo "" > ${UPTIMELOG} |
|
echo "**********" >> ${UPTIMELOG} |
|
echo "Load_Avg" >> ${UPTIMELOG} |
|
echo "**********" >> ${UPTIMELOG} |
|
uptime >> ${UPTIMELOG} |
|
echo "" >> ${UPTIMELOG} |
|
unset COLUMNS #Set COLUMNS width back to the default value |
|
#ps -eo pcpu,pid,user,args | sort -k 1 -r | head -11 >> ${CPULOG} |
|
|
|
cat ${MPSTATLOG} > ${LOGFILE} |
|
cat ${VMSTATLOG} >> ${LOGFILE} |
|
cat ${TOPLOG} >> ${LOGFILE} |
|
cat ${UPTIMELOG} >> ${LOGFILE} |
|
|
|
# Convert OS commands output into HTML format: |
|
export FONTSIZE=4 |
|
export FONT=Arial |
|
export FONTCOLOR=BLUE |
|
#${HASHHTMLOS} awk 'BEGIN { print "<table borader=1>"} {print "<tr>"; for(i=1;i<=NF;i++)print "<td><FONT COLOR=BLACK FACE="Times New Roman" SIZE=${FONTSIZE}>" $i"</FONT></td>"; print "</tr>"} END{print "</table>" }' ${MPSTATLOG} > ${CPULOGCONV} ${ENDHASHHTMLOS} |
|
${HASHHTMLOS} awk 'BEGIN { print "<table borader=1>"} {print "<tr>"; for(i=1;i<=NF;i++)print "<td><FONT COLOR=BROWN FACE="Times New Roman" SIZE=${FONTSIZE}>" $i"</FONT></td>"; print "</tr>"} END{print "</table>" }' ${MPSTATLOG} > ${CPULOGCONV} ${ENDHASHHTMLOS} |
|
${HASHHTMLOS} awk 'BEGIN { print "<table borader=1>"} {print "<tr>"; for(i=1;i<=NF;i++)print "<td><FONT COLOR=BROWN FACE="Times New Roman" SIZE=${FONTSIZE}>" $i"</FONT></td>"; print "</tr>"} END{print "</table>" }' ${VMSTATLOG} >> ${CPULOGCONV} ${ENDHASHHTMLOS} |
|
${HASHHTMLOS} awk 'BEGIN { print "<table borader=1>"} {print "<tr>"; for(i=1;i<=NF;i++)print "<td><FONT COLOR=BROWN FACE="Times New Roman" SIZE=${FONTSIZE}>" $i"</FONT></td>"; print "</tr>"} END{print "</table>" }' ${TOPLOG} >> ${CPULOGCONV} ${ENDHASHHTMLOS} |
|
${HASHHTMLOS} awk 'BEGIN { print "<table borader=1>"} {print "<tr>"; for(i=1;i<=NF;i++)print "<td><FONT COLOR=BROWN FACE="Times New Roman" SIZE=${FONTSIZE}>" $i"</FONT></td>"; print "</tr>"} END{print "</table>" }' ${UPTIMELOG} >> ${CPULOGCONV} ${ENDHASHHTMLOS} |
|
|
|
#${HASHHTMLOS} cat /dev/null > ${CPULOGHTML} ${ENDHASHHTMLOS} |
|
${HASHHTMLOS} cp ${CPULOGCONV} ${LOGFILE} |
|
|
|
# Check ACTIVE SESSIONS on DB side: |
|
echo "[CPU Utilization Crossed The Threshold [ ${CPU_UTL}% ]. Sending Email Alert ...]" |
|
for ORACLE_SID in $( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|awk '{print $NF}'|sed -e 's/ora_pmon_//g'|grep -v sed|grep -v "s///g" ) |
|
do |
|
export ORACLE_SID |
|
|
|
# Getting ORACLE_HOME: |
|
# ################### |
|
ORA_USER=`ps -ef|grep ${ORACLE_SID}|grep pmon|grep -v grep|egrep -v ${EXL_DB}|grep -v "\-MGMTDB"|awk '{print $1}'|tail -1` |
|
USR_ORA_HOME=`grep -i "^${ORA_USER}:" /etc/passwd| cut -f6 -d ':'|tail -1` |
|
|
|
# SETTING ORATAB: |
|
if [[ -r /etc/oratab ]] |
|
then |
|
ORATAB=/etc/oratab |
|
export ORATAB |
|
## If OS is Solaris: |
|
elif [[ -r /var/opt/oracle/oratab ]] |
|
then |
|
ORATAB=/var/opt/oracle/oratab |
|
export ORATAB |
|
fi |
|
|
|
# ATTEMPT1: Get ORACLE_HOME using pwdx command: |
|
export PGREP=`which pgrep` |
|
export PWDX=`which pwdx` |
|
if [[ -x ${PGREP} ]] && [[ -x ${PWDX} ]] |
|
then |
|
PMON_PID=`pgrep -lf _pmon_${ORACLE_SID}|awk '{print $1}'` |
|
export PMON_PID |
|
ORACLE_HOME=`pwdx ${PMON_PID} 2>/dev/null|awk '{print $NF}'|sed -e 's/\/dbs//g'` |
|
export ORACLE_HOME |
|
fi |
|
|
|
# ATTEMPT2: If ORACLE_HOME not found get it from oratab file: |
|
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]] |
|
then |
|
## If OS is Linux: |
|
if [[ -r /etc/oratab ]] |
|
then |
|
ORATAB=/etc/oratab |
|
ORACLE_HOME=`grep -v '^\#' ${ORATAB} | grep -v '^$'| grep -i "^${ORACLE_SID}:" | perl -lpe'$_ = reverse' | cut -f3 | perl -lpe'$_ = reverse' |cut -f2 -d':'` |
|
export ORACLE_HOME |
|
|
|
## If OS is Solaris: |
|
elif [[ -r /var/opt/oracle/oratab ]] |
|
then |
|
ORATAB=/var/opt/oracle/oratab |
|
ORACLE_HOME=`grep -v '^\#' ${ORATAB} | grep -v '^$'| grep -i "^${ORACLE_SID}:" | perl -lpe'$_ = reverse' | cut -f3 | perl -lpe'$_ = reverse' |cut -f2 -d':'` |
|
export ORACLE_HOME |
|
fi |
|
fi |
|
|
|
# ATTEMPT3: If ORACLE_HOME is in /etc/oratab, use dbhome command: |
|
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]] |
|
then |
|
ORACLE_HOME=`dbhome "${ORACLE_SID}"` |
|
export ORACLE_HOME |
|
fi |
|
|
|
# ATTEMPT4: If ORACLE_HOME is still not found, search for the environment variable: [Less accurate] |
|
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]] |
|
then |
|
ORACLE_HOME=`env|grep -i ORACLE_HOME|sed -e 's/ORACLE_HOME=//g'` |
|
export ORACLE_HOME |
|
fi |
|
|
|
# ATTEMPT5: If ORACLE_HOME is not found in the environment search user's profile: [Less accurate] |
|
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]] |
|
then |
|
ORACLE_HOME=`grep -h 'ORACLE_HOME=\/' ${USR_ORA_HOME}/.bash_profile ${USR_ORA_HOME}/.*profile | perl -lpe'$_ = reverse' |cut -f1 -d'=' | perl -lpe'$_ = reverse'|tail -1` |
|
export ORACLE_HOME |
|
fi |
|
|
|
# ATTEMPT6: If ORACLE_HOME is still not found, search for orapipe: [Least accurate] |
|
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]] |
|
then |
|
if [[ -x /usr/bin/locate ]] |
|
then |
|
ORACLE_HOME=`locate -i orapipe|head -1|sed -e 's/\/bin\/orapipe//g'` |
|
export ORACLE_HOME |
|
fi |
|
fi |
|
|
|
# TERMINATE: If all above attempts failed to get ORACLE_HOME location, EXIT the script: |
|
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]] |
|
then |
|
echo "Please export ORACLE_HOME variable in your .bash_profile file under oracle user home directory in order to get this script to run properly" |
|
echo "e.g." |
|
echo "export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1" |
|
exit |
|
fi |
|
|
|
export LD_LIBRARY_PATH=${ORACLE_HOME}/lib |
|
|
|
|
|
# Check Long Running Transactions if CPUDIGMORE=Y: |
|
case ${CPUDIGMORE} in |
|
y|Y|yes|YES|Yes|ON|On|on) |
|
DBCPUDIGMORE=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF |
|
set linesize ${SQLLINESIZE} |
|
|
|
-- Enable HTML color format: |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
|
|
SPOOL ${CPULOGHTML} APPEND |
|
prompt |
|
|
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='27%' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT SESSIONS STATUS: [Local Instance | ${ORACLE_SID} ] |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 1000 |
|
|
|
${HASHNONHTML} PROMPT *************** |
|
|
|
${HASHNONHTML} PROMPT SESSIONS STATUS: [Local Instance | ${ORACLE_SID} ] |
|
${HASHNONHTML} PROMPT *************** |
|
|
|
set pages 0 |
|
select 'ACTIVE: '||count(*) from v\$session where USERNAME is not null and status='ACTIVE'; |
|
select 'INACTIVE: '||count(*) from v\$session where USERNAME is not null and status='INACTIVE'; |
|
select 'BACKGROUND: '||count(*) from v\$session where USERNAME is null; |
|
select 'ALL: '||count(*) from v\$session; |
|
|
|
${HASHNONHTML} PROMPT |
|
|
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='25%' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT ACTIVE SESSIONS ON INSTANCE: [ ${ORACLE_SID} ] |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='2' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} SET PAGES 1000 |
|
|
|
--${HASHHTML} PROMPT |
|
|
|
${HASHNONHTML} PROMPT *************************** |
|
|
|
${HASHNONHTML} PROMPT ACTIVE SESSIONS ON INSTANCE: [ ${ORACLE_SID} ] |
|
${HASHNONHTML} PROMPT *************************** |
|
|
|
set feedback off linesize ${SQLLINESIZE} pages 1000 |
|
col event for a24 |
|
col "STATUS|WAIT_STATE|TIME_WAITED" for a31 |
|
col "USER|OSID|SID,SER|MACHN|MODULE" for a65 |
|
col "ST|WA_ST|WAITD|ACT_SINC|LOGIN" for a44 |
|
col "SQLID | FULL_SQL_TEXT" for a75 |
|
col "CURR_SQLID" for a35 |
|
col "I|BLKD_BY" for a9 |
|
select |
|
substr(s.USERNAME||'| '||p.spid||'|'||s.sid||','||s.serial#||' |'||substr(s.MACHINE,1,22)||'|'||substr(s.MODULE,1,18),1,65)"USER|OSID|SID,SER|MACHN|MODULE" |
|
,substr(s.status||'|'||w.state||'|'||round(w.WAIT_TIME_MICRO/1000000)||'|'||LAST_CALL_ET||'|'||to_char(LOGON_TIME,'ddMon'),1,44) "ST|WA_ST|WAITD|ACT_SINC|LOGIN" |
|
,substr(w.event,1,24) "EVENT" |
|
--,substr(w.event,1,30)"EVENT",s.SQL_ID ||' | '|| Q.SQL_FULLTEXT "SQLID | FULL_SQL_TEXT" |
|
,s.SQL_ID "CURRENT SQLID" |
|
,s.FINAL_BLOCKING_INSTANCE||'|'||s.FINAL_BLOCKING_SESSION "I|BLKD_BY" |
|
from v\$session s, v\$session_wait w, v\$process p |
|
where s.USERNAME is not null |
|
and s.sid=w.sid |
|
and p.addr = s.paddr |
|
and s.STATUS='ACTIVE' |
|
and w.EVENT NOT IN ('SQL*Net message from client','class slave wait','Streams AQ: waiting for messages in the queue','Streams capture: waiting for archive log' |
|
,'Streams AQ: waiting for time management or cleanup tasks','PL/SQL lock timer','rdbms ipc message') |
|
order by "I|BLKD_BY" desc,"CURRENT SQLID",w.event,"USER|OSID|SID,SER|MACHN|MODULE","ST|WA_ST|WAITD|ACT_SINC|LOGIN" desc; |
|
|
|
--${HASHHTML} PROMPT <br> |
|
${HASHNONHTML} PROMPT |
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='40%' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT Long Running Operations On Database: [ ${ORACLE_SID} ] |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='2' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 1000 |
|
|
|
${HASHNONHTML} PROMPT *********************************** |
|
|
|
${HASHNONHTML} PROMPT Long Running Operations On Instance: [ ${ORACLE_SID} ] |
|
${HASHNONHTML} PROMPT *********************************** |
|
|
|
set linesize ${SQLLINESIZE} pages 1000 |
|
col OPERATION for a21 |
|
col "%DONE" for 999.999 |
|
col "STARTED|MIN_ELAPSED|REMAIN" for a30 |
|
col MESSAGE for a80 |
|
col "USERNAME| SID,SERIAL#" for a26 |
|
select USERNAME||'| '||SID||','||SERIAL# "USERNAME| SID,SERIAL#",SQL_ID |
|
--,OPNAME OPERATION |
|
,round(SOFAR/TOTALWORK*100,2) "%DONE" |
|
,to_char(START_TIME,'DD-Mon HH24:MI')||'| '||trunc(ELAPSED_SECONDS/60)||'|'||trunc(TIME_REMAINING/60) "STARTED|MIN_ELAPSED|REMAIN" ,MESSAGE |
|
from v\$session_longops |
|
where SOFAR/TOTALWORK*100 <>'100' |
|
and TOTALWORK <> '0' |
|
order by "STARTED|MIN_ELAPSED|REMAIN" desc, "USERNAME| SID,SERIAL#"; |
|
|
|
PROMPT |
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='42%' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT Sessions Active Since More Than 1 Hour On Database: [ ${ORACLE_SID} ] |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='2' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 1000 |
|
|
|
${HASHNONHTML} PROMPT ************************************************** |
|
|
|
${HASHNONHTML} PROMPT Sessions Active Since More Than 1 Hour On Instance: [ ${ORACLE_SID} ] |
|
${HASHNONHTML} PROMPT ************************************************** |
|
|
|
set lines ${SQLLINESIZE} |
|
col module for a30 |
|
col DURATION_HOURS for 99999.9 |
|
col STARTED_AT for a13 |
|
col "USERNAME| SID,SERIAL#" for a30 |
|
col "SQL_ID | SQL_TEXT" for a120 |
|
select username||'| '||sid ||','|| serial# "USERNAME| SID,SERIAL#",substr(MODULE,1,30) "MODULE", to_char(sysdate-last_call_et/24/60/60,'DD-MON HH24:MI') STARTED_AT, |
|
last_call_et/60/60 "DURATION_HOURS" |
|
--,SQL_ID ||' | '|| (select SQL_FULLTEXT from v\$sql where address=sql_address) "SQL_ID | SQL_TEXT" |
|
,SQL_ID |
|
from v\$session where |
|
username is not null |
|
and module is not null |
|
-- 1 is the number of hours |
|
and last_call_et > 60*60*1 |
|
and status = 'ACTIVE'; |
|
|
|
PROMPT |
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='27%' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT RUNNING JOBS On Database: [ ${ORACLE_SID} ] |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='2' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 1000 |
|
|
|
${HASHNONHTML} PROMPT ************************ |
|
|
|
${HASHNONHTML} PROMPT RUNNING JOBS On Instance: [ ${ORACLE_SID} ] |
|
${HASHNONHTML} PROMPT ************************ |
|
|
|
col INS for 999 |
|
col "JOB_NAME|OWNER|SPID|SID" for a55 |
|
col ELAPSED_TIME for a17 |
|
col CPU_USED for a17 |
|
col "WAIT_SEC" for 9999999999 |
|
col WAIT_CLASS for a15 |
|
col "BLKD_BY" for 9999999 |
|
col "WAITED|WCLASS|EVENT" for a45 |
|
select j.RUNNING_INSTANCE INS,j.JOB_NAME ||' | '|| j.OWNER||' |'||SLAVE_OS_PROCESS_ID||'|'||j.SESSION_ID"JOB_NAME|OWNER|SPID|SID" |
|
,s.FINAL_BLOCKING_SESSION "BLKD_BY",ELAPSED_TIME,CPU_USED |
|
,substr(s.SECONDS_IN_WAIT||'|'||s.WAIT_CLASS||'|'||s.EVENT,1,45) "WAITED|WCLASS|EVENT",S.SQL_ID |
|
from dba_scheduler_running_jobs j, gv\$session s |
|
where j.RUNNING_INSTANCE=S.INST_ID(+) |
|
and j.SESSION_ID=S.SID(+) |
|
order by INS,"JOB_NAME|OWNER|SPID|SID",ELAPSED_TIME; |
|
|
|
SPOOL OFF |
|
EOF |
|
) |
|
|
|
BACKUPJOBCOUNTRAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set pages 0 feedback off; |
|
prompt |
|
SELECT count(*) FROM v\$rman_backup_job_details WHERE status like 'RUNNING%'; |
|
exit; |
|
EOF |
|
) |
|
BACKUPJOBCOUNT=`echo ${BACKUPJOBCOUNTRAW}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'` |
|
|
|
if [[ ${BACKUPJOBCOUNT} -gt 0 ]] |
|
then |
|
BACKUPJOBOUTPUT=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF |
|
set pages 0 termout off echo off feedback off linesize ${SQLLINESIZE} |
|
col name for A40 |
|
EXEC DBMS_SESSION.set_identifier('${SCRIPT_NAME}'); |
|
set feedback off |
|
|
|
-- Enable HTML color format: |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
|
|
SPOOL ${CPULOGHTML} APPEND |
|
|
|
prompt |
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='20%' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT Running Backups: [ ${ORACLE_SID} ] |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='2' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 1000 |
|
|
|
${HASHNONHTML} prompt *************** |
|
|
|
${HASHNONHTML} Prompt Running Backups: [ ${ORACLE_SID} ] |
|
${HASHNONHTML} prompt *************** |
|
|
|
set feedback off linesize ${SQLLINESIZE} pages 1000 |
|
col START_TIME for a15 |
|
col END_TIME for a15 |
|
col TIME_TAKEN_DISPLAY for a10 |
|
col INPUT_BYTES_DISPLAY heading "DATA SIZE" for a10 |
|
col OUTPUT_BYTES_DISPLAY heading "Backup Size" for a11 |
|
col OUTPUT_BYTES_PER_SEC_DISPLAY heading "Speed/s" for a10 |
|
col output_device_type heading "Device_TYPE" for a11 |
|
SELECT to_char (start_time,'DD-MON-YY HH24:MI') START_TIME, to_char(end_time,'DD-MON-YY HH24:MI') END_TIME, time_taken_display, status, |
|
input_type, output_device_type,input_bytes_display, output_bytes_display, output_bytes_per_sec_display,COMPRESSION_RATIO COMPRESS_RATIO |
|
FROM v\$rman_backup_job_details |
|
WHERE status like 'RUNNING%'; |
|
|
|
SPOOL OFF |
|
exit; |
|
EOF |
|
) |
|
fi |
|
echo "" |
|
;; |
|
esac |
|
done |
|
echo "CPU utilization has hit the threshold. Reporting the problem." |
|
|
|
cat ${CPULOGHTML} >> ${LOGFILE} |
|
export SRV_NAME="`uname -n`" |
|
|
|
export MSGSUBJECT="ALERT: CPU Utilization on Server [ ${SRV_NAME} ] has reached [ ${CPU_UTL}% ]" |
|
echo ${MSGSUBJECT} |
|
|
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
|
|
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE} |
|
echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL} |
|
fi |
|
|
|
rm -f ${CPUUTLLOG} |
|
rm -f ${CPULOG} |
|
|
|
echo "CPU CHECK Completed." |
|
|
|
|
|
# ######################### |
|
# Getting ORACLE_SID: |
|
# ######################### |
|
# Exit with sending Alert mail if No DBs are running: |
|
INS_COUNT=$( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|wc -l ) |
|
if [[ ${INS_COUNT} -eq 0 ]] |
|
then |
|
echo "[Reported By ${SCRIPT_NAME} Script]" > /tmp/oracle_processes_DBA_BUNDLE.log |
|
echo " " >> /tmp/oracle_processes_DBA_BUNDLE.log |
|
echo "Current running INSTANCES on server [ ${SRV_NAME} ]:" >> /tmp/oracle_processes_DBA_BUNDLE.log |
|
echo "***************************************************" >> /tmp/oracle_processes_DBA_BUNDLE.log |
|
ps -ef|grep -v grep|grep pmon >> /tmp/oracle_processes_DBA_BUNDLE.log |
|
echo " " >> /tmp/oracle_processes_DBA_BUNDLE.log |
|
echo "Current running LISTENERS on server [ ${SRV_NAME} ]:" >> /tmp/oracle_processes_DBA_BUNDLE.log |
|
echo "***************************************************" >> /tmp/oracle_processes_DBA_BUNDLE.log |
|
ps -ef|grep -v grep|grep tnslsnr >> /tmp/oracle_processes_DBA_BUNDLE.log |
|
mail -s "ALARM: No Databases Are Running on Server: ${SRV_NAME} !!!" ${MAIL_LIST} < /tmp/oracle_processes_DBA_BUNDLE.log |
|
rm -f /tmp/oracle_processes_DBA_BUNDLE.log |
|
exit |
|
fi |
|
|
|
# Avoid Monitoring Running Services if more than one DB instance is running: |
|
if [[ ${INS_COUNT} -gt 1 ]] |
|
then |
|
export SERVICEMON="" |
|
fi |
|
|
|
|
|
# ######################### |
|
# Setting ORACLE_SID: |
|
# ######################### |
|
for ORACLE_SID in $( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|awk '{print $NF}'|sed -e 's/ora_pmon_//g'|grep -v sed|grep -v "s///g" ) |
|
do |
|
export ORACLE_SID |
|
echo "" |
|
echo "[Checking ${ORACLE_SID} Database ...]" |
|
|
|
|
|
# ######################### |
|
# Getting ORACLE_HOME |
|
# ######################### |
|
ORA_USER=`ps -ef|grep ${ORACLE_SID}|grep pmon|grep -v grep|egrep -v ${EXL_DB}|grep -v "\-MGMTDB"|awk '{print $1}'|tail -1` |
|
USR_ORA_HOME=`grep -i "^${ORA_USER}:" /etc/passwd| cut -f6 -d ':'|tail -1` |
|
|
|
# SETTING ORATAB: |
|
if [[ -r /etc/oratab ]] |
|
then |
|
ORATAB=/etc/oratab |
|
export ORATAB |
|
## If OS is Solaris: |
|
elif [[ -r /var/opt/oracle/oratab ]] |
|
then |
|
ORATAB=/var/opt/oracle/oratab |
|
export ORATAB |
|
fi |
|
|
|
# ATTEMPT1: Get ORACLE_HOME using pwdx command: |
|
export PGREP=`which pgrep` |
|
export PWDX=`which pwdx` |
|
if [[ -x ${PGREP} ]] && [[ -x ${PWDX} ]] |
|
then |
|
PMON_PID=`pgrep -lf _pmon_${ORACLE_SID}|awk '{print $1}'` |
|
export PMON_PID |
|
ORACLE_HOME=`pwdx ${PMON_PID} 2>/dev/null|awk '{print $NF}'|sed -e 's/\/dbs//g'` |
|
export ORACLE_HOME |
|
fi |
|
|
|
|
|
# ATTEMPT2: If ORACLE_HOME not found get it from oratab file: |
|
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]] |
|
then |
|
## If OS is Linux: |
|
if [[ -r /etc/oratab ]] |
|
then |
|
ORATAB=/etc/oratab |
|
ORACLE_HOME=`grep -v '^\#' ${ORATAB} | grep -v '^$'| grep -i "^${ORACLE_SID}:" | perl -lpe'$_ = reverse' | cut -f3 | perl -lpe'$_ = reverse' |cut -f2 -d':'` |
|
export ORACLE_HOME |
|
|
|
## If OS is Solaris: |
|
elif [[ -r /var/opt/oracle/oratab ]] |
|
then |
|
ORATAB=/var/opt/oracle/oratab |
|
ORACLE_HOME=`grep -v '^\#' ${ORATAB} | grep -v '^$'| grep -i "^${ORACLE_SID}:" | perl -lpe'$_ = reverse' | cut -f3 | perl -lpe'$_ = reverse' |cut -f2 -d':'` |
|
export ORACLE_HOME |
|
fi |
|
fi |
|
|
|
# ATTEMPT3: If ORACLE_HOME is in /etc/oratab, use dbhome command: |
|
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]] |
|
then |
|
ORACLE_HOME=`dbhome "${ORACLE_SID}"` |
|
export ORACLE_HOME |
|
fi |
|
|
|
# ATTEMPT4: If ORACLE_HOME is still not found, search for the environment variable: [Less accurate] |
|
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]] |
|
then |
|
ORACLE_HOME=`env|grep -i ORACLE_HOME|sed -e 's/ORACLE_HOME=//g'` |
|
export ORACLE_HOME |
|
fi |
|
|
|
# ATTEMPT5: If ORACLE_HOME is not found in the environment search user's profile: [Less accurate] |
|
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]] |
|
then |
|
ORACLE_HOME=`grep -h 'ORACLE_HOME=\/' ${USR_ORA_HOME}/.bash_profile ${USR_ORA_HOME}/.*profile | perl -lpe'$_ = reverse' |cut -f1 -d'=' | perl -lpe'$_ = reverse'|tail -1` |
|
export ORACLE_HOME |
|
fi |
|
|
|
# ATTEMPT6: If ORACLE_HOME is still not found, search for orapipe: [Least accurate] |
|
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]] |
|
then |
|
if [[ -x /usr/bin/locate ]] |
|
then |
|
ORACLE_HOME=`locate -i orapipe|head -1|sed -e 's/\/bin\/orapipe//g'` |
|
export ORACLE_HOME |
|
fi |
|
fi |
|
|
|
# TERMINATE: If all above attempts failed to get ORACLE_HOME location, EXIT the script: |
|
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]] |
|
then |
|
echo "Please export ORACLE_HOME variable in your .bash_profile file under oracle user home directory in order to get this script to run properly" |
|
echo "e.g." |
|
echo "export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1" |
|
mail -s "dbalarm script on Server [ ${SRV_NAME} ] failed to locate ORACLE_HOME for SID [ ${ORACLE_SID} ], Please export ORACLE_HOME variable in your .bash_profile file under oracle user home directory" ${MAIL_LIST} < /dev/null |
|
exit |
|
fi |
|
|
|
|
|
# ############################# |
|
# Getting hostname in lowercase: |
|
# ############################# |
|
HOSTNAMELOWER=$( echo "`hostname --short`"| tr '[A-Z]' '[a-z]' ) |
|
export HOSTNAMELOWER |
|
|
|
|
|
# ######################## |
|
# Getting GRID_HOME: |
|
# ######################## |
|
|
|
CHECK_OCSSD=`ps -ef|grep 'ocssd.bin'|grep -v grep|wc -l` |
|
CHECK_CRSD=`ps -ef|grep 'crsd.bin'|grep -v grep|wc -l` |
|
|
|
if [[ ${CHECK_OCSSD} -gt 0 ]] |
|
then |
|
GRID_HOME=`ps -ef|grep 'ocssd.bin'|grep -v grep|awk '{print $NF}'|sed -e 's/\/bin\/ocssd.bin//g'|grep -v sed|grep -v "//g"|tail -1` |
|
export GRID_HOME |
|
|
|
if [[ ! -d ${GRID_HOME} ]] |
|
then |
|
ASM_INSTANCE_NAME=`ps -ef|grep pmon|grep -v grep|grep asm_pmon_|awk '{print $NF}'|sed -e 's/asm_pmon_//g'|grep -v sed|grep -v "s///g"|tail -1` |
|
GRID_HOME=`dbhome ${ASM_INSTANCE_NAME}` |
|
export GRID_HOME |
|
fi |
|
|
|
|
|
# ######################## |
|
# Getting GRID_BASE: |
|
# ######################## |
|
|
|
# Locating GRID_BASE: |
|
|
|
GRID_BASE=`cat ${GRID_HOME}/crs/install/crsconfig_params|grep ^ORACLE_BASE|tail -1|awk '{print $NF}'|sed -e 's/ORACLE_BASE=//g'` |
|
export GRID_BASE |
|
|
|
if [[ ! -d ${GRID_BASE} ]] |
|
then |
|
GRID_BASE=`cat ${GRID_HOME}/crs/utl/appvipcfg|grep ^ORACLE_BASE|tail -1|awk '{print $NF}'|sed -e 's/ORACLE_BASE=//g'` |
|
export GRID_BASE |
|
fi |
|
|
|
if [[ ! -d ${GRID_BASE} ]] |
|
then |
|
GRID_BASE=`cat ${GRID_HOME}/install/envVars.properties|grep ^ORACLE_BASE|tail -1|awk '{print $NF}'|sed -e 's/ORACLE_BASE=//g'` |
|
export GRID_BASE |
|
fi |
|
fi |
|
|
|
|
|
# ######################### |
|
# Variables: |
|
# ######################### |
|
export PATH=${PATH}:${ORACLE_HOME}/bin |
|
export LOG_DIR=${USR_ORA_HOME}/BUNDLE_Logs |
|
mkdir -p ${LOG_DIR} |
|
chown -R ${ORA_USER} ${LOG_DIR} |
|
chmod -R go-rwx ${LOG_DIR} |
|
|
|
if [[ ! -w ${LOG_DIR} ]] |
|
then |
|
mkdir -p /tmp/BUNDLE_Logs |
|
export LOG_DIR=/tmp/BUNDLE_Logs |
|
chown -R ${ORA_USER} ${LOG_DIR} |
|
chmod -R go-rwx ${LOG_DIR} |
|
fi |
|
|
|
touch ${LOG_DIR}/dbalarm.part.log |
|
export LOGFILE=${LOG_DIR}/dbalarm.part.log |
|
|
|
|
|
# ######################### |
|
# HTML Preparation: |
|
# ######################### |
|
case ${HTMLENABLE} in |
|
y|Y|yes|YES|Yes|ON|On|on) |
|
if [[ -x /usr/sbin/sendmail ]] |
|
then |
|
export SENDMAIL="/usr/sbin/sendmail -t" |
|
export MAILEXEC="echo #" |
|
export HASHHTML="" |
|
export HASHNONHTML="--" |
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
export SENDMAILARGS |
|
else |
|
export SENDMAIL="echo #" |
|
export MAILEXEC="mail -s" |
|
export HASHHTML="--" |
|
export HASHNONHTML="" |
|
fi |
|
;; |
|
*) |
|
export SENDMAIL="echo #" |
|
export HASHHTML="--" |
|
export HASHNONHTML="" |
|
export MAILEXEC="mail -s" |
|
;; |
|
esac |
|
|
|
|
|
#export HTMLTITLE="SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type=\"text/css\"> table { background: #eee; } -th { font:bold 10pt Arial,Helvetica,sans-serif; color:#b7ceec; background:#151b54; padding: 5px; align:center; } td { font:10pt Arial,Helvetica,sans-serif; color:Blue; background:#f7f7e7; padding: 5px; align:center; } </style>' TABLE \"border='3' align='left'\" ENTMAP OFF" |
|
|
|
#export HTMLTABLE="SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type=\"text/css\"> table { background: #eee; } -th { font:bold 10pt Arial,Helvetica,sans-serif; color:#b7ceec; background:#151b54; padding: 5px; align:center; } td { font:10pt Arial,Helvetica,sans-serif; color:Blue; background:#f7f7e7; padding: 5px; align:center; } </style>' TABLE \"border='2' align='left'\" ENTMAP OFF" |
|
|
|
# ########################## |
|
# Neutralize login.sql file: [Bug Fix] |
|
# ########################## |
|
# Existance of login.sql file under Oracle user Linux home directory eliminates many functions during the execution of this script via crontab: |
|
|
|
if [[ -r ${USR_ORA_HOME}/login.sql ]] |
|
then |
|
echo "login.sql file found and will be neutralized." |
|
mv ${USR_ORA_HOME}/login.sql ${USR_ORA_HOME}/login.sql_NeutralizedBy${SCRIPT_NAME} |
|
fi |
|
|
|
|
|
# ######################## |
|
# Getting ORACLE_BASE: |
|
# ######################## |
|
# Get ORACLE_BASE from user's profile if it EMPTY: |
|
|
|
if [[ ! -d "${ORACLE_BASE}" ]] |
|
then |
|
ORACLE_BASE=`cat ${ORACLE_HOME}/install/envVars.properties|grep ^ORACLE_BASE|tail -1|awk '{print $NF}'|sed -e 's/ORACLE_BASE=//g'` |
|
export ORACLE_BASE |
|
fi |
|
|
|
if [[ ! -d "${ORACLE_BASE}" ]] |
|
then |
|
ORACLE_BASE=`grep -h 'ORACLE_BASE=\/' ${USR_ORA_HOME}/.bash* ${USR_ORA_HOME}/.*profile | perl -lpe'$_ = reverse' |cut -f1 -d'=' | perl -lpe'$_ = reverse'|tail -1` |
|
export ORACLE_BASE |
|
fi |
|
|
|
|
|
# ######################### |
|
# Getting DB_NAME: |
|
# ######################### |
|
DB_NAME_RAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set pages 0 feedback off lines 1000; |
|
prompt |
|
SELECT name from v\$database; |
|
exit; |
|
EOF |
|
) |
|
# Getting DB_NAME in Uppercase & Lowercase: |
|
DB_NAME_UPPER=`echo ${DB_NAME_RAW}| perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'` |
|
DB_NAME_LOWER=$( echo "${DB_NAME_UPPER}" | tr -s '[:upper:]' '[:lower:]' ) |
|
export DB_NAME_UPPER |
|
export DB_NAME_LOWER |
|
|
|
|
|
# ######################### |
|
# Getting DB_UNQ_NAME: |
|
# ######################### |
|
VAL121=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set pages 0 feedback off; |
|
prompt |
|
select value from v\$parameter where name='db_unique_name'; |
|
exit; |
|
EOF |
|
) |
|
# Getting DB_NAME in Uppercase & Lowercase: |
|
DB_UNQ_NAME=`echo ${VAL121}| perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'` |
|
export DB_UNQ_NAME |
|
|
|
# In case DB_UNQ_NAME variable is empty then use DB_NAME instead: |
|
case ${DB_UNQ_NAME} in |
|
'') DB_UNQ_NAME=${DB_NAME}; export DB_UNQ_NAME;; |
|
esac |
|
|
|
|
|
if [[ -d ${ORACLE_BASE}/diag/rdbms/${DB_NAME_UPPER} ]] |
|
then |
|
DB_NAME=${DB_NAME_UPPER} |
|
fi |
|
|
|
if [[ -d ${ORACLE_BASE}/diag/rdbms/${DB_NAME_LOWER} ]] |
|
then |
|
DB_NAME=${DB_NAME_LOWER} |
|
fi |
|
|
|
if [[ -d ${ORACLE_BASE}/diag/rdbms/${DB_UNQ_NAME} ]] |
|
then |
|
DB_NAME=${DB_UNQ_NAME} |
|
fi |
|
|
|
export DB_NAME |
|
|
|
|
|
# ################### |
|
# Getting DB Version: |
|
# ################### |
|
echo "Checking DB Version" |
|
VAL311=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set pages 0 feedback off lines 1000; |
|
prompt |
|
select version from v\$instance; |
|
exit; |
|
EOF |
|
) |
|
DB_VER=`echo ${VAL311}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'` |
|
|
|
|
|
# ##################### |
|
# Getting DB Block Size: |
|
# ##################### |
|
echo "Checking DB Block Size" |
|
VAL302=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set pages 0 feedback off lines 1000; |
|
prompt |
|
select value from v\$parameter where name='db_block_size'; |
|
exit; |
|
EOF |
|
) |
|
blksize=`echo ${VAL302}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'` |
|
|
|
|
|
# ##################### |
|
# Getting DB ROLE: |
|
# ##################### |
|
echo "Checking DB Role" |
|
VAL312=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set pages 0 feedback off lines 1000; |
|
prompt |
|
--Remove all spaces from the output: |
|
select replace(DATABASE_ROLE,' ','') from v\$database; |
|
--select DATABASE_ROLE from v\$database; |
|
exit; |
|
EOF |
|
) |
|
DB_ROLE=`echo ${VAL312}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'` |
|
|
|
case ${DB_ROLE} in |
|
PRIMARY) export DB_ROLE_ID=0 ;; |
|
PHYSICALSTANDBY) export DB_ROLE_ID=1 |
|
# Disable the reporting of BLOCKED Sessions if the DB Role is not PRIMARY: |
|
export BLOCKTHRESHOLD=100000 |
|
;; |
|
esac |
|
|
|
|
|
# ###################################### |
|
# Check Flash Recovery Area Utilization: |
|
# ###################################### |
|
VAL318=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set pages 0 feedback off lines 1000; |
|
prompt |
|
select value from v\$parameter where name='db_recovery_file_dest'; |
|
exit; |
|
EOF |
|
) |
|
FRA_LOC=`echo ${VAL318}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'` |
|
|
|
# If FRA is configured, check the its utilization: |
|
if [[ ! -z ${FRA_LOC} ]] |
|
then |
|
|
|
FRACHK1=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF |
|
set pages 0 termout off echo off feedback off linesize ${SQLLINESIZE} |
|
col name for A40 |
|
SELECT ROUND((SPACE_USED - SPACE_RECLAIMABLE)/SPACE_LIMIT * 100, 1) FROM V\$RECOVERY_FILE_DEST; |
|
exit; |
|
EOF |
|
) |
|
|
|
FRAPRCUSED=`echo ${FRACHK1}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'` |
|
|
|
# Convert FRAPRCUSED from float number to integer: |
|
FRAPRCUSED=${FRAPRCUSED%.*} |
|
if [[ -z ${FRAPRCUSED} ]] |
|
then |
|
FRAPRCUSED=1 |
|
fi |
|
|
|
# If FRA %USED >= the defined threshold then send an email alert: |
|
INTEG='^[0-9]+$' |
|
# Verify that FRAPRCUSED value is a valid number: |
|
if [[ ${FRAPRCUSED} =~ ${INTEG} ]] |
|
then |
|
echo "Checking FRA For [ ${ORACLE_SID} ] ..." |
|
if [[ ${FRAPRCUSED} -ge ${FRATHRESHOLD} ]] |
|
then |
|
FRA_RPT=${LOG_DIR}/FRA_REPORT.log |
|
|
|
FRACHK2=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF |
|
set linesize ${SQLLINESIZE} |
|
${HASHHTML} set linesize 300 |
|
${HASHNONHTML} col name for a100 |
|
${HASHNONHTML} col TOTAL_MB for 99999999999999999 |
|
${HASHNONHTML} col FREE_MB for 99999999999999999 |
|
|
|
-- Enable HTML color format: |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
|
|
SPOOL ${FRA_RPT} |
|
${HASHHTML} set pages 0 |
|
${HASHHTML} select '<b>'||'Reported By ${SCRIPT_NAME} Script'||'</b>' from dual; |
|
${HASHHTML} set pages 1000 |
|
|
|
|
|
${HASHNONHTML} PROMPT [Reported By ${SCRIPT_NAME} Script] |
|
${HASHNONHTML} PROMPT |
|
${HASHNONHTML} PROMPT [FLASH RECOVERY AREA Utilization] |
|
${HASHNONHTML} PROMPT |
|
|
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <p> <table border='3' bordercolor='#E67E22' width='30%' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT FLASH RECOVERY AREA Utilization |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 1000 |
|
|
|
col NAME for a30 |
|
SELECT NAME,SPACE_LIMIT/1024/1024 AS TOTAL_MB,(SPACE_LIMIT - SPACE_USED + SPACE_RECLAIMABLE)/1024/1024 AS FREE_MB, |
|
ROUND((SPACE_USED - SPACE_RECLAIMABLE)/SPACE_LIMIT * 100, 1) AS "%FULL" |
|
FROM V\$RECOVERY_FILE_DEST; |
|
|
|
${HASHNONHTML} PROMPT |
|
|
|
${HASHNONHTML} PROMPT [FRA COMPONENTS] |
|
${HASHNONHTML} PROMPT |
|
|
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='22%' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT FRA COMPONENTS |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 1000 |
|
|
|
select * from v\$flash_recovery_area_usage; |
|
|
|
${HASHNONHTML} PROMPT |
|
|
|
${HASHNONHTML} PROMPT [Exist Restore Points: <You may need to drop>] |
|
${HASHNONHTML} PROMPT |
|
|
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='22%' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT Exist Restore Points |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 1000 |
|
|
|
col SCN for 999999999999999999 |
|
col time for a35 |
|
col RESTORE_POINT_TIME for a35 |
|
col name for a40 |
|
select NAME,SCN,TIME,STORAGE_SIZE/1024/1024 STORAGE_SIZE_MB from v\$restore_point; |
|
spool off |
|
exit; |
|
EOF |
|
) |
|
|
|
|
|
# Check if FLASHBACK_RESET flag is enabled: |
|
|
|
# This logfile will be used for logging the reset of FLASHBACK: |
|
touch ${LOG_DIR}/resetflashback_${ORACLE_SID}.log |
|
export FLBLOG=${LOG_DIR}/resetflashback_${ORACLE_SID}.log |
|
|
|
case ${FLASHBACK_RESET} in |
|
Y|y|YES|Yes|yes|ON|On|on) |
|
|
|
# Check if FLASHBACK DATABASE feature is turned ON: |
|
FLASHBACK_ON_RAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set pages 0 feedback off lines 1000; |
|
prompt |
|
select count(*) from v\$database where flashback_on='YES'; |
|
exit; |
|
EOF |
|
) |
|
FLASHBACK_ON=`echo ${FLASHBACK_ON_RAW}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'` |
|
|
|
# IF the FLASHBACK feature is enabled then proceed with resetting it: |
|
case ${FLASHBACK_ON} in |
|
1) |
|
|
|
# Check if MRP process is running: |
|
MRPSTATUSRAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF |
|
set pages 0 feedback off echo off; |
|
prompt |
|
select count(*) from GV\$MANAGED_STANDBY where PROCESS='MRP0' and STATUS='APPLYING_LOG'; |
|
exit; |
|
EOF |
|
) |
|
MRPSTATUS=`echo ${MRPSTATUSRAW}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'` |
|
|
|
# If the database is PHYSICAL STANDBY and in RECOVERY mode, stop and start the recovery before and after turning FLASHBACK ON" |
|
if [[ "${DB_ROLE_ID}" -eq 1 && "${MRPSTATUS}" -eq 1 ]] |
|
then |
|
export RECOVERY_STOP="RECOVER MANAGED STANDBY DATABASE CANCEL;" |
|
export RECOVERY_START="RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE NODELAY DISCONNECT;" |
|
export STANDBY_TAG=" ON PHYSICAL STANDBY" |
|
else |
|
export RECOVERY_STOP="" |
|
export RECOVERY_START="" |
|
export STANDBY_TAG="" |
|
fi |
|
|
|
# TURN FLASHBACK DATABASE OFF & ON: |
|
FLASHBACKRESETRAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF |
|
SPOOL ${FLBLOG} |
|
PROMPT TURNING OFF FLASHBACK ${STANDBY_TAG}... |
|
exec dbms_system.ksdwrt(3,'SCRIPT: ${SCRIPT_NAME} EXECUTING: TURNING OFF FLASHBACK TO FREE UP FRA'); |
|
ALTER DATABASE FLASHBACK OFF; |
|
PROMPT TURNING ON FLASHBACK ${STANDBY_TAG}... |
|
exec dbms_system.ksdwrt(3,'SCRIPT: ${SCRIPT_NAME} EXECUTING: TURNING ON FLASHBACK'); |
|
${RECOVERY_STOP} |
|
ALTER DATABASE FLASHBACK ON; |
|
${RECOVERY_START} |
|
SPOOL OFF |
|
exit; |
|
EOF |
|
) |
|
|
|
FLASHBACK_CHK_RAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set pages 0 feedback off lines 1000; |
|
prompt |
|
select count(*) from v\$database where flashback_on='YES'; |
|
exit; |
|
EOF |
|
) |
|
FLASHBACK_CHK=`echo ${FLASHBACK_CHK_RAW}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'` |
|
|
|
if [[ "${FLASHBACK_CHK}" -eq 0 ]] |
|
then |
|
cat ${FLBLOG} > ${LOGFILE} |
|
export MSGSUBJECT="WARNING: FLASHBACK RESET procedure failed to RE-ENABLE FLASHBACK feature on database [ ${DB_NAME_UPPER} ] on Server [ ${SRV_NAME} ]" |
|
echo ${MSGSUBJECT} |
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
|
|
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE} |
|
echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL} |
|
fi |
|
|
|
|
|
export FLB_RESET_MSG=" | FLASHBACK RESET PROCEDURE EXECUTED${STANDBY_TAG}" |
|
|
|
;; |
|
esac |
|
;; |
|
esac |
|
|
|
echo "FRA has reached ${FRAPRCUSED}%${FLB_RESET_MSG}. Reporting the problem." |
|
cat ${FRA_RPT} > ${LOGFILE} |
|
cat ${FLBLOG} >> ${LOGFILE} |
|
export MSGSUBJECT="ALERT: FRA has reached ${FRAPRCUSED}%${FLB_RESET_MSG} on database [ ${DB_NAME_UPPER} ] on Server [ ${SRV_NAME} ]" |
|
|
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
|
|
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${FRA_RPT} |
|
echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL} |
|
|
|
|
|
fi |
|
fi |
|
|
|
rm -f ${FRAFULL} |
|
rm -f ${FRA_RPT} |
|
fi |
|
|
|
|
|
# ################################ |
|
# Check ASM Diskgroup Utilization: |
|
# ################################ |
|
echo "Checking ASM Diskgroup Utilization ..." |
|
VAL314=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set pages 0 feedback off; |
|
prompt |
|
select count(*) from v\$asm_diskgroup; |
|
exit; |
|
EOF |
|
) |
|
ASM_GROUP_COUNT=`echo ${VAL314}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'` |
|
|
|
# If ASM DISKS Are Exist, Check the size utilization: |
|
if [[ ${ASM_GROUP_COUNT} -gt 0 ]] |
|
then |
|
echo "Checking ASM on [ ${ORACLE_SID} ] ..." |
|
|
|
ASM_UTL=${LOG_DIR}/ASM_UTILIZATION.log |
|
|
|
ASMCHK1=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF |
|
set pages 0 termout off echo off feedback off linesize ${SQLLINESIZE} |
|
col name for A40 |
|
spool ${ASM_UTL} |
|
select name,ROUND((1-(free_mb / total_mb))*100, 2) "%FULL" from v\$asm_diskgroup; |
|
select name,ROUND((1-(free_mb / total_mb))*100, 2) "%FULL" from v\$asm_diskgroup; |
|
spool off |
|
exit; |
|
EOF |
|
) |
|
|
|
ASMFULL=${LOG_DIR}/asm_full.log |
|
#cat ${ASM_UTL}|awk '{ print $1" "$NF }'| while read OUTPUT3 |
|
cat ${ASM_UTL}|egrep -v ${EXL_DISK_GROUP}|awk '{ print $1" "$NF }'| while read OUTPUT3 |
|
do |
|
ASMPRCUSED=`echo ${OUTPUT3}|awk '{print $NF}'` |
|
ASMDGNAME=`echo ${OUTPUT3}|awk '{print $1}'` |
|
echo "[Reported By ${SCRIPT_NAME} Script]" > ${ASMFULL} |
|
echo " " >> ${ASMFULL} |
|
echo "ASM_DISK_GROUP %USED" >> ${ASMFULL} |
|
echo "---------------------- --------------" >> ${ASMFULL} |
|
echo "${ASMDGNAME} ${ASMPRCUSED}%" >> ${ASMFULL} |
|
|
|
# Convert ASMPRCUSED from float number to integer: |
|
ASMPRCUSED=${ASMPRCUSED%.*} |
|
if [[ -z ${ASMPRCUSED} ]] |
|
then |
|
ASMPRCUSED=1 |
|
fi |
|
# If ASM %USED >= the defined threshold send an email for each DISKGROUP: |
|
if [[ ${ASMPRCUSED} -ge ${ASMTHRESHOLD} ]] |
|
then |
|
ASM_RPT=${LOG_DIR}/ASM_REPORT.log |
|
|
|
ASMCHK2=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF |
|
set linesize ${SQLLINESIZE} pages 1000 |
|
col name for a35 |
|
|
|
-- Enable HTML color format: |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
|
|
SPOOL ${ASM_RPT} |
|
|
|
${HASHHTML} set pages 0 |
|
${HASHHTML} select '<b>'||'Reported By ${SCRIPT_NAME} Script'||'</b>' from dual; |
|
${HASHHTML} set pages 1000 |
|
|
|
${HASHNONHTML} PROMPT [Reported By ${SCRIPT_NAME} Script] |
|
${HASHNONHTML} PROMPT |
|
${HASHNONHTML} prompt ASM DISK GROUPS: |
|
${HASHNONHTML} PROMPT *************** |
|
|
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <p> <table border='3' bordercolor='#E67E22' color='#FFFFFF' width='25%' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT ASM DISK GROUPS |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 1000 |
|
|
|
select name,total_mb,free_mb,ROUND((1-(free_mb / total_mb))*100, 2) "%FULL" from v\$asm_diskgroup where name='${ASMDGNAME}'; |
|
spool off |
|
exit; |
|
EOF |
|
) |
|
|
|
echo "ASM DISK GROUP [ ${ASMDGNAME} ] has reached ${ASMPRCUSED}%. Reporting the problem." |
|
export MSGSUBJECT="ALERT: ASM DISK GROUP [ ${ASMDGNAME} ] has reached ${ASMPRCUSED}% on database [ ${DB_NAME_UPPER} ] on Server [ ${SRV_NAME} ]" |
|
cat ${ASM_RPT} > ${LOGFILE} |
|
|
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
|
|
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE} |
|
echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL} |
|
fi |
|
done |
|
|
|
rm -f ${ASMFULL} |
|
rm -f ${ASM_RPT} |
|
fi |
|
|
|
|
|
# ######################### |
|
# Tablespaces Size Check: |
|
# ######################### |
|
|
|
# Workaround Bugs [28821847 & 24445571] which conceal UNDO Tablespace details on dba_tablespace_usage_metrics on 12c+: |
|
|
|
case ${DB_VER} in |
|
12|18|19) export BUG24445571="";; |
|
*) export BUG24445571="--";; |
|
esac |
|
|
|
echo "Checking TABLESPACES on [ ${ORACLE_SID} ] ..." |
|
|
|
if [[ ${DB_VER} -gt 10 ]] |
|
then |
|
# If The Database Version is 11g Onwards: |
|
|
|
TBSCHK=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF |
|
|
|
set pages 0 termout off echo off feedback off |
|
col tablespace_name for A25 |
|
col y for 999999999 heading 'Total_MB' |
|
col z for 999999999 heading 'Used_MB' |
|
col bused for 999.99 heading '%Used' |
|
|
|
spool ${LOG_DIR}/tablespaces_DBA_BUNDLE.log |
|
|
|
select tablespace_name, |
|
(used_space*$blksize)/(1024*1024) Used_MB, |
|
(tablespace_size*$blksize)/(1024*1024) Total_MB, |
|
used_percent "%Used" |
|
from dba_tablespace_usage_metrics |
|
${BUG24445571} where tablespace_name not like '%UNDO%' union all SELECT /*+ RULE */ a.tablespace_name,Used_MB,Total_MB,round ((Used_MB*100)/Total_MB,2) "%Used" FROM ( SELECT SUM (maxbytes) / 1024 / 1024 Total_MB, b.tablespace_name FROM dba_data_files a, dba_tablespaces b WHERE a.tablespace_name = b.tablespace_name AND b.contents like 'UNDO' GROUP BY b.tablespace_name) a, ( SELECT c.tablespace_name, SUM (bytes) / 1024 / 1024 Used_MB FROM DBA_UNDO_EXTENTS c WHERE status <> 'EXPIRED' GROUP BY c.tablespace_name) b WHERE a.tablespace_name = b.tablespace_name |
|
/ |
|
|
|
spool off |
|
exit; |
|
EOF |
|
) |
|
|
|
else |
|
|
|
# If The Database Version is 10g Backwards: |
|
# Check if AUTOEXTEND OFF (MAXSIZE=0) is set for any of the datafiles divide by ALLOCATED size else divide by MAXSIZE: |
|
VAL33=$(${ORACLE_HOME}/bin/sqlplus -S '/ as sysdba' << EOF |
|
set pages 0 feedback off; |
|
SELECT COUNT(*) FROM DBA_DATA_FILES WHERE MAXBYTES=0; |
|
exit; |
|
EOF |
|
) |
|
VAL44=`echo ${VAL33}| awk '{print $NF}'` |
|
case ${VAL44} in |
|
"0") CALCPERCENTAGE1="((sbytes - fbytes)*100 / MAXSIZE) bused " ;; |
|
*) CALCPERCENTAGE1="round(((sbytes - fbytes) / sbytes) * 100,2) bused " ;; |
|
esac |
|
|
|
VAL55=$(${ORACLE_HOME}/bin/sqlplus -S '/ as sysdba' << EOF |
|
set pages 0 feedback off; |
|
SELECT COUNT(*) FROM DBA_TEMP_FILES WHERE MAXBYTES=0; |
|
exit; |
|
EOF |
|
) |
|
VAL66=`echo ${VAL55}| awk '{print $NF}'` |
|
case ${VAL66} in |
|
"0") CALCPERCENTAGE2="((sbytes - fbytes)*100 / MAXSIZE) bused " ;; |
|
*) CALCPERCENTAGE2="round(((sbytes - fbytes) / sbytes) * 100,2) bused " ;; |
|
esac |
|
|
|
TBSCHK=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF |
|
set pages 0 termout off echo off feedback off |
|
col tablespace for A25 |
|
col "MAXSIZE MB" format 9999999 |
|
col x for 999999999 heading 'Allocated MB' |
|
col y for 999999999 heading 'Free MB' |
|
col z for 999999999 heading 'Used MB' |
|
col bused for 999.99 heading '%Used' |
|
--bre on report |
|
spool ${LOG_DIR}/tablespaces_DBA_BUNDLE.log |
|
select a.tablespace_name tablespace,bb.MAXSIZE/1024/1024 "MAXSIZE MB",sbytes/1024/1024 x,fbytes/1024/1024 y, |
|
(sbytes - fbytes)/1024/1024 z, |
|
$CALCPERCENTAGE1 |
|
--round(((sbytes - fbytes) / sbytes) * 100,2) bused |
|
--((sbytes - fbytes)*100 / MAXSIZE) bused |
|
from (select tablespace_name,sum(bytes) sbytes from dba_data_files group by tablespace_name ) a, |
|
(select tablespace_name,sum(bytes) fbytes,count(*) ext from dba_free_space group by tablespace_name) b, |
|
(select tablespace_name,sum(MAXBYTES) MAXSIZE from dba_data_files group by tablespace_name) bb |
|
--where a.tablespace_name in (select tablespace_name from dba_tablespaces) |
|
where a.tablespace_name = b.tablespace_name (+) |
|
and a.tablespace_name = bb.tablespace_name |
|
and round(((sbytes - fbytes) / sbytes) * 100,2) > 0 |
|
UNION ALL |
|
select c.tablespace_name tablespace,dd.MAXSIZE/1024/1024 MAXSIZE_GB,sbytes/1024/1024 x,fbytes/1024/1024 y, |
|
(sbytes - fbytes)/1024/1024 obytes, |
|
$CALCPERCENTAGE2 |
|
from (select tablespace_name,sum(bytes) sbytes |
|
from dba_temp_files group by tablespace_name having tablespace_name in (select tablespace_name from dba_tablespaces)) c, |
|
(select tablespace_name,sum(bytes_free) fbytes,count(*) ext from v\$temp_space_header group by tablespace_name) d, |
|
(select tablespace_name,sum(MAXBYTES) MAXSIZE from dba_temp_files group by tablespace_name) dd |
|
--where c.tablespace_name in (select tablespace_name from dba_tablespaces) |
|
where c.tablespace_name = d.tablespace_name (+) |
|
and c.tablespace_name = dd.tablespace_name |
|
order by tablespace; |
|
select tablespace_name,null,null,null,null,null||'100.00' from dba_data_files minus select tablespace_name,null,null,null,null,null||'100.00' from dba_free_space; |
|
spool off |
|
exit; |
|
EOF |
|
) |
|
fi |
|
TBSLOG=${LOG_DIR}/tablespaces_DBA_BUNDLE.log |
|
TBSFULL=${LOG_DIR}/full_tbs.log |
|
#cat ${TBSLOG}|awk '{ print $1" "$NF }'| while read OUTPUT2 |
|
cat ${TBSLOG}|egrep -v ${EXL_TBS} |awk '{ print $1" "$NF }'| while read OUTPUT2 |
|
do |
|
PRCUSED=`echo ${OUTPUT2}|awk '{print $NF}'` |
|
TBSNAME=`echo ${OUTPUT2}|awk '{print $1}'` |
|
echo "[Reported By ${SCRIPT_NAME} Script]" > ${TBSFULL} |
|
echo " " >> ${TBSFULL} |
|
echo "Tablespace_name %USED" >> ${TBSFULL} |
|
echo "---------------------- --------------" >> ${TBSFULL} |
|
# echo ${OUTPUT2}|awk '{print $1" "$NF}' >> ${TBSFULL} |
|
echo "${TBSNAME} ${PRCUSED}%" >> ${TBSFULL} |
|
|
|
# Convert PRCUSED from float number to integer: |
|
PRCUSED=${PRCUSED%.*} |
|
if [[ -z ${PRCUSED} ]] |
|
then |
|
PRCUSED=1 |
|
fi |
|
# If the tablespace %USED >= the defined threshold send an email for each tablespace: |
|
if [[ ${PRCUSED} -ge ${TBSTHRESHOLD} ]] |
|
then |
|
echo "TABLESPACE [ ${TBSNAME} ] reached ${PRCUSED}%. Reporting the problem." |
|
mail -s "ALERT: TABLESPACE [ ${TBSNAME} ] reached ${PRCUSED}% on database [ ${DB_NAME_UPPER} ] on Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${TBSFULL} |
|
fi |
|
done |
|
|
|
rm -f ${LOG_DIR}/tablespaces_DBA_BUNDLE.log |
|
rm -f ${LOG_DIR}/full_tbs.log |
|
|
|
|
|
# ############################################ |
|
# Checking Monitored Services: |
|
# ############################################ |
|
|
|
#case ${DB_NAME} in |
|
#ORCL) |
|
|
|
if [[ -x ${SERVICEMON} ]] |
|
then |
|
echo "Checking Monitored Services on [ ${ORACLE_SID} ] ..." |
|
VAL_SRVMON_RAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF |
|
set pages 0 feedback off; |
|
prompt |
|
select count(*) from V\$ACTIVE_SERVICES where lower(NAME) in (${SERVICEMON}) or upper(NAME) in (${SERVICEMON}); |
|
exit; |
|
EOF |
|
) |
|
|
|
ONLINE_SERVICES_COUNT=`echo ${VAL_SRVMON_RAW}| awk '{print $NF}'` |
|
#echo "Number of ONLINE Services is: $ONLINE_SERVICES_COUNT" |
|
|
|
MONITORED_SERVICES_COUNT=`echo "${SERVICEMON}" | awk -F "," '{print NF}'` |
|
#echo "Number of MONITORED Services is: $MONITORED_SERVICES_COUNT" |
|
|
|
DOWN_SERVICES_COUNT=`expr ${MONITORED_SERVICES_COUNT} - ${ONLINE_SERVICES_COUNT}` |
|
#echo "Number of OFFLINE Services is: $DOWN_SERVICES_COUNT" |
|
|
|
if [[ ${DOWN_SERVICES_COUNT} -gt 0 ]] |
|
then |
|
VAL_SRVNAME_RAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF |
|
set pages 0 feedback off; |
|
prompt |
|
select name from dba_services minus select name from v\$ACTIVE_SERVICES; |
|
exit; |
|
EOF |
|
) |
|
|
|
OFFLINE_SRVNAME=`echo ${VAL_SRVNAME_RAW}| awk '{print $NF}'` |
|
|
|
VAL_SRVMON_EMAIL=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF |
|
set linesize 160 pages 1000 echo off feedback off |
|
|
|
-- Enable HTML color format: |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
|
|
spool ${LOG_DIR}/current_running_services.log |
|
|
|
${HASHHTML} set pages 0 |
|
${HASHHTML} select '<b>'||'Reported By ${SCRIPT_NAME} Script'||'</b>' from dual; |
|
${HASHHTML} set pages 1000 |
|
|
|
${HASHNONHTML} PROMPT [Reported By ${SCRIPT_NAME} Script] |
|
${HASHNONHTML} PROMPT |
|
|
|
${HASHNONHTML} PROMPT |
|
${HASHNONHTML} PROMPT SERVICE [ ${OFFLINE_SRVNAME} ] REPORTED OFFLINE. |
|
${HASHNONHTML} PROMPT |
|
|
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <p> <table border='3' width='30%' bordercolor='#E67E22' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT SERVICE [ ${OFFLINE_SRVNAME} ] REPORTED OFFLINE |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 1000 |
|
|
|
select name OFFLINE_SERVICES from dba_services minus select name from v\$active_services; |
|
|
|
${HASHHTML} PROMPT <br> |
|
select INST_ID,NAME ONLINE_SERVICE_NAME from GV\$ACTIVE_SERVICES where NAME not in ('SYS\$BACKGROUND','SYS\$USERS') order by ONLINE_SERVICE_NAME; |
|
spool off |
|
exit; |
|
EOF |
|
) |
|
|
|
echo "Service Down detected [ ${OFFLINE_SRVNAME} ]. Reporting the problem." |
|
export MSGSUBJECT="ALERT: SERVICE [ ${OFFLINE_SRVNAME} ] Detected OFFLINE on Instance [ ${ORACLE_SID} ] on Server [ ${SRV_NAME} ]" |
|
cat ${LOG_DIR}/current_running_services.log > ${LOGFILE} |
|
|
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
|
|
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOG_DIR}/current_running_services.log |
|
echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL} |
|
|
|
rm -f ${LOG_DIR}/current_running_services.log |
|
fi |
|
fi |
|
|
|
#;; |
|
#esac |
|
|
|
|
|
# ###################################### |
|
# Checking RMAN In-Complete Backup Jobs: |
|
# ###################################### |
|
|
|
case ${CHKRMANBKP} in |
|
y|Y|yes|YES|Yes|ON|On|on) |
|
|
|
echo "Checking FAILED RMAN Backup Jobs In The Last ${LAST_MIN_BKP_CHK} Minutes ..." |
|
RMANBKPCNTRAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set pages 0 feedback off; |
|
prompt |
|
select count(*) from v\$rman_backup_job_details where end_time > sysdate - (${LAST_MIN_BKP_CHK}/1440) and status in ('FAILED','COMPLETED WITH ERRORS'); |
|
exit; |
|
EOF |
|
) |
|
RMANBKPCNT=`echo ${RMANBKPCNTRAW}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'` |
|
|
|
if [[ ${RMANBKPCNT} -gt 0 ]] |
|
then |
|
echo "FAILED RMAN Backup Jobs Detected." |
|
RMANBKPFAILLOG=${LOG_DIR}/RMANBKPFAILREPORT.log |
|
|
|
RMANBKPCHK=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF |
|
set pages 1000 termout off echo off feedback off linesize ${SQLLINESIZE} |
|
|
|
-- Enable HTML color format: |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
|
|
spool ${RMANBKPFAILLOG} |
|
|
|
${HASHNONHTML} PROMPT [FAILED BACKUP REPORT IN THE LAST ${LAST_MIN_BKP_CHK} Minutes] |
|
${HASHNONHTML} PROMPT |
|
|
|
${HASHHTML} set pages 0 |
|
${HASHHTML} select '<b>'||'Reported By ${SCRIPT_NAME} Script'||'</b>' from dual; |
|
${HASHHTML} set pages 1000 |
|
|
|
|
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <p> <table border='3' bordercolor='#E67E22' width='35%' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT FAILED BACKUP REPORT IN THE LAST ${LAST_MIN_BKP_CHK} Minutes |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 1000 |
|
|
|
col START_TIME for a15 |
|
col END_TIME for a15 |
|
col TIME_TAKEN_DISPLAY for a10 |
|
col INPUT_BYTES_DISPLAY heading "DATA SIZE" for a10 |
|
col OUTPUT_BYTES_DISPLAY heading "Backup Size" for a11 |
|
col OUTPUT_BYTES_PER_SEC_DISPLAY heading "Speed/s" for a10 |
|
col output_device_type heading "Device_TYPE" for a11 |
|
SELECT to_char (start_time,'DD-MON-YY HH24:MI') START_TIME, to_char(end_time,'DD-MON-YY HH24:MI') END_TIME, time_taken_display, status, |
|
input_type, output_device_type,input_bytes_display, output_bytes_display, output_bytes_per_sec_display,COMPRESSION_RATIO COMPRESS_RATIO |
|
FROM v\$rman_backup_job_details |
|
WHERE end_time > sysdate - (${LAST_MIN_BKP_CHK}/1440) |
|
and status in ('FAILED','COMPLETED WITH ERRORS'); |
|
|
|
spool off |
|
exit; |
|
EOF |
|
) |
|
echo "FAILED RMAN Backup Detected. Reporting the problem." |
|
cat ${RMANBKPFAILLOG} > ${LOGFILE} |
|
export MSGSUBJECT="Info: FAILED RMAN Backup Detected on Database [ ${DB_NAME_UPPER} ] on Server [ ${SRV_NAME} ]" |
|
|
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
|
|
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${RMANBKPFAILLOG} |
|
echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL} |
|
fi |
|
esac |
|
|
|
# ############################################### |
|
# Checking ACTIVE SESSIONS COUNT ON THE DATABASE: |
|
# ############################################### |
|
|
|
# Verify if ACTIVE_SESSIONS_THRES is set to a number: |
|
INTEG='^[0-9]+$' |
|
if [[ ${ACTIVE_SESSIONS_THRES} =~ ${INTEG} ]] |
|
then |
|
# Verify if ACTIVE_SESSIONS_THRES is set to value > 0: |
|
if [[ ${ACTIVE_SESSIONS_THRES} -gt 0 ]] |
|
then |
|
echo "Checking The Number of ACTIVE SESSIONS ..." |
|
ACTVSESSCOUNTRAW=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF |
|
select count(*) from v\$session where status='ACTIVE' and wait_class <>'Idle' and last_call_et > ${ACTIVE_TIME}; |
|
exit; |
|
EOF |
|
) |
|
ACTVSESSCOUNT=`echo ${ACTVSESSCOUNTRAW} | awk '{print $NF}'` |
|
echo ACTVSESSCOUNT is: $ACTVSESSCOUNT |
|
if [[ ${ACTVSESSCOUNT} -ge ${ACTIVE_SESSIONS_THRES} ]] |
|
then |
|
ACTVSESSRAW=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF |
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='27%' align='left' summary='ACTIVE SESSIONS:'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT ACTIVE SESSIONS on Instance [ ${ORACLE_SID} ]: |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 1000 lines 300 |
|
|
|
${HASHNONHTML} set linesize ${SQLLINESIZE} pages 1000 |
|
${HASHNONHTML} col "ST|WAITD|ACT_SINC|LOGIN" for a35 |
|
${HASHNONHTML} col "USER|SID,SER|MACHIN|MODUL" for a64 |
|
${HASHNONHTML} col "EVENT" for a24 |
|
${HASHNONHTML} col "I|BLK_BY" for a9 |
|
${HASHNONHTML} col "CURRENT SQL" for a14 |
|
|
|
${HASHNONHTML} PROMPT |
|
${HASHNONHTML} PROMPT ************************************* |
|
|
|
${HASHNONHTML} PROMPT ACTIVE SESSIONS ON INSTANCE [ ${ORACLE_SID} ]: |
|
${HASHNONHTML} PROMPT ************************************* |
|
|
|
spool ${LOG_DIR}/Active_Sessions.log |
|
select |
|
substr(s.USERNAME||'| '||s.sid||','||s.serial#||' |'||substr(s.MACHINE,1,20)||'|'||substr(s.MODULE,1,18),1,64)"USER|SID,SER|MACHIN|MODUL" |
|
,substr(s.status||'|'||round(w.WAIT_TIME_MICRO/1000000)||'|'||LAST_CALL_ET||'|'||to_char(LOGON_TIME,'ddMon HH24:MI'),1,40) "ST|WAITD|ACT_SINC|LOGIN" |
|
,substr(w.event,1,24) "EVENT" |
|
,s.SQL_ID "CURRENT SQL" |
|
,s.FINAL_BLOCKING_INSTANCE||'|'||s.FINAL_BLOCKING_SESSION "I|BLK_BY" |
|
from v\$session s, v\$session_wait w |
|
where s.USERNAME is not null |
|
and s.sid=w.sid |
|
and s.STATUS='ACTIVE' |
|
AND s.WAIT_CLASS <> 'Idle' |
|
AND s.last_call_et > ${ACTIVE_TIME} |
|
--AND MODULE NOT IN ( ${EXCLUDED_MODULES} ) |
|
order by "CURRENT SQL","I|BLK_BY" desc,w.event,"USER|SID,SER|MACHIN|MODUL","ST|WAITD|ACT_SINC|LOGIN" desc; |
|
exit; |
|
EOF |
|
) |
|
|
|
echo "ACTIVE SESSIONS has crossed the defined threshold. Current count is: ${ACTVSESSCOUNT}" |
|
|
|
cat ${LOG_DIR}/Active_Sessions.log > ${LOGFILE} |
|
|
|
export MSGSUBJECT="INFO: ACTIVE SESSIONS COUNT is [ ${ACTVSESSCOUNT} ] on Instance [ ${ORACLE_SID} ] on Server [ ${SRV_NAME} ]" |
|
|
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
|
|
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE} |
|
echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL} |
|
|
|
rm -f ${LOGFILE} |
|
|
|
fi |
|
fi |
|
fi |
|
|
|
# ############################################ |
|
# Checking BLOCKING SESSIONS ON THE DATABASE: |
|
# ############################################ |
|
|
|
echo "Checking Blocking Sessions on [ ${ORACLE_SID} ] With Wait > ${WAIT_FOR_LOCK_THRES} seconds..." |
|
|
|
if [[ ${DB_VER} -gt 10 ]] |
|
then |
|
export WAIT_COL="s2.WAIT_TIME_MICRO" |
|
export WAIT_DISPLAY="round(${WAIT_COL}/1000000,0)" |
|
export KILLARG="DISCONNECT" |
|
else |
|
export WAIT_COL="s2.SECONDS_IN_WAIT" |
|
export WAIT_DISPLAY="round(${WAIT_COL})" |
|
export KILLARG="KILL" |
|
fi |
|
|
|
VAL77=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF |
|
set pages 0 feedback off; |
|
select count(*) from gv\$LOCK l1, gv\$SESSION s1, gv\$LOCK l2, gv\$SESSION s2 |
|
where s2.wait_class<>'Idle' |
|
and s1.sid=l1.sid |
|
and s2.sid=l2.sid |
|
and l1.BLOCK=1 |
|
and l2.request > 0 |
|
and l1.id1=l2.id1 |
|
and l2.id2=l2.id2 |
|
and ${WAIT_DISPLAY} > ${WAIT_FOR_LOCK_THRES}; |
|
exit; |
|
EOF |
|
) |
|
|
|
VAL88=`echo ${VAL77}| awk '{print $NF}'` |
|
|
|
if [[ ${VAL88} -ge ${BLOCKTHRESHOLD} ]] |
|
then |
|
echo "BLOCKING SESSIONS detected. Reporting the problem." |
|
|
|
VAL99=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF |
|
set linesize ${SQLLINESIZE} pages 1000 echo off feedback off |
|
col BLOCKING_STATUS for a90 |
|
|
|
-- Enable HTML color format: |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
|
|
spool ${LOG_DIR}/blocking_sessions.log |
|
|
|
${HASHHTML} set pages 0 |
|
${HASHHTML} select '<b>'||'Reported By ${SCRIPT_NAME} Script'||'</b>' from dual; |
|
${HASHHTML} set pages 1000 |
|
|
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <p> <table border='3' bordercolor='#E67E22' width='27%' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT MASTER BLOCKING SESSIONS ON DATABASE [ ${ORACLE_SID} ] |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 1000 |
|
|
|
${HASHNONHTML} prompt ************************************ |
|
${HASHNONHTML} PROMPT MASTER BLOCKING SESSIONS ON DATABASE: [ ${ORACLE_SID} ] |
|
${HASHNONHTML} PROMPT ************************************ |
|
|
|
set feedback off linesize ${SQLLINESIZE} pages 1000 |
|
col "I|OS/DB USER|SID,SER|MACHN|MOD" for a75 |
|
col "PREV|CURRENT_SQL|REMAIN_SEC" for a30 |
|
col "ST|WAITD|ACT_SINC|LOGIN" for a34 |
|
col event for a24 |
|
select /*+RULE*/ |
|
substr(s.INST_ID||'|'||s.OSUSER||'/'||s.USERNAME||'| '||s.sid||','||s.serial#||' |'||substr(s.MACHINE,1,22)||'|'||substr(s.MODULE,1,18),1,75)"I|OS/DB USER|SID,SER|MACHN|MOD" |
|
,substr(s.status||'|'||round(w.WAIT_TIME_MICRO/1000000)||'|'||LAST_CALL_ET||'|'||to_char(LOGON_TIME,'ddMon HH24:MI'),1,34) "ST|WAITD|ACT_SINC|LOGIN" |
|
,substr(w.event,1,24) "EVENT" |
|
,s.PREV_SQL_ID||'|'||s.SQL_ID||'|'||round(w.TIME_REMAINING_MICRO/1000000) "PREV|CURRENT_SQL|REMAIN_SEC" |
|
from gv\$session s, gv\$session_wait w, (select distinct s2.FINAL_BLOCKING_SESSION blocking_sid,s2.blocking_instance blocking_inst_id from gv\$session s2 where s2.FINAL_BLOCKING_SESSION is not null) blk_sess |
|
where s.sid =blk_sess.blocking_sid |
|
and s.inst_id=blk_Sess.blocking_inst_id |
|
and s.USERNAME is not null |
|
and s.sid=w.sid |
|
and s.inst_id=w.inst_id |
|
and s.FINAL_BLOCKING_SESSION is null; |
|
|
|
col "KILL MASTER BLOCKING SESSION" for a75 |
|
select /*+RULE*/ 'ALTER SYSTEM ${KILLARG} SESSION '''||s.sid||','||s.serial#||',@'||s.inst_id||''' IMMEDIATE;' "KILL MASTER BLOCKING SESSION" |
|
from gv\$session s |
|
where s.sid in (select distinct FINAL_BLOCKING_SESSION from gv\$session where FINAL_BLOCKING_SESSION is not null) |
|
and s.USERNAME is not null |
|
and s.FINAL_BLOCKING_SESSION is null |
|
/ |
|
|
|
${HASHNONHTML} prompt |
|
|
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='27%' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT List of BLOCKED SESSIONS |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 1000 |
|
|
|
${HASHNONHTML} prompt |
|
${HASHNONHTML} prompt ******************************* |
|
|
|
${HASHNONHTML} prompt [List of Victim BLOCKED SESSIONS] |
|
${HASHNONHTML} prompt ******************************* |
|
|
|
set linesize ${SQLLINESIZE} pages 1000 echo off feedback off |
|
col module for a27 |
|
col event for a24 |
|
col MACHINE for a27 |
|
col "WA_ST|WAITD|ACT_SINC|LOG_T" for a38 |
|
col "INST|USER|SID,SERIAL#" for a30 |
|
col "INS|USER|SID,SER|MACHIN|MODUL" for a65 |
|
col "PREV|CURR SQLID" for a27 |
|
col "I|BLKD_BY" for a12 |
|
col "${WAIT_DISPLAY}" for 99999999.9 |
|
select /*+RULE*/ |
|
substr(s.INST_ID||'|'||s.USERNAME||'| '||s.sid||','||s.serial#||' |'||substr(s.MACHINE,1,22)||'|'||substr(s.MODULE,1,18),1,65)"INS|USER|SID,SER|MACHIN|MODUL" |
|
,substr(w.state||'|'||round(w.WAIT_TIME_MICRO/1000000)||'|'||LAST_CALL_ET||'|'||to_char(LOGON_TIME,'ddMon'),1,38) "WA_ST|WAITD|ACT_SINC|LOG_T" |
|
,substr(w.event,1,24) "EVENT" |
|
,s.FINAL_BLOCKING_INSTANCE||'|'||s.FINAL_BLOCKING_SESSION "I|BLKD_BY" |
|
from gv\$session s, gv\$session_wait w |
|
where s.USERNAME is not null |
|
and s.FINAL_BLOCKING_SESSION is not null |
|
and s.sid=w.sid |
|
and s.STATUS='ACTIVE' |
|
and s.wait_class<>'Idle' |
|
order by "I|BLKD_BY" desc,w.event,"INS|USER|SID,SER|MACHIN|MODUL","WA_ST|WAITD|ACT_SINC|LOG_T" desc; |
|
|
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='27%' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT Blocking Locks On Objects Level |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 1000 |
|
|
|
${HASHNONHTML} prompt |
|
${HASHNONHTML} prompt **************************** |
|
|
|
${HASHNONHTML} Prompt [Blocking Locks On Objects Level] |
|
${HASHNONHTML} prompt **************************** |
|
|
|
--${HASHNONHTML} PROMPT |
|
${HASHHTML} set linesize ${SQLLINESIZE} pages 1000 echo off feedback off |
|
${HASHNONHTML} set linesize ${SQLLINESIZE} pages 100 echo on feedback on |
|
|
|
column OS_PID format A15 Heading "OS_PID" |
|
column ORACLE_USER format A15 Heading "ORACLE_USER" |
|
column LOCK_TYPE format A15 Heading "LOCK_TYPE" |
|
column LOCK_HELD format A11 Heading "LOCK_HELD" |
|
column LOCK_REQUESTED format A11 Heading "LOCK_REQUESTED" |
|
column STATUS format A13 Heading "STATUS" |
|
column OWNER format A15 Heading "OWNER" |
|
column OBJECT_NAME format A35 Heading "OBJECT_NAME" |
|
select /*+RULE*/ l.sid, |
|
ORACLE_USERNAME oracle_user, |
|
decode(TYPE, |
|
'MR', 'Media Recovery', |
|
'RT', 'Redo Thread', |
|
'UN', 'User Name', |
|
'TX', 'Transaction', |
|
'TM', 'DML', |
|
'UL', 'PL/SQL User Lock', |
|
'DX', 'Distributed Xaction', |
|
'CF', 'Control File', |
|
'IS', 'Instance State', |
|
'FS', 'File Set', |
|
'IR', 'Instance Recovery', |
|
'ST', 'Disk Space Transaction', |
|
'TS', 'Temp Segment', |
|
'IV', 'Library Cache Invalidation', |
|
'LS', 'Log Start or Switch', |
|
'RW', 'Row Wait', |
|
'SQ', 'Sequence Number', |
|
'TE', 'Extend Table', |
|
'TT', 'Temp Table', type) lock_type, |
|
decode(LMODE, |
|
0, 'None', |
|
1, 'Null', |
|
2, 'Row-S (SS)', |
|
3, 'Row-X (SX)', |
|
4, 'Share', |
|
5, 'S/Row-X (SSX)', |
|
6, 'Exclusive', lmode) lock_held, |
|
decode(REQUEST, |
|
0, 'None', |
|
1, 'Null', |
|
2, 'Row-S (SS)', |
|
3, 'Row-X (SX)', |
|
4, 'Share', |
|
5, 'S/Row-X (SSX)', |
|
6, 'Exclusive', request) lock_requested, |
|
decode(BLOCK, |
|
0, 'Not Blocking', |
|
1, 'Blocking', |
|
2, 'Global', block) status, |
|
OWNER, |
|
OBJECT_NAME |
|
from v\$locked_object lo, |
|
dba_objects do, |
|
v\$lock l |
|
where lo.OBJECT_ID = do.OBJECT_ID |
|
AND l.SID = lo.SESSION_ID |
|
AND l.BLOCK='1'; |
|
|
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='35%' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT Long Running Operations On DATABASE [ ${ORACLE_SID} ] |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 1000 |
|
|
|
${HASHNONHTML} prompt |
|
${HASHNONHTML} prompt ****************************************** |
|
|
|
${HASHNONHTML} Prompt [Long Running Operations On DATABASE $ORACLE_SID] |
|
${HASHNONHTML} prompt ****************************************** |
|
|
|
set linesize ${SQLLINESIZE} pages 1000 |
|
col "USERNAME| SID,SERIAL#" for a40 |
|
col MESSAGE for a80 |
|
col "%COMPLETE" for 999.999 |
|
col "SID|SERIAL#" for a12 |
|
col "STARTED|MIN_ELAPSED|REMAIN" for a30 |
|
select USERNAME||'| '||SID||','||SERIAL# "USERNAME| SID,SERIAL#",SQL_ID |
|
--,OPNAME OPERATION |
|
,round(SOFAR/TOTALWORK*100,2) "%DONE" |
|
,to_char(START_TIME,'DD-Mon HH24:MI')||'| '||trunc(ELAPSED_SECONDS/60)||'|'||trunc(TIME_REMAINING/60) "STARTED|MIN_ELAPSED|REMAIN" ,MESSAGE |
|
from v\$session_longops |
|
where SOFAR/TOTALWORK*100 <>'100' |
|
and TOTALWORK <> '0' |
|
order by "STARTED|MIN_ELAPSED|REMAIN" desc, "USERNAME| SID,SERIAL#"; |
|
|
|
|
|
${HASHHTML} SET PAGES 0 |
|
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF |
|
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='27%' align='left' summary='Script output'> <tr> <th scope="col"> |
|
${HASHHTML} PROMPT LOCKING ANALYSIS |
|
${HASHHTML} PROMPT </td> </tr> </table> <p> <br> |
|
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF |
|
${HASHHTML} set pages 0 lines 300 |
|
${HASHHTML} col blocking_status for a300 |
|
|
|
${HASHNONHTML} set linesize ${SQLLINESIZE} pages 0 |
|
${HASHNONHTML} PROMPT |
|
${HASHNONHTML} PROMPT ****************** |
|
|
|
${HASHNONHTML} PROMPT [LOCKING ANALYSIS] |
|
${HASHNONHTML} PROMPT ****************** |
|
|
|
select /*+RULE*/ 'User: '||s1.username || '@' || s1.machine || '(SID=' || s1.sid ||' ) running SQL_ID:'||s1.sql_id||' is blocking |
|
User: '|| s2.username || '@' || s2.machine || '(SID=' || s2.sid || ') running SQL_ID:'||s2.sql_id||' For '||${WAIT_DISPLAY}||' Seconds |
|
[Inform user '||s1.username||' Or Kill his session using:] |
|
ALTER SYSTEM ${KILLARG} SESSION '''||s1.sid||','||s1.serial#||',@'||s1.inst_id||''' immediate;' AS blocking_status |
|
from gv\$LOCK l1, gv\$SESSION s1, gv\$LOCK l2, gv\$SESSION s2 |
|
where s1.sid=l1.sid |
|
and s2.sid=l2.sid |
|
and l1.BLOCK=1 |
|
and l2.request > 0 |
|
and l1.id1 = l2.id1 |
|
and l2.id2 = l2.id2 |
|
order by ${WAIT_COL} desc |
|
/ |
|
|
|
spool off |
|
exit; |
|
EOF |
|
) |
|
cat ${LOG_DIR}/blocking_sessions.log > ${LOGFILE} |
|
export MSGSUBJECT="ALERT: BLOCKING SESSIONS detected on database [ ${DB_NAME_UPPER} ] on Server [ ${SRV_NAME} ]" |
|
|
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
|
|
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOG_DIR}/blocking_sessions.log |
|
echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL} |
|
rm -f ${LOG_DIR}/blocking_sessions.log |
|
fi |
|
|
|
|
|
# ######################### |
|
# Locating DB ALERTLOG path: |
|
# ######################### |
|
echo "Locating DB Instance ALERTLOG ..." |
|
|
|
# First Attempt: |
|
DUMP=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set pages 0 feedback off lines 30000; |
|
prompt |
|
SELECT VALUE from V\$DIAG_INFO where name='Diag Trace'; |
|
exit; |
|
EOF |
|
) |
|
ALERTZ=`echo ${DUMP} | perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'` |
|
ALERTDB=${ALERTZ}/alert_${ORACLE_SID}.log |
|
export ALERTDB |
|
|
|
# Second Attempt: |
|
if [[ ! -r ${ALERTDB} ]] |
|
then |
|
DUMP=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set pages 0 feedback off lines 30000; |
|
prompt |
|
SELECT value from v\$parameter where NAME='background_dump_dest'; |
|
exit; |
|
EOF |
|
) |
|
ALERTZ=`echo ${DUMP} | perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'` |
|
ALERTDB=${ALERTZ}/alert_${ORACLE_SID}.log |
|
export ALERTDB |
|
fi |
|
|
|
# Third Attempt: |
|
if [[ ! -r ${ALERTDB} ]] |
|
then |
|
DUMP=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set pages 0 feedback off lines 30000; |
|
prompt |
|
SELECT value from v\$parameter where NAME='core_dump_dest'; |
|
exit; |
|
EOF |
|
) |
|
ALERTZ=`echo ${DUMP} | perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|sed -e 's/\/cdump/\/trace/g'` |
|
ALERTDB=${ALERTZ}/alert_${ORACLE_SID}.log |
|
export ALERTDB |
|
fi |
|
|
|
# Forth Attempt: |
|
if [[ ! -r ${ALERTDB} ]] |
|
then |
|
ALERTDB=${ORACLE_BASE}/diag/rdbms/${DB_NAME}/${ORACLE_SID}/trace/alert_${ORACLE_SID}.log |
|
export ALERTDB |
|
fi |
|
|
|
# Fifth Attempt: [Expensive search with locate command] |
|
if [[ ! -r ${ALERTDB} ]] |
|
then |
|
if [[ -x /usr/bin/locate ]] |
|
then |
|
ALERTDB=`ls -rtl \`locate alert_${ORACLE_SID}\`|tail -1|awk '{print $NF}'` |
|
export ALERTDB |
|
fi |
|
fi |
|
|
|
|
|
# ########################### |
|
# Checking Database Errors: |
|
# ########################### |
|
|
|
# ALERTLOG errors to be send in text format: |
|
export MAILEXEC="mail -s" |
|
|
|
# Final check of ALERTLOG path: |
|
if [[ -r ${ALERTDB} ]] |
|
then |
|
ALERTLOG=${ALERTDB} |
|
elif [[ -r ${ORACLE_BASE}/admin/${ORACLE_SID}/bdump/alert_${ORACLE_SID}.log ]] |
|
then |
|
ALERTLOG=${ORACLE_BASE}/admin/${ORACLE_SID}/bdump/alert_${ORACLE_SID}.log |
|
elif [[ -r ${ORACLE_HOME}/diagnostics/${DB_NAME}/diag/rdbms/${DB_NAME}/${ORACLE_SID}/trace/alert_${ORACLE_SID}.log ]] |
|
then |
|
ALERTLOG=${ORACLE_HOME}/diagnostics/${DB_NAME}/diag/rdbms/${DB_NAME}/${ORACLE_SID}/trace/alert_${ORACLE_SID}.log |
|
else |
|
ALERTLOG=`/usr/bin/find ${ORACLE_BASE} -iname alert_${ORACLE_SID}.log -print 2>/dev/null|sort|tail -1` |
|
fi |
|
|
|
# If HTML OPTION Enabled: |
|
#case ${SENDMAIL} in |
|
#'/usr/sbin/sendmail -t') |
|
#if [ -f ${ALERTLOG} ] |
|
#then |
|
#ALERTXML=`echo ${ALERTLOG} |awk '{print $NF}'|sed -e 's/\/trace\/alert.*/\/alert\/log.xml/g'` |
|
#echo ALERTXML is: $ALERTXML |
|
# if [ -f ${ALERTXML} ] |
|
# then |
|
# export ALERTLOG=${ALERTXML} |
|
# fi |
|
#export ALERTLOG |
|
#echo ALERTLOG is: $ALERTLOG |
|
#fi |
|
#;; |
|
#esac |
|
|
|
if [[ -r ${ALERTLOG} ]] |
|
then |
|
echo "Checking DB ALERTLOG ..." |
|
# Rename the old log generated by the script (if exists): |
|
if [[ -r ${LOG_DIR}/alert_${ORACLE_SID}_new.log ]] |
|
then |
|
mv ${LOG_DIR}/alert_${ORACLE_SID}_new.log ${LOG_DIR}/alert_${ORACLE_SID}_old.log |
|
# Create new log: |
|
tail -1000 ${ALERTLOG} > ${LOG_DIR}/alert_${ORACLE_SID}_new.log |
|
# Extract new entries by comparing old & new logs: |
|
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/diff_${ORACLE_SID}.log |
|
echo " " >> ${LOG_DIR}/diff_${ORACLE_SID}.log |
|
diff ${LOG_DIR}/alert_${ORACLE_SID}_old.log ${LOG_DIR}/alert_${ORACLE_SID}_new.log |grep ">" | cut -f2 -d'>' >> ${LOG_DIR}/diff_${ORACLE_SID}.log |
|
|
|
# Search for errors: |
|
|
|
ERRORS=`cat ${LOG_DIR}/diff_${ORACLE_SID}.log | grep 'ORA-\|TNS-' |egrep -v ${EXL_DB_ALERT_ERR}| tail -1` |
|
EXPFLAG=`cat ${LOG_DIR}/diff_${ORACLE_SID}.log | grep 'DM00 ' | tail -1` |
|
ALTERSFLAG=`cat ${LOG_DIR}/diff_${ORACLE_SID}.log | grep 'ALTER SYSTEM ' | tail -1` |
|
ALTERDFLAG=`cat ${LOG_DIR}/diff_${ORACLE_SID}.log | grep 'Completed: ' | tail -1` |
|
STARTUPFLAG=`cat ${LOG_DIR}/diff_${ORACLE_SID}.log | grep 'Starting ORACLE instance' | tail -1` |
|
SHUTDOWNFLAG=`cat ${LOG_DIR}/diff_${ORACLE_SID}.log | grep 'Instance shutdown complete' | tail -1` |
|
WARNINGFLAG=`cat ${LOG_DIR}/diff_${ORACLE_SID}.log | grep 'WARNING: ' | tail -1` |
|
|
|
FILE_ATTACH=${LOG_DIR}/diff_${ORACLE_SID}.log |
|
|
|
else |
|
# Create new log: |
|
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/alert_${ORACLE_SID}_new.log |
|
echo " " >> ${LOG_DIR}/alert_${ORACLE_SID}_new.log |
|
tail -1000 ${ALERTLOG} >> ${LOG_DIR}/alert_${ORACLE_SID}_new.log |
|
|
|
# Search for errors: |
|
ERRORS=`cat ${LOG_DIR}/alert_${ORACLE_SID}_new.log | grep 'ORA-\|TNS-' |egrep -v ${EXL_DB_ALERT_ERR}| tail -1` |
|
FILE_ATTACH=${LOG_DIR}/alert_${ORACLE_SID}_new.log |
|
fi |
|
|
|
|
|
# Send mail in case error exist: |
|
|
|
case "${ERRORS}" in |
|
*ORA-*|*TNS-*) |
|
# In case time out errors reported enclose the Network Failure Staticits in the same E-mail: |
|
case ${TIMEOUTDIGMORE} in |
|
y|Y|yes|YES|Yes|true|TRUE|True|on|ON|On) |
|
case "${ERRORS}" in |
|
*'timed out'*) |
|
case `uname` in |
|
Linux ) |
|
if [[ -x /usr/bin/sar ]] |
|
then |
|
echo "Alertlog TIMEOUT errors reported, Checking OS Network Failure Statistics for the last 15 minutes ..." |
|
echo -e "Netowrk Statistics are shown at the bottom of this E-mail\n$(cat ${FILE_ATTACH})" > ${FILE_ATTACH} |
|
echo "" >> ${FILE_ATTACH} |
|
echo "Following up on the detected TIMEOUT error [ ${ERRORS} ]" >> ${FILE_ATTACH} |
|
echo "" >> ${FILE_ATTACH} |
|
echo "NIC Statistics in the last 15 minutes:" >> ${FILE_ATTACH} |
|
echo "*************************************" >> ${FILE_ATTACH} |
|
echo "sar -n EDEV -s `date "+%H:%M:%S" -d "20 min ago"` | grep -Ev lo" >> ${FILE_ATTACH} |
|
sar -n EDEV -s `date "+%H:%M:%S" -d "20 min ago"` | grep -Ev lo >> ${FILE_ATTACH} |
|
fi |
|
esac |
|
esac |
|
esac |
|
|
|
case ${TEMPSPACEDIGMORE} in |
|
y|Y|yes|YES|Yes|true|TRUE|True|on|ON|On) |
|
case "${ERRORS}" in |
|
*'ORA-1652'*|*'ORA-01652'*) |
|
echo -e "TOP TEMP SPACE CONSUMERS are shown at the bottom of this E-mail\n$(cat ${FILE_ATTACH})" > ${FILE_ATTACH} |
|
TOP_TEMP_CONSUMERS=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set pages 1000 feedback off lines ${SQLLINESIZE} |
|
SPOOL ${FILE_ATTACH} APPEND |
|
col "USER|SID,SER|MACHIN|MODUL" for a65 |
|
COL TABLESPACE FOR A15 |
|
PROMPT |
|
PROMPT Following up on the detected error [ ${ERRORS} ] ... |
|
PROMPT |
|
PROMPT TOP TEMP SPACE CONSUMERS: |
|
PROMPT ************************* |
|
|
|
select substr(s.USERNAME||'|'||s.sid||','||s.serial#||'|'||substr(s.MACHINE,1,20)||'|'||substr(s.MODULE,1,20),1,65)"USER|SID,SER|MACHINE|MODULE" |
|
,SUM (O.BLOCKS) * T.BLOCK_SIZE/1024/1024 USED_MB ,COUNT(*) SORTS#, S.SQL_ID,O.TABLESPACE |
|
FROM V\$SORT_USAGE O, V\$SESSION S, DBA_TABLESPACES T |
|
WHERE O.SESSION_ADDR = S.SADDR AND O.TABLESPACE = T.TABLESPACE_NAME |
|
GROUP BY S.SID, S.SERIAL#, S.USERNAME, S.OSUSER, S.MODULE,S.MACHINE, T.BLOCK_SIZE,S.SQL_ID, O.TABLESPACE |
|
ORDER BY USED_MB desc,S.USERNAME; |
|
spool off |
|
exit; |
|
EOF |
|
) |
|
esac |
|
esac |
|
|
|
case ${REPORT_MAX_SESSIONS} in |
|
y|Y|yes|YES|Yes|true|TRUE|True|on|ON|On) |
|
case "${ERRORS}" in |
|
*ORA-00020*) |
|
echo "Alertlog ORA-00020 detected, checking connected sessions distribution ..." |
|
echo -e "ORA-00020 detected, Please also check the Sessions Distribution at the bottom of this E-mail\n$(cat ${FILE_ATTACH})" >${FILE_ATTACH} |
|
|
|
SESSIONS_DISTRIBUTION=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set feedback off echo off linesize ${SQLLINESIZE} pages 1000 |
|
col inst for 9999 |
|
col module for a70 |
|
col event for a28 |
|
col MACHINE for a70 |
|
col USERNAME for a40 |
|
|
|
SPO ${FILE_ATTACH} APP |
|
PROMPT |
|
PROMPT Following up on the detected error [ ${ERRORS} ] ... |
|
PROMPT |
|
PROMPT SESSIONS Distribution: [By USERNAME] |
|
PROMPT ********************* ************ |
|
|
|
select USERNAME,count(*) "TOTAL_SESSIONS" from v\$session group by USERNAME order by count(*) desc, USERNAME; |
|
|
|
PROMPT |
|
PROMPT SESSIONS Distribution: [By MODULE] |
|
PROMPT ********************* ********* |
|
|
|
select MODULE,count(*) "TOTAL_SESSIONS" from v\$session group by module order by count(*) desc,MODULE; |
|
PROMPT |
|
PROMPT SESSIONS Distribution: [By MACHINE] |
|
PROMPT ********************* ********** |
|
|
|
select MACHINE,count(*) "TOTAL_SESSIONS" from v\$session group by MACHINE order by count(*) desc,MACHINE; |
|
|
|
PROMPT |
|
set pages 0 |
|
select 'ACTIVE SESSIONS: '||count(*) from v\$session where USERNAME is not null and status='ACTIVE'; |
|
select 'INACTIVE SESSIONS: '||count(*) from v\$session where USERNAME is not null and status='INACTIVE'; |
|
select 'BACKGROUND SESSIONS: '||count(*) from v\$session where USERNAME is null; |
|
PROMPT -------------------- ------ |
|
|
|
select 'TOTAL SESSIONS: '||count(*) from v\$session; |
|
PROMPT |
|
select 'PARAMETER: PROCESSES | VALUE: '||INITIAL_ALLOCATION||' | CURRENT_UTILIZATION: '||CURRENT_UTILIZATION||' | MAX_UTILIZATION: '||MAX_UTILIZATION from v\$resource_limit where RESOURCE_NAME ='processes'; |
|
select 'PARAMETER: SESSIONS | VALUE: '||INITIAL_ALLOCATION||' | CURRENT_UTILIZATION: '||CURRENT_UTILIZATION||' | MAX_UTILIZATION: '||MAX_UTILIZATION from v\$resource_limit where RESOURCE_NAME ='sessions'; |
|
|
|
/* |
|
set pages 1000 |
|
col PARAMETER for a15 |
|
col VALUE for 999999999999 |
|
col CURRENT_CONNECTED_SESSIONS for 99999999999999999999999999 |
|
col MAX_CONNECTED_SESSIONS for 9999999999999999999999 |
|
select RESOURCE_NAME PARAMETER,INITIAL_ALLOCATION VALUE,CURRENT_UTILIZATION CURRENT_CONNECTED_SESSIONS,MAX_UTILIZATION MAX_CONNECTED_SESSIONS from v\$resource_limit where RESOURCE_NAME in ('processes','sessions'); |
|
*/ |
|
spool off |
|
exit; |
|
EOF |
|
) |
|
esac |
|
esac |
|
|
|
|
|
cat ${FILE_ATTACH} > ${LOGFILE} |
|
export MSGSUBJECT="ALERT: Instance [ ${ORACLE_SID} ] on Server [ ${SRV_NAME} ] reporting errors: ${ERRORS}" |
|
echo ${MSGSUBJECT} |
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
|
|
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE} |
|
#echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL} |
|
|
|
;; |
|
esac |
|
|
|
case ${PARANOIDMODE} in |
|
y|Y|yes|YES|Yes|true|TRUE|True|on|ON|On) |
|
|
|
case "${EXPFLAG}" in |
|
*'DM00'*) |
|
cat ${FILE_ATTACH} > ${LOGFILE} |
|
export MSGSUBJECT="INFO: EXPORT/IMPORT Operation Initiated on Instance [ ${ORACLE_SID} ] on Server [ ${SRV_NAME} ]" |
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
|
|
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE} |
|
#echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL} |
|
;; |
|
esac |
|
|
|
case "${ALTERSFLAG}" in |
|
*'ALTER SYSTEM'*) |
|
cat ${FILE_ATTACH} > ${LOGFILE} |
|
export MSGSUBJECT="INFO: ALTER SYSTEM Command Executed Against Instance [ ${ORACLE_SID} ] on Server [ ${SRV_NAME} ]" |
|
echo ${MSGSUBJECT} |
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
|
|
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE} |
|
#echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL} |
|
;; |
|
esac |
|
|
|
case "${ALTERDFLAG}" in |
|
*'Completed:'*) |
|
cat ${FILE_ATTACH} > ${LOGFILE} |
|
export MSGSUBJECT="INFO: MAJOR DB ACTIVITY Completed on Instance [ ${ORACLE_SID} ] on Server [ ${SRV_NAME} ]" |
|
echo ${MSGSUBJECT} |
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
|
|
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE} |
|
#echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL} |
|
;; |
|
esac |
|
|
|
case "${STARTUPFLAG}" in |
|
*'Starting ORACLE instance'*) |
|
cat ${FILE_ATTACH} > ${LOGFILE} |
|
export MSGSUBJECT="ALERT: Startup Event of Instance [ ${ORACLE_SID} ] Triggered on Server [ ${SRV_NAME} ]" |
|
echo ${MSGSUBJECT} |
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
|
|
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE} |
|
#echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL} |
|
;; |
|
esac |
|
|
|
case "${SHUTDOWNFLAG}" in |
|
*'Instance shutdown complete'*) |
|
cat ${FILE_ATTACH} > ${LOGFILE} |
|
export MSGSUBJECT="ALARM: Shutdown Event of Instance [ ${ORACLE_SID} ] Triggered on Server [ ${SRV_NAME} ]" |
|
echo ${MSGSUBJECT} |
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
|
|
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE} |
|
#echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL} |
|
;; |
|
esac |
|
|
|
case "${WARNINGFLAG}" in |
|
*'WARNING: '*) |
|
cat ${FILE_ATTACH} > ${LOGFILE} |
|
export MSGSUBJECT="INFO: WARNING Message Detected on Instance [ ${ORACLE_SID} ] on Server [ ${SRV_NAME} ]" |
|
echo ${MSGSUBJECT} |
|
SENDMAILARGS=$( |
|
echo "To: ${EMAIL};" |
|
echo "Subject: ${MSGSUBJECT} ;" |
|
echo "Content-Type: text/html;" |
|
echo "MIME-Version: 1.0;" |
|
cat ${LOGFILE} |
|
) |
|
|
|
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE} |
|
;; |
|
esac |
|
|
|
|
|
;; |
|
esac |
|
fi |
|
|
|
|
|
# ################################################ |
|
# Removal of JUNK MESSAGES inside the DB ALERTLOG: |
|
# ################################################ |
|
|
|
case ${REMOVE_JUNK_MSGS} in |
|
y|Y|yes|Yes|YES|ON|on) |
|
if [[ -r ${ALERTLOG} ]] |
|
then |
|
# Remove "XDB initialized" message caused by Bug 29845449 from the alertlog and 2 lines above it; which covers the message timestamp: |
|
vim -e - ${ALERTLOG} << EOF |
|
g/XDB initialized/.-2,.d |
|
wq |
|
EOF |
|
fi |
|
;; |
|
esac |
|
|
|
# ##################### |
|
# Reporting Offline DBs: |
|
# ##################### |
|
# Populate ${LOG_DIR}/alldb_DBA_BUNDLE.log from ORATAB: |
|
# put all running instances in one variable: |
|
ALL_RUNNING_INSTANCES=`ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|awk '{print $NF}'|sed -e 's/ora_pmon_//g'|grep -v sed|grep -v "s///g"` |
|
# Exclude all running instances/DB names from getting checked when reading ORATAB file: |
|
grep -v '^\#' ${ORATAB} |egrep -v "${EXL_DB}"|egrep -v "${ALL_RUNNING_INSTANCES}"|grep -v "${DB_NAME_LOWER}:"| grep -v "${DB_NAME_UPPER}:"| grep -v '^$' | grep "^" | cut -f1 -d':' > ${LOG_DIR}/alldb_DBA_BUNDLE.log |
|
|
|
# Populate ${LOG_DIR}/updb_DBA_BUNDLE.log: |
|
echo ${ORACLE_SID} >> ${LOG_DIR}/updb_DBA_BUNDLE.log |
|
echo ${DB_NAME} >> ${LOG_DIR}/updb_DBA_BUNDLE.log |
|
|
|
# End looping for databases: |
|
echo "" |
|
done |
|
|
|
# Continue Reporting Offline DBs... |
|
case ${CHKOFFLINEDB} in |
|
y|Y|yes|YES|Yes|ON|On|on) |
|
echo "Checking Offline Databases ..." |
|
# Sort the lines alphabetically with removing duplicates: |
|
sort ${LOG_DIR}/updb_DBA_BUNDLE.log | uniq -d > ${LOG_DIR}/updb_DBA_BUNDLE.log.sort |
|
sort ${LOG_DIR}/alldb_DBA_BUNDLE.log > ${LOG_DIR}/alldb_DBA_BUNDLE.log.sort |
|
diff ${LOG_DIR}/alldb_DBA_BUNDLE.log.sort ${LOG_DIR}/updb_DBA_BUNDLE.log.sort > ${LOG_DIR}/diff_DBA_BUNDLE.sort |
|
echo "The Following Instances are POSSIBLY Down/Hung on [ ${SRV_NAME} ]:" > ${LOG_DIR}/offdb_DBA_BUNDLE.log |
|
echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" >> ${LOG_DIR}/offdb_DBA_BUNDLE.log |
|
grep "^< " ${LOG_DIR}/diff_DBA_BUNDLE.sort | cut -f2 -d'<' >> ${LOG_DIR}/offdb_DBA_BUNDLE.log |
|
echo " " >> ${LOG_DIR}/offdb_DBA_BUNDLE.log |
|
echo "If above instances are permanently offline, please add their names to 'EXL_DB' parameter at line# 90 or hash their entries in ${ORATAB} to let the script ignore them in the next run." >> ${LOG_DIR}/offdb_DBA_BUNDLE.log |
|
OFFLINE_DBS_NUM=`cat ${LOG_DIR}/offdb_DBA_BUNDLE.log| wc -l` |
|
|
|
# If OFFLINE_DBS is not null: |
|
if [[ ${OFFLINE_DBS_NUM} -gt 4 ]] |
|
then |
|
echo "" >> ${LOG_DIR}/offdb_DBA_BUNDLE.log |
|
echo "Current Running Instances:" >> ${LOG_DIR}/offdb_DBA_BUNDLE.log |
|
echo "************************" >> ${LOG_DIR}/offdb_DBA_BUNDLE.log |
|
ps -ef|grep pmon|grep -v grep >> ${LOG_DIR}/offdb_DBA_BUNDLE.log |
|
echo "" >> ${LOG_DIR}/offdb_DBA_BUNDLE.log |
|
|
|
VALX1=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF |
|
set pages 100; |
|
spool ${LOG_DIR}/running_instances.log |
|
set linesize ${SQLLINESIZE} |
|
col BLOCKED for a7 |
|
col STARTUP_TIME for a19 |
|
select instance_name INS_NAME,STATUS,DATABASE_STATUS DB_STATUS,LOGINS,BLOCKED,to_char(STARTUP_TIME,'DD-MON-YY HH24:MI:SS') STARTUP_TIME from v\$instance; |
|
spool off |
|
exit; |
|
EOF |
|
) |
|
cat ${LOG_DIR}/running_instances.log >> ${LOG_DIR}/offdb_DBA_BUNDLE.log |
|
|
|
echo "Offline Database Detected. Reporting the problem." |
|
mail -s "ALARM: Database Inaccessible on Server: [ ${SRV_NAME} ]" ${MAIL_LIST} < ${LOG_DIR}/offdb_DBA_BUNDLE.log |
|
fi |
|
|
|
# Wiping Logs: |
|
#cat /dev/null > ${LOG_DIR}/updb_DBA_BUNDLE.log |
|
#cat /dev/null > ${LOG_DIR}/alldb_DBA_BUNDLE.log |
|
#cat /dev/null > ${LOG_DIR}/updb_DBA_BUNDLE.log.sort |
|
#cat /dev/null > ${LOG_DIR}/alldb_DBA_BUNDLE.log.sort |
|
#cat /dev/null > ${LOG_DIR}/diff_DBA_BUNDLE.sort |
|
|
|
rm -f ${LOG_DIR}/updb_DBA_BUNDLE.log |
|
rm -f ${LOG_DIR}/alldb_DBA_BUNDLE.log |
|
rm -f ${LOG_DIR}/updb_DBA_BUNDLE.log.sort |
|
rm -f ${LOG_DIR}/alldb_DBA_BUNDLE.log.sort |
|
rm -f ${LOG_DIR}/diff_DBA_BUNDLE.sort |
|
|
|
;; |
|
esac |
|
|
|
|
|
# ########################### |
|
# Checking Listeners log: |
|
# ########################### |
|
# Check if the LISTENER CHECK flag is Y: |
|
|
|
case ${CHKLISTENER} in |
|
y|Y|yes|YES|Yes|ON|On|on) |
|
echo "Checking Listener Log ..." |
|
# In case there is NO Listeners are running send an (Alarm): |
|
LSN_COUNT=$( ps -ef|grep -v grep|grep tnslsnr|wc -l ) |
|
|
|
if [[ ${LSN_COUNT} -eq 0 ]] |
|
then |
|
echo "The following are the LISTENERS running by user ${ORA_USER} on server ${SRV_NAME}:" > ${LOG_DIR}/listener_processes.log |
|
echo "************************************************************************************" >> ${LOG_DIR}/listener_processes.log |
|
ps -ef|grep -v grep|grep tnslsnr >> ${LOG_DIR}/listener_processes.log |
|
mail -s "ALARM: No Listeners Are Running on Server: ${SRV_NAME} !!!" ${MAIL_LIST} < ${LOG_DIR}/listener_processes.log |
|
|
|
# In case there is listener running analyze its log: |
|
else |
|
# for LISTENER_NAME in $( ps -ef|grep -v grep|grep tnslsnr|awk '{print $(NF-1)}' ) |
|
for LISTENER_NAME in $( ps -ef|grep -v grep|grep tnslsnr|awk '{print $(9)}' ) |
|
do |
|
# LISTENER_HOME=`ps -ef|grep -v grep|grep tnslsnr|grep "${LISTENER_NAME} "|awk '{print $(NF-2)}' |sed -e 's/\/bin\/tnslsnr//g'|grep -v sed|grep -v "s///g"` |
|
LISTENER_HOME=`ps -ef|grep -v grep|grep tnslsnr|grep "${LISTENER_NAME} "|awk '{print $(8)}' |sed -e 's/\/bin\/tnslsnr//g'|grep -v sed|grep -v "s///g"|head -1` |
|
export LISTENER_HOME |
|
TNS_ADMIN=${LISTENER_HOME}/network/admin |
|
export TNS_ADMIN |
|
LISTENER_LOGDIR=`${LISTENER_HOME}/bin/lsnrctl status ${LISTENER_NAME} |grep "Listener Log File"| awk '{print $NF}'| sed -e 's/\/alert\/log.xml//g'` |
|
export LISTENER_LOGDIR |
|
LISTENER_LOG=${LISTENER_LOGDIR}/trace/${LISTENER_NAME}.log |
|
export LISTENER_LOG |
|
|
|
# Determine if the listener name is in Upper/Lower case: |
|
if [[ ! -r ${LISTENER_LOG} ]] |
|
then |
|
# Listner_name is Uppercase: |
|
LISTENER_NAME=$( echo ${LISTENER_NAME} | awk '{print toupper($0)}' ) |
|
export LISTENER_NAME |
|
LISTENER_LOG=${LISTENER_LOGDIR}/trace/${LISTENER_NAME}.log |
|
export LISTENER_LOG |
|
fi |
|
if [[ ! -r ${LISTENER_LOG} ]] |
|
then |
|
# Listener_name is Lowercase: |
|
LISTENER_NAME=$( echo "${LISTENER_NAME}" | awk '{print tolower($0)}' ) |
|
export LISTENER_NAME |
|
LISTENER_LOG=${LISTENER_LOGDIR}/trace/${LISTENER_NAME}.log |
|
export LISTENER_LOG |
|
fi |
|
|
|
if [[ -r ${LISTENER_LOG} ]] |
|
then |
|
# Rename the old log (If exists): |
|
if [[ -r ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log ]] |
|
then |
|
mv ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log ${LOG_DIR}/alert_lis_${LISTENER_NAME}_old.log |
|
# Create a new log: |
|
tail -1000 ${LISTENER_LOG} > ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log |
|
# Get the new entries: |
|
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/diff_lis_${LISTENER_NAME}.log |
|
echo " " >> ${LOG_DIR}/diff_lis_${LISTENER_NAME}.log |
|
diff ${LOG_DIR}/alert_lis_${LISTENER_NAME}_old.log ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log | grep ">" | cut -f2 -d'>' >> ${LOG_DIR}/diff_lis_${LISTENER_NAME}.log |
|
# Search for errors: |
|
#ERRORS=`cat ${LOG_DIR}/diff_lis_${LISTENER_NAME}.log|grep "TNS-"|egrep -v "${EXL_LSNR_ERR}"|tail -1` |
|
ERRORS=`cat ${LOG_DIR}/diff_lis_${LISTENER_NAME}.log|grep "TNS-"|egrep -v "${EXL_LSNR_ERR}"|tail -1` |
|
SRVC_REG=`cat ${LOG_DIR}/diff_lis_${LISTENER_NAME}.log| grep "service_register" ` |
|
FILE_ATTACH=${LOG_DIR}/diff_lis_${LISTENER_NAME}.log |
|
|
|
# If no old logs exist: |
|
else |
|
# Just create a new log without doing any comparison: |
|
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log |
|
echo " " >> ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log |
|
tail -1000 ${LISTENER_LOG} >> ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log |
|
|
|
# Search for errors: |
|
#ERRORS=`cat ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log|grep "TNS-"|egrep -v "${EXL_LSNR_ERR}"|tail -1` |
|
ERRORS=`cat ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log | grep "TNS-"|egrep -v "${EXL_LSNR_ERR}"|tail -1` |
|
SRVC_REG=`cat ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log | grep "service_register" ` |
|
FILE_ATTACH=${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log |
|
fi |
|
|
|
|
|
# Report TNS Errors (Alert) |
|
case "${ERRORS}" in |
|
*TNS-*) |
|
# In case timeout errors reported enclose the Network Failure Staticits in the same E-mail: |
|
case ${TIMEOUTDIGMORE} in |
|
y|Y|yes|YES|Yes|true|TRUE|True|on|ON|On) |
|
case "${ERRORS}" in |
|
*timeout*) |
|
case `uname` in |
|
Linux ) |
|
echo "Listener TIMEOUT errors reported, Checking OS Network Failure Statistics for the last 15 minutes ..." |
|
echo -e "Network Statistics are shown at the bottom of this E-mail\n$(cat ${FILE_ATTACH})" > ${FILE_ATTACH} |
|
echo "" >> ${FILE_ATTACH} |
|
echo "" >> ${FILE_ATTACH} |
|
echo "NIC Statistics in the last 15 minutes:" >> ${FILE_ATTACH} |
|
echo "*************************************" >> ${FILE_ATTACH} |
|
echo "sar -n EDEV -s `date "+%H:%M:%S" -d "20 min ago"` | grep -Ev lo" >> ${FILE_ATTACH} |
|
sar -n EDEV -s `date "+%H:%M:%S" -d "20 min ago"` | grep -Ev lo >> ${FILE_ATTACH} |
|
esac |
|
esac |
|
esac |
|
mail -s "ALERT: Listener [ ${LISTENER_NAME} ] on Server [ ${SRV_NAME} ] reporting errors: ${ERRORS}" ${MAIL_LIST} < ${FILE_ATTACH} |
|
esac |
|
|
|
|
|
# Report Registered Services to the listener (Info) |
|
case "${SRVC_REG}" in |
|
*service_register*) |
|
mail -s "INFO: Service Registered on Listener [ ${LISTENER_NAME} ] on Server [ ${SRV_NAME} ] | TNS poisoning possibility" ${MAIL_LIST} < ${FILE_ATTACH} |
|
esac |
|
else |
|
echo "Cannot find the listener log: <${LISTENER_LOG}> for listener ${LISTENER_NAME} !" |
|
fi |
|
done |
|
fi |
|
|
|
esac |
|
|
|
|
|
# ############################### |
|
# Checking ASM Instance ALERTLOG: |
|
# ############################### |
|
# Manually Specify ASM Instance alertlog file location: [In case the script failed to find its location] |
|
ASMALERT= |
|
export ASMALERT |
|
|
|
# Check if the CHKASMALERTLOG is enabled: |
|
case ${CHKASMALERTLOG} in |
|
y|Y|yes|YES|Yes|ON|On|on) |
|
|
|
ASMCOUNT=`ps -ef|grep -v grep|grep asm_pmon_|wc -l` |
|
if [[ ${ASMCOUNT} -gt 0 ]] |
|
then |
|
echo "[ASM Instance Found] Locating ASM Instance ALERTLOG ..." |
|
|
|
# Fetching ASM Instance name: |
|
ASM_INSTANCE_NAME=`ps -ef|grep pmon|grep -v grep|grep asm_pmon_|awk '{print $NF}'|sed -e 's/asm_pmon_//g'|grep -v sed|grep -v "s///g"|tail -1` |
|
export ASM_INSTANCE_NAME |
|
|
|
# Locating GRID_HOME: |
|
GRID_HOME=`ps -ef|grep ocssd|grep -v grep|awk '{print $NF}'|sed -e 's/\/bin\/ocssd.bin//g'|grep -v "ocssd.bin"|tail -1` |
|
export GRID_HOME |
|
|
|
if [[ ! -d ${GRID_HOME} ]] |
|
then |
|
GRID_HOME=`dbhome ${ASM_INSTANCE_NAME}` |
|
export GRID_HOME |
|
fi |
|
|
|
# Locating GRID_BASE: |
|
GRID_BASE=`cat ${GRID_HOME}/crs/install/crsconfig_params|grep ^ORACLE_BASE|tail -1|awk '{print $NF}'|sed -e 's/ORACLE_BASE=//g'` |
|
export GRID_BASE |
|
|
|
if [[ ! -d ${GRID_BASE} ]] |
|
then |
|
GRID_BASE=`cat ${GRID_HOME}/crs/utl/appvipcfg|grep ^ORACLE_BASE|tail -1|awk '{print $NF}'|sed -e 's/ORACLE_BASE=//g'` |
|
export GRID_BASE |
|
fi |
|
|
|
if [[ ! -d ${GRID_BASE} ]] |
|
then |
|
GRID_BASE=`cat ${GRID_HOME}/install/envVars.properties|grep ^ORACLE_BASE|tail -1|awk '{print $NF}'|sed -e 's/ORACLE_BASE=//g'` |
|
export GRID_BASE |
|
fi |
|
|
|
# Locating ASM ALERTLOG: |
|
ASMALERT=`ls -rtl ${GRID_BASE}/diag/asm/+asm/${ASM_INSTANCE_NAME}/trace/alert_+ASM*.log|tail -1|awk '{print $NF}'` |
|
export ASMALERT |
|
|
|
if [[ ! -r ${ASMALERT} ]] |
|
then |
|
if [[ -x /usr/bin/locate ]] |
|
then |
|
ASMALERT=`ls -rtl \`/usr/bin/locate alert_+ASM\`|tail -1|awk '{print $NF}'` |
|
export ASMALERT |
|
fi |
|
fi |
|
|
|
if [[ ! -d ${GRID_BASE} ]] |
|
then |
|
if [[ -r ${ASMALERT} ]] |
|
then |
|
GRID_BASE=`grep 'ORACLE_BASE from environment' ${ASMALERT} | awk '{print $(5)}'|tail -1` |
|
export GRID_BASE |
|
fi |
|
fi |
|
|
|
if [[ -r ${ASMALERT} ]] |
|
then |
|
# ASM ALERTLOG Inspection: |
|
echo "Checking ASM ALERTLOG ..." |
|
if [[ -r ${LOG_DIR}/alertASM_new.log ]] |
|
then |
|
|
|
mv ${LOG_DIR}/alertASM_new.log ${LOG_DIR}/alertASM_old.log |
|
# Create new log: |
|
tail -1000 ${ASMALERT} > ${LOG_DIR}/alertASM_new.log |
|
# Extract new entries by comparing old & new logs: |
|
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/diff_ASMALERT.log |
|
echo " " >> ${LOG_DIR}/diff_ASMALERT.log |
|
diff ${LOG_DIR}/alertASM_old.log ${LOG_DIR}/alertASM_new.log |grep ">" | cut -f2 -d'>' >> ${LOG_DIR}/diff_ASMALERT.log |
|
|
|
# Search for errors: |
|
|
|
ERRORS=`cat ${LOG_DIR}/diff_ASMALERT.log | grep 'ORA-\|TNS-' |egrep -v ${EXL_DB_ALERT_ERR}| tail -1` |
|
STARTUPFLAG=`cat ${LOG_DIR}/diff_ASMALERT.log | grep 'Starting ORACLE instance' | tail -1` |
|
SHUTDOWNFLAG=`cat ${LOG_DIR}/diff_ASMALERT.log | grep 'Instance shutdown complete' | tail -1` |
|
|
|
FILE_ATTACH=${LOG_DIR}/diff_ASMALERT.log |
|
|
|
else |
|
# If dbalarm is running for the first time against ASM ALERTLOG, Create a new staging log: |
|
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/alertASM_new.log |
|
echo " " >> ${LOG_DIR}/alertASM_new.log |
|
tail -1000 ${ASMALERT} >> ${LOG_DIR}/alertASM_new.log |
|
|
|
# Search for errors: |
|
ERRORS=`cat ${LOG_DIR}/alertASM_new.log | grep 'ORA-\|TNS-' |egrep -v ${EXL_DB_ALERT_ERR}| tail -1` |
|
FILE_ATTACH=${LOG_DIR}/alertASM_new.log |
|
fi |
|
|
|
# Send E-mail alert in case any of the following errors detected: |
|
|
|
case "${ERRORS}" in |
|
*ORA-*|*TNS-*) |
|
mail -s "ALERT: ASM Instance on Server [ ${SRV_NAME} ] reporting errors: ${ERRORS}" ${MAIL_LIST} < ${FILE_ATTACH} |
|
echo "ALERT: ASM Instance on Server [ ${SRV_NAME} ] reporting errors: ${ERRORS}" |
|
esac |
|
|
|
case "${STARTUPFLAG}" in |
|
*'Starting ORACLE instance'*) |
|
mail -s "ALERT: Startup Event of ASM Instance Triggered on Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${FILE_ATTACH} |
|
echo "ALERT: Startup Event of ASM Instance Triggered on Server [ ${SRV_NAME} ]" |
|
esac |
|
|
|
case "${SHUTDOWNFLAG}" in |
|
*'Instance shutdown complete'*) |
|
mail -s "ALARM: Shutdown Event of ASM Instance Triggered on Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${FILE_ATTACH} |
|
echo "ALARM: Shutdown Event of ASM Instance Triggered on Server [ ${SRV_NAME} ]" |
|
esac |
|
|
|
else |
|
echo "Cannot find ASM ALERTLOG, locate utility is not installed on this system." |
|
echo "Please manually export the ASM ALERTLOG full path inside dbalarm.sh: e.g. ASMALERT=/u01/app/grid/diag/asm/+asm/+ASM/trace/alert_+ASM.log" |
|
fi |
|
fi |
|
esac |
|
|
|
|
|
# ###################################### |
|
# Checking GRID INFRASTRUCTURE ALERTLOG: |
|
# ###################################### |
|
# Manually Specify GRID INFRASTRUCTURE alertlog file location: [In case the script failed to find its location] |
|
GRIDLOGFILE= |
|
export GRIDLOGFILE |
|
|
|
# Check if the CHKCLSALERTLOG flag is enabled: |
|
case ${CHKCLSALERTLOG} in |
|
y|Y|yes|YES|Yes|ON|On|on) |
|
|
|
# Locate ADR BASE: |
|
VAL_ADR_BASE=$(${ORACLE_HOME}/bin/adrci <<EOF |
|
exit; |
|
EOF |
|
) |
|
ADR_BASE=`echo ${VAL_ADR_BASE}|awk '{print $(NF-1)}'|sed -e 's/"//g'` |
|
export ADR_BASE |
|
|
|
# Check for ocssd process: |
|
CHECK_OCSSD=`ps -ef|grep 'ocssd.bin'|grep -v grep|wc -l` |
|
if [[ ${CHECK_OCSSD} -gt 0 ]] |
|
then |
|
echo "[Grid Infrastructure Setup Detected] Locating Grid Infrastructure ALERTLOG ..." |
|
# Hashed the following line to avoid slowing down the script execution: |
|
#GRIDLOGFILE=`locate -i crs/${HOSTNAMELOWER}/crs/trace/alert.log` |
|
|
|
# Locate Clusterware log location: |
|
GRIDLOGFILE="${GRID_BASE}/diag/crs/${HOSTNAMELOWER}/crs/trace/alert.log" |
|
|
|
if [[ ! -r ${GRIDLOGFILE} ]] |
|
then |
|
GRIDLOGFILE="${GRID_BASE}/diag/crs/${HOSTNAMELOWER}/crs/trace/alert${HOSTNAMELOWER}.log" |
|
fi |
|
|
|
if [[ ! -r ${GRIDLOGFILE} ]] |
|
then |
|
GRIDLOGFILE="${GRID_HOME}/log/${HOSTNAMELOWER}/alert${HOSTNAMELOWER}.log" |
|
fi |
|
|
|
if [[ ! -r ${GRIDLOGFILE} ]] |
|
then |
|
GRIDLOGFILE="${GRID_HOME}/log/${HOSTNAMELOWER}/alert.log" |
|
fi |
|
|
|
if [[ ! -r ${GRIDLOGFILE} ]] |
|
then |
|
GRIDLOGFILE="${ADR_BASE}/diag/crs/${HOSTNAMELOWER}/crs/trace/alert.log" |
|
fi |
|
|
|
if [[ ! -r ${GRIDLOGFILE} ]] |
|
then |
|
GRIDLOGFILE="${ADR_BASE}/diag/crs/${HOSTNAMELOWER}/crs/trace/alert${HOSTNAMELOWER}.log" |
|
fi |
|
|
|
export GRIDLOGFILE |
|
|
|
if [[ -r ${GRIDLOGFILE} ]] |
|
then |
|
# CLUSTERWARE ALERTLOG Inspection: |
|
echo "Checking GRID INFRASTRUCTURE ALERTLOG ..." |
|
if [[ -r ${LOG_DIR}/alertGRID_new.log ]] |
|
then |
|
mv ${LOG_DIR}/alertGRID_new.log ${LOG_DIR}/alertGRID_old.log |
|
# Create new logfile: |
|
tail -1000 ${GRIDLOGFILE} > ${LOG_DIR}/alertGRID_new.log |
|
# Extract the new entries by comparing old & new logs: |
|
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/diff_GRIDALERT.log |
|
echo " " >> ${LOG_DIR}/diff_GRIDALERT.log |
|
diff ${LOG_DIR}/alertGRID_old.log ${LOG_DIR}/alertGRID_new.log |grep ">" | cut -f2 -d'>' >> ${LOG_DIR}/diff_GRIDALERT.log |
|
|
|
# Search for errors: |
|
|
|
ERRORS=`cat ${LOG_DIR}/diff_GRIDALERT.log | grep 'ORA-\|TNS-\| error \|error:\|errors with\|Errors\|failed\|fatal error\|Unable to failover\|disconnected from server\|Maximum restart attempts' |egrep -v ${EXL_GRID_ALERT_ERR}| tail -1` |
|
STARTUPFLAG=`cat ${LOG_DIR}/diff_GRIDALERT.log | grep 'is starting' | tail -1` |
|
SHUTDOWNFLAG=`cat ${LOG_DIR}/diff_GRIDALERT.log | grep 'is exiting' | tail -1` |
|
NODEEVECTFLAG=`cat ${LOG_DIR}/diff_GRIDALERT.log | grep 'Node down event' | tail -1` |
|
IPCONFLICTFLAG=`cat ${LOG_DIR}/diff_GRIDALERT.log | grep 'is already in use in the network' | tail -1` |
|
HEARTBEATFLAG=`cat ${LOG_DIR}/diff_GRIDALERT.log | grep 'not scheduled for' | tail -1` |
|
SERVICEFAILFLAG=`cat ${LOG_DIR}/diff_GRIDALERT.log | grep 'has been removed from pool' | tail -1` |
|
|
|
|
|
FILE_ATTACH=${LOG_DIR}/diff_GRIDALERT.log |
|
|
|
else |
|
# If dbalarm is running for the first time against GRID ALERTLOG, Create a new staging log: |
|
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/alertGRID_new.log |
|
echo " " >> ${LOG_DIR}/alertGRID_new.log |
|
tail -1000 ${GRIDALERT} >> ${LOG_DIR}/alertGRID_new.log |
|
|
|
# Search for errors: |
|
ERRORS=`cat ${LOG_DIR}/alertGRID_new.log | grep 'ORA-\|TNS-' |egrep -v ${EXL_DB_ALERT_ERR}| tail -1` |
|
FILE_ATTACH=${LOG_DIR}/alertGRID_new.log |
|
fi |
|
|
|
# Send E-mail alert in case any of the following errors detected: |
|
|
|
case "${ERRORS}" in |
|
*'ORA-'*|*'TNS-'*|*' error '*|*'error:'*|*'errors with'*|*'Errors'*|*'failed'*|*'fatal error'*|*'Unable to failover'*|*'disconnected from server'*|*'Maximum restart attempts'*) |
|
mail -s "ALERT: GRID on Server [ ${SRV_NAME} ] reporting errors: ${ERRORS}" ${MAIL_LIST} < ${FILE_ATTACH} |
|
echo "ALERT: GRID on Server [ ${SRV_NAME} ] reporting errors: ${ERRORS}" |
|
esac |
|
|
|
case "${STARTUPFLAG}" in |
|
*'is starting'*) |
|
mail -s "ALARM: GRID Startup Event Detected on Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${FILE_ATTACH} |
|
echo "ALARM: GRID Startup Event Detected." |
|
esac |
|
|
|
case "${SHUTDOWNFLAG}" in |
|
*'is exiting'*) |
|
mail -s "ALARM: GRID SHUTDOWN Event Detected on Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${FILE_ATTACH} |
|
echo "ALARM: GRID SHUTDOWN Event Detected." |
|
esac |
|
|
|
case "${NODEEVECTFLAG}" in |
|
*'Node down event'*) |
|
mail -s "ALARM: GRID Node Eviction Event Detected on Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${FILE_ATTACH} |
|
echo "ALARM: GRID Node Eviction Event Detected." |
|
esac |
|
|
|
case "${IPCONFLICTFLAG}" in |
|
*'is already in use in the network'*) |
|
mail -s "ALARM: IP CONFLICT Detected In The Network Impacting The GRID On Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${FILE_ATTACH} |
|
echo "ALARM: IP CONFLICT Detected In The Network Impacting The GRID." |
|
esac |
|
|
|
case "${HEARTBEATFLAG}" in |
|
*'not scheduled for'*) |
|
mail -s "ALARM: GRID HEARTBEAT Failure Detected on Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${FILE_ATTACH} |
|
echo "ALARM: GRID HEARTBEAT Failure Detected." |
|
esac |
|
|
|
case "${SERVICEFAILFLAG}" in |
|
*'has been removed from pool'*) |
|
mail -s "ALARM: GRID SERVICE Down Event Detected on Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${FILE_ATTACH} |
|
echo "ALARM: GRID SERVICE Down Event Detected." |
|
esac |
|
|
|
else |
|
echo "Unable to locate the GRID INFRASTRUCTURE ALERTLOG." |
|
echo "Please export it manually inside dbalarm script. e.g. GRIDLOGFILE=/u01/app/grid/diag/crs/databasemachinename/crs/trace/alert.log" |
|
fi |
|
fi |
|
esac |
|
|
|
|
|
# ########################### |
|
# Checking Goldengate Errors: |
|
# ########################### |
|
# Manually Specify goldengate logfile location: [In case the script failed to find its location] |
|
ALERTGGPATH= |
|
export ALERTGGPATH |
|
|
|
# Check if the Goldengate CHECK flag is Y: |
|
|
|
case ${CHKGOLDENGATE} in |
|
y|Y|yes|YES|Yes|ON|On|on) |
|
echo "Checking GoldenGate log ..." |
|
|
|
# Determine goldengate log path: |
|
if [[ ! -z ${ALERTGGPATH} ]] |
|
then |
|
GGLOG=${ALERTGGPATH} |
|
export GGLOG |
|
else |
|
GGLOG=`/bin/ps -ef|grep ggserr.log|grep -v grep|tail -1|awk '{print $NF}'` |
|
export GGLOG |
|
fi |
|
|
|
# Second Attempt: |
|
if [[ ! -r ${GGLOG} ]] |
|
then |
|
GGLOG=`/bin/ps -ef|grep 'PROCESSID MGR'| grep -v grep| awk '{print $10}'|sed -e 's/dirprm\/mgr.prm/ggserr.log/g'` |
|
export GGLOG |
|
fi |
|
|
|
# Third Attempt: [Expensive search with locate command] |
|
if [[ ! -r ${GGLOG} ]] |
|
then |
|
if [[ -x /usr/bin/locate ]] |
|
then |
|
GGLOG=`ls -rtl \`/usr/bin/locate ggserr.log\`|tail -1|awk '{print $NF}'` |
|
export GGLOG |
|
fi |
|
fi |
|
|
|
if [[ -r ${GGLOG} ]] |
|
then |
|
# Rename the old log generated by the script (if exists): |
|
if [[ -r ${LOG_DIR}/ggserr_new.log ]] |
|
then |
|
mv ${LOG_DIR}/ggserr_new.log ${LOG_DIR}/ggserr_old.log |
|
# Create new staging log in case it's the first run of dbalarm.sh: |
|
tail -1000 ${GGLOG} > ${LOG_DIR}/ggserr_new.log |
|
|
|
# Extract new entries by comparing old & new logs: |
|
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/diff_ggserr.log |
|
echo " " >> ${LOG_DIR}/diff_ggserr.log |
|
diff ${LOG_DIR}/ggserr_old.log ${LOG_DIR}/ggserr_new.log |grep ">" | cut -f2 -d'>' >> ${LOG_DIR}/diff_ggserr.log |
|
|
|
# Search for errors: |
|
#ERRORS=`cat ${LOG_DIR}/diff_ggserr.log | grep 'ERROR' |egrep -v ${EXL_GG_ERR}| tail -1` |
|
ERRORS=`cat ${LOG_DIR}/diff_ggserr.log | grep 'ERROR' | tail -1` |
|
|
|
FILE_ATTACH=${LOG_DIR}/diff_ggserr.log |
|
|
|
else |
|
# Create new log: |
|
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/ggserr_new.log |
|
echo " " >> ${LOG_DIR}/ggserr_new.log |
|
tail -1000 ${GGLOG} >> ${LOG_DIR}/ggserr_new.log |
|
|
|
# Search for errors: |
|
#ERRORS=`cat ${LOG_DIR}/ggserr_new.log | grep 'ERROR' |egrep -v ${EXL_GG_ERR}| tail -1` |
|
ERRORS=`cat ${LOG_DIR}/ggserr_new.log | grep 'ERROR' | tail -1` |
|
FILE_ATTACH=${LOG_DIR}/ggserr_new.log |
|
fi |
|
|
|
# Send mail in case error exist: |
|
case ${ERRORS} in |
|
*' ERROR '*) |
|
echo "Goldengate Error Detected. Reporting the problem." |
|
mail -s "Goldengate Error on Server [ ${SRV_NAME} ]: ${ERRORS}" ${MAIL_LIST} < ${FILE_ATTACH} |
|
esac |
|
fi |
|
esac |
|
|
|
|
|
# ############################# |
|
# Check Device Driver Messages: [dmesg] |
|
# ############################# |
|
|
|
case ${DEVICEDRIVERLOG} in |
|
y|Y|yes|YES|Yes|ON|On|on) |
|
echo "Checking Device Driver [dmesg] ..." |
|
|
|
if [[ -r ${LOG_DIR}/dmesg_new.log ]] |
|
then |
|
mv ${LOG_DIR}/dmesg_new.log ${LOG_DIR}/dmesg_old.log |
|
# Generate a new log to compare the old with: |
|
dmesg > ${LOG_DIR}/dmesg_new.log |
|
# Extract new entries by comparing old & new logs: |
|
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/diff_dmesg.log |
|
echo " " >> ${LOG_DIR}/diff_dmesg.log |
|
diff ${LOG_DIR}/dmesg_old.log ${LOG_DIR}/dmesg_new.log |grep ">" | cut -f2 -d'>' >> ${LOG_DIR}/diff_dmesg.log |
|
|
|
# Search for Errors: |
|
ERRORS=`cat ${LOG_DIR}/diff_dmesg.log | grep 'error' |egrep -v ${EXL_DMESG_ERR}| tail -1` |
|
FILE_ATTACH=${LOG_DIR}/diff_dmesg.log |
|
|
|
else |
|
# If dbalarm is running for the first time against dmesg log, create a new staging log and use it for the next execution: |
|
dmesg > ${LOG_DIR}/dmesg_new.log |
|
fi |
|
|
|
case "${ERRORS}" in |
|
*error*) |
|
mail -s "ALERT: OS DEVICE DRIVER Error Detected on Server [ ${SRV_NAME} ] | ${ERRORS}" ${MAIL_LIST} < ${FILE_ATTACH} |
|
echo "ALERT: OS DEVICE DRIVER Error Detected | ${ERRORS}" |
|
esac |
|
esac |
|
|
|
|
|
# ############################### |
|
# De-Neutralize login.sql file: |
|
# ############################### |
|
# If login.sql was renamed during the execution of the script revert it back to its original name: |
|
if [[ -r ${USR_ORA_HOME}/login.sql_NeutralizedBy${SCRIPT_NAME} ]] |
|
then |
|
mv ${USR_ORA_HOME}/login.sql_NeutralizedBy${SCRIPT_NAME} ${USR_ORA_HOME}/login.sql |
|
fi |
|
|
|
echo "" |
|
echo "[dbalarm Script Completed]" |
|
echo "" |
|
|
|
|
|
# ############# |
|
# END OF SCRIPT |
|
# ############# |
|
# REPORT BUGS to: mahmmoudadel@hotmail.com |
|
# DOWNLOAD THE LATEST VERSION OF DATABASE ADMINISTRATION BUNDLE FROM: |
|
# http://dba-tips.blogspot.com/2014/02/oracle-database-administration-scripts.html |
|
# DISCLAIMER: THIS SCRIPT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY. IT IS PROVIDED "AS IS". |