Last active
July 31, 2023 08:44
-
-
Save haballan/78329ca717605d84a083 to your computer and use it in GitHub Desktop.
Oracle Database Monitoring Script (Monitors the alertlog, listener logs, CPU, FILESYSTEM, TABLESPACES, ASM, long running queries, locks, alter system/database commands, export/import operations, startup/shutdown activities) http://dba-tips.blogspot.com/2014/02/database-monitoring-script-for-ora-and.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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". |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment