Saturday, February 15, 2014

Oracle Database Administration Scripts | DBA Bundle

If you were googling for a DBA scripts/tools to help you out with managing the mighty Oracle DB then you have landed on the right blog :-)
I know you're super busy and have no time for reading long articles, so let me jump to the bottom line, the DBA Bundle is a group of shell scripts bundled all together in one tar file, once deployed on the system it allows you to execute different tasks using one single Linux command alias. Its main goal is to simplify your day-to-day common/complex DBA tasks.

DOWNLOAD the latest version from this link:
https://www.dropbox.com/s/le5pxctq0w6v49u/DBA_BUNDLE7.tar?dl=0
 
After opening the link, click on the Down Arrow on the right side:



In case the Dropbox website is blocked in your area, or you cannot copy files directly to the server you want to operate the bundle from due to security restrictions; then do this small trick:

1- On the Server, create a new empty file with name DBA_BUNDLE7.txt:
     # touch
DBA_BUNDLE7.txt
2- Open below link and Copy its content (Ctrl+a then Ctrl+c) and paste it in the DBA_BUNDLE7.txt file:
3- Execute this command to convert the text file to a tar file:
     # LC_ALL=C tr -cd 0-9a-fA-F < DBA_BUNDLE7.txt | xxd -r -p > DBA_BUNDLE7.tar

Then continue to follow below instructions ...
 

What this Bundle can do?
In a nutshell, it's a multi-tool can easily get deployed on any Oracle server. It will help you out to open the database/ASM instance alertlog, Clusterware log, listener config file, display the Clusterware services status, display the tablespaces/ASM diskgroups utilization, display the active sessions, display the blocking locks, display the invalid objects, display audit records, gather database statistics, perform data export, take an RMAN/Cold backup and more and more of such activities using ONE single command from OS shell for each activity without the need to google for the commands you want to use!

How it works: First, download the bundle tar file and extract it under Oracle owner home directory, e.g. /home/oracle  
Second, go to the bundle extracted location and execute "aliases_DBA_BUNDLE.sh" script, using "." command
e.g.
.  aliases_DBA_BUNDLE.sh
This script will get you up and running with the bundle by doing two things:
1- Set the default database environment, so whenever you run any of common aliases like "alert, tns, bdump,..." it will automatically point to the respective files for the default database.
e.g. if you have two running instances (orcl & salesdb), and you want to open the alertlog for salesdb, just run ". aliases_DBA_BUNDLE.sh"  script, enter salesdb number from the displayed list and then type alert/vialert to view salesdb alertlog file.
2- Add the bundle aliases inside the user's profile to make it easy for you to call any script from any working directory using one command alias without the need to step under the bundle directory.
3-At the end it will display all the aliases along with their description in a tabular format. So, you don't have to memorize the aliases, later you can execute "bundle" command to swap between default databases or to view the aliases' description.

For interactive scripts, whenever you execute any of them you will be prompted for the database number to enter in case you have more than one up & running database on the same machine.

Scripts Description:
Now let me give you a brief description for each script in the bundle:


Generic Aliases Associated with the Default Selected Database
Shell Alias Description
bundle Set a database as a default database (all generic aliases will be associated to this database)
alert Open the Database Alertlog with tail -f
vialert Open the Database Alertlog with vi editor
raclog Open the Clusterware/Oracle Restart Alertlog
sql Open sqlplus ‘/ as sysdba’
p List all Running Database Instances (PMON Processes)
lsn List Running Listeners
lis Open listener.ora file with vi editor
tns Open tnsnames.ora file with vi editor
pfile Open the default instance PFILE with vi editor
spfile Open the default instance SPFILE with view editor
oh Go to $ORACLE_HOME directory
dbs Go to $ORACLE_HOME/dbs
aud Go to $ORACLE_HOME/rdbms/audit
bdump Go to BACKGROUND_DUMP_DEST
network Go to $ORACLE_HOME/network/admin
removebundle Remove all the bundle Aliases from the System. (When you run it, let me know the reason)
Scripts With aliases

Script Name Shell Alias Description
table_info.sh  tableinfo Show specific table’s important info (size, indexes, non indexed FK, constraints,...).
oradebug.sh   oradebug Generate Hang Analysis report using oradebug tool in case of instance hang. (New script in V3.6)
active_sessions.sh  active Show the current active sessions and their blocking sessions, along with long running operations + Current running jobs + long running queries. (New script in V3.6)
session_details.sh  session List the Details of a specific user session. (If no input provided, it will list all sessions on the instance).
all_sessions_info.sh sessions List All connected sessions on all running instances [RAC DB] along with their distribution in details.
process_info.sh  spid Show the DB Session details when providing its Unix PID.
sql_id_details.sh sqlid Show the details of a specific SQL STATEMENT by providing its SQL_ID and gives you the option of tuning it using SQL TUNING ADVISOR.
Co-author: Farrukh Salman [Karkoor]
asmdisks.sh asmdisks Show ASM Diskgroups and their size, ASM disks, ASM disks mount points
On OS.
tablespaces.sh  tbs List All TABLESPACES, ASM Disk Groups and FRA (if was configured) allocated size and free space details.
datafiles.sh  datafiles List All DATAFILES and their size.
export_data.sh   exportdata Export Full DB|SCHEMA|TABLE data. (Gives you the option of using exp or expdp utility for the export).
RMAN_full.sh      rmanfull Takes an online RMAN full backup for the database (gives you the option of number of channels/compressed/Encrypted backup type).
Archives_Delete.sh archivedel Delete all Archive logs older than (provided) number of days.
analyze_objects.sh Analyze Analyze All tables under a specific SCHEMA (using ANALYZE legacy command).
gather_stats.sh  gather Gather STATISTICS on a SCHEMA or TABLE using DBMS_STATS. http://dba-tips.blogspot.ae/2014/09/script-to-ease-gathering- statistics-on.html
rebuild_table.sh tablerebuild Rebuild a table and its related indexes.
db_locks.sh                        locks List Blocking LOCKS details on the database (blocking users, blocking locks on objects, long running operations).
db_jobs.sh jobs List All database Jobs (dba_jobs + dba_scheduler_jobs + Auto Tune Tasks and current running jobs and their wait status) + job DDL & its history if provided its name/number.  
invalid_objects.sh invalid List All invalid Objects on the DB + their compile statements.
biggest_100_objects.sh objects List the Biggest 100 Objects on the database.
object_size.sh objectsize Calculate any object size + its indexes size.
lock_user.sh lockuser Lock a specific DB User Account and expire the password.
unlock_user.sh unlockuser Unlock a specific DB User Account + the option of reset the account password.
audit_records.sh   audit Retrieve AUDIT data for a DB user in a specific date or number of days back. http://dba-tips.blogspot.ae/2014/02/extract-oracle-audit-records- script.html
last_logon_report.sh lastlogin Show the last login date of ALL users in the database.
failed_logins.sh failedlogin Show the failed login attempts in the last provided n number of days.
parameter_val.sh  parm Show the value of a Visible/Hidden initialization Parameter.
user_details.sh    userdetail Generate the DDL Creation script for a DB user + its privileges important info about its schema and objects.
user_ddl.sh userddl Generate the DDL Creation script for a DB user + its privileges important info about its schema and objects.
object_ddl.sh  objectddl Generate DDL script for a database Object + its granted permissions on it.
role_ddl.sh roleddl Generate DDL script for a database role.
start_tracing.sh     starttrace Start TRACING an Oracle session activities in a trace file.  http://dba-tips.blogspot.ae/2014/02/script-to-trace-oracle-sesson.html  
stop_tracing.sh  stoptrace Stop TRACING an already traced Oracle session & provide the session’s trace file and its TKPROFED log version.  http://dba-tips.blogspot.ae/2014/02/script-to-trace-oracle-sesson.html  
oracle_cleanup.sh cleanup Backup & Clean up All DBs & Listeners’ Logs. http://dba-tips.blogspot.ae/2014/02/oracle-logs-cleanup-script.html
Scripts Without aliases
Script Name Description
dbalarm.sh Monitors ALERTLOGs of ALL Databases and Listeners log running on the server and instantly report ORA- errors and TNS- errors that appears in these logs to the DBA E-mail Address by sending a detailed email to the DBA along with monitoring CPU, Filesystem/FRA/Tablespaces utilization, blocking locks.
(you have to modify this parameter in line number 27 to point to your E-mail Address):
MAIL_LIST="youremail@yourcompany.com"
Note: sendmail service should be configured on the server.
*The best way to use this script is by schedule it to run in the crontab every 5 minutes (or less).
For more details:
http://dba-tips.blogspot.ae/2014/02/database-monitoring-script- for-ora-and.html
dbdailychk.sh Perform the following health checks on all running databases on the server:
# CHECKING ALL DATABASES ALERTLOGS FOR ERRORS.
# CHECKING ALL LISTENERS ALERTLOGS FOR ERRORS.
# CHECKING CPU UTILIZATION.
# CHECKING FILESYSTEM UTILIZATION.
# CHECKING TABLESPACES UTILIZATION.
# CHECKING FLASH RECOVERY AREA UTILIZATION.
# CHECKING ASM DISKGROUPS UTILIZATION.
# CHECKING BLOCKING SESSIONS ON THE DATABASE.
# CHECKING UNUSABLE INDEXES ON THE DATABASE.
# CHECKING INVALID OBJECTS ON THE DATABASE.
# CHECKING FAILED LOGIN ATTEMPTS ON THE DATABASE.
# CHECKING AUDIT RECORDS ON THE DATABASE.
# CHECKING CORRUPTED BLOCKS ON THE DATABASE.
# CHECKING FAILED JOBS IN THE DATABASE.
# CHECKING ACTIVE INCIDENTS.
# CHECKING OUTSTANDING ALERTS.
# CHECKING DATABASE SIZE GROWTH.
# CHECKING OS / HARDWARE STATISTICS.
# CHECKING RESOURCE LIMITS.
# CHECKING RECYCLEBIN.
# CHECKING CURRENT RESTORE POINTS.
# CHECKING HEALTH MONITOR CHECKS RECOMMENDATIONS THAT RUN BY DBMS_HM PACKAGE.
# CHECKING MONITORED INDEXES.
# CHECKING REDOLOG SWITCHES.
# CHECKING MODIFIED INITIALIZATION PARAMETERS SINCE THE LAST DB STARTUP.
# CHECKING ADVISORS RECOMMENDATIONS:

Replace youremail@yourcompany.com template with your e-mail address.
You can also customize the defined thresholds as per your preferences under THRESHOLD section inside the script.
Last step, Schedule the script to run in the crontab e.g. one time early morning:
0 6 * * * /home/oracle/dbdailychk.sa
For more details:
http://dba-tips.blogspot.ae/2015/05/oracle-database-health-check- script.html
delete_standby_archives.sh Deletes the applied Archives on STANDBY DATABASES
older than N hours (specified by the user). To be customized and scheduled from the crontab.
For more details:
http://dba-tips.blogspot.ae/2017/01/script-to-delete-applied- archivelogs-on.html
COLD_BACKUP.sh Takes a COLD BACKUP of a specific database
(But the beauty of this script once it take the cold backup it will generate another script to help you to restore the taken cold backup easily)
This script will perform the following activities: shutdown the database, take a cold backup, create a restore script (in case you want to restore this cold backup later) then it will automatically startup the database.
For more Details:
http://dba-tips.blogspot.ae/2014/02/cold-backup-script.html
SHUTDOWN_All.sh SHUTDOWN ALL running Databases & Listeners on The server. Keep away from children :-)
schedule_rman_full_bkp.sh Takes an RMAN Full backup for a specific database. Can be scheduled in the crontab.
You MUST adjust the variables/channels/maintenance section to match your environment.
schedule_rman_image_copy_bkp.sh Takes an RMAN Image/Copy for a specific database. Can be scheduled in the crontab.
You MUST adjust the variables/channels/maintenance sections to match your env.

Why consider RMAN image backups in your backup strategy? the answer is in this link:
http://dba-tips.blogspot.ae/2011/11/switch-database-to-rman-copy-backup-and.html
delete_applied_archives_on_standby.sh Deletes the applied archivelogs on a standby DB.
For More Details:
http://dba-tips.blogspot.com/2017/01/script-to-delete-applied-archivelogs-on.html
configuration_baseline.sh Collects all kind of configuration baseline data for OS and all running DATABASES to help you track and control the changes on your environment.
For more details:
http://dba-tips.blogspot.com/2016/12/configuration-baseline-script-for-linux.html
backup_ctrl_spf_AWR.sh Backup Controlfile as (Trace/RMAN BKP), Backup SPFILE and Generate AWR for full day This script can be scheduled in the crontab to run once a day. Script options/variables must be modified to match your environment. New Starting from V4.1
kill_long_running_queries.sh Kill all queries running longer than 2.5 Hours(can be customized inside the script) by specific modules (to be specified inside the script)
This script can be scheduled in the crontab. Script options/variables MUST be modified to get the killing criteria match your requirements. New Starting from V4.1
check_standby_lag.sh If you have a standby DB then you can use this script on Primary DB site to report to you any LAG happens between the primary and the standby DB.
The variables section at the top of the script must be populated by you to match your environment or the script will not be able to run.
This script can be scheduled in the crontab to run every 5 minutes. New Starting from V4.1
This link will show you how to use this script:
http://dba-tips.blogspot.ae/2017/11/shell-script-to-check-lag-sync-status.html
From time to time I'll keep updating this bundle with new scripts, fixing bugs and adding new features, so give this topic a visit at least once every 3 months to download the latest version.

As I mentioned inside each script, I'M SHARING THIS BUNDLE AND ITS SCRIPTS IN THE HOPE THAT IT WILL BE USEFUL FOR YOU, BUT WITHOUT ANY WARRANTY. ALL SCRIPTS IN THIS BUNDLE ARE PROVIDED "AS IS".

No one is perfect... that's why pencils have erasers.

Your suggestions, bug reporting, and comments are most welcome :-)

Lastly, A special thank you to the beautiful mind Abd El-Gawad Othman, without his support, suggestions, and encouragement I wouldn't be confident enough to share this bundle with you.

Script to Export Database | Schema | Table using (Data pump expdp or Legacy export exp)

Update on 05-Feb-2020: 
This post is not valid anymore. Sorry for inconvenience! 

A new script has been released, please follow this link to get the final script:
http://dba-tips.blogspot.com/2020/02/new-script-for-exporting-data.html



Creating a script to export the data is not a big deal, but importing the dump file is a time-consuming job for the DBA. export_data.sh script will not only do the export job, but it will help you out with the import steps when you decide to import the dumpfile, it lists the DDL statements and grants that you need to run before and after the import process in a separate script. I consider this function the most useful feature in this script.

The script gives you the options to export Full Database, Schema or table using either Legacy export utility exp or the modern Data Pump utility expdp.
This script was tested on 10g, 11g and 12c on Linux & SUN environments.

How it works:

First download the script from here:
https://www.dropbox.com/s/hk0pfo2tanop35r/export_data.sh?dl=0

Second run the script, if you have multiple running database on the server it will give you the option to select the database you want to export data from.

> It will ask you the location you want to save the dump file
WHERE TO SAVE THE EXPORT FILE [DUMPFILE]? [ENTER THE FULL PATH]
> It will ask you if you want to export the FULL DATABASE.
Do you want to EXPORT FULL DATABASE? [Y|N] [Y] [N TO EXPORT SCHEMA|TABLE]
    [If your answer is "no"]
      > It will ask you if you want to export a SCHEMA.
Do you want to EXPORT a SCHEMA? [Y|N] [Y] [N If you want to EXPORT TABLE]
          [If your answer is "no"]
             >It will go into the export table mode:
                [Enter the Owner then
Please Enter the TABLE OWNER:
                  Enter the Table name]
Please Enter the TABLE NAME:
> It will ask you to select the utility you want to perform the export with [expdp or exp]
WHICH EXPORT UTILITY YOU WANT TO USE: [1) DATAPUMP [EXPDP]]
====================================
1) DATAPUMP [EXPDP]
2) LEGACY EXPORT [EXP]
> Then let the script do the remaining steps:
    - If EXPDP was selected to export the data, the script will automatically calculate the degree of parallelism based on the number of core CPUs on the server. [By the way parallelism is a buggy feature in EXPDP]
    - It will create a user called DBA_BUNDLEEXP7, granting it dba privilege to use it in the export
       (I'm creating this user because using a sysdba user will disable functions like consistent=y during the export)
    - It will create a directory called EXPORT_FILES_DBA_BUNDLE pointing to the dump location
       you've entered earlier [this in case you selected expdp utility to perform the export job].
    - It will create a "BEFORE IMPORT SCRIPT" [In case you selected export Schema mode earlier]
       this script will include the [creation statement of  roles assigned to the user, user creation statement,
       grant privileges/roles, grant privileges the user has on other schemas objects.
     - It will create an "AFTER IMPORT SCRIPT" [In case you selected export Database mode earlier]
        this script will hint you all triggers owned by SYS user  [if exist]. These triggers will not be created
        during the import process.
     - It will create an "AFTER IMPORT SCRIPT" [In case you selected export Schema mode earlier]
        this script will include the [creation statements of public synonyms for user;s table [if exist],
        grant privileges on schema objects to other users [if exist], giving you a hint for the triggers owned
        by other users that pointing to the exported schema tables [if exist], recompile invalid objects.
     - It will create an "AFTER IMPORT SCRIPT" [In case you selected export Table mode earlier]
        this script will create the public synonyms for exported table [if exist].
     - The script will start the export job using DBA_BUNDLEEXP7 user.
     - Once the export job finish it will drop the DBA_BUNDLEEXP7 user.
     - At the end the script will list to you "Import Guidelines" including the
        BEFORE/AFTER import scripts locations. Finally, it will print the full path of the dumpfile.

If you still not OK with that introduction don't worry the script is self-explanatory :-)
Please note that COMPRESSION option is used by default in the export process.

At any stage, you can terminate the script by pressing [Ctrl+c]

This script is part of DBA BUNDLE, to read more about it please visit this link:
http://dba-tips.blogspot.ae/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".

The following is the code: [in case the download link is not working]

# ###################################################################################################################################################
# Ver: 3.4
# EXPORT DATABASE | SCHEMA | TABLE.
# To be run by ORACLE user
# # # #
# Author: Mahmmoud ADEL # # # # ###
# # # # # #
# Created: 03-02-2014
# Modified: 26-05-2014 Hashed METADATA export lines to clear the confusion.
# 21-08-2014 Added DEGREE OF PARALLELISM calculation.
# 22-01-2020 Passing the export DataPump parameters to a Par file.
# 22-01-2020 Convert the execution of the export in the background NOHUP mode.
# 23-01-2020 Added the option of providing multiple schemas to export.
# 23-01-2020 Added the option of providing multiple tables to export.
# 23-01-2020 Added the option of excluding specific schemas and tables from the Full DB export mode.
# 23-01-2020 Added the option of excluding specific tables from the SCHEMA mode export.
# 28-01-2020 Added the option of COMPRESSING the legacy dump file on the fly for all LEGACY export modes.
# 29-01-2020 Redesigned the parallelism option section to pop-up only when database edition support parallelism.
# 02-02-2020 Added Email Notification option.
# 17-08-2020 Fix a directory creation bug.
# 03-01-2020 Translation of user input . & ~
# 10-11-2021 Fixed the bug of script hung when entering a blank value for Parallelism degree.
# 30-05-2022 Adding CONTENT mode to allow the user export DDL or DATA ONLY.
# 30-05-2022 Adding the final Par file review before the start of the export job.
# 01-09-2022 Set a Warning message if the Exporter DB USER DBA_BUNDLEEXP7 is already exist and forcefully drop it if the user continue.
# ###################################################################################################################################################
# ###########
# Description:
# ###########
export SRV_NAME="`uname -n`"
echo
echo "=============================================="
echo "This script EXPORTS DATABASE | SCHEMA | TABLE."
echo "=============================================="
echo
sleep 1
# #######################################
# Excluded INSTANCES:
# #######################################
# Here you can mention the instances the script 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].
# ###########################
# Listing Available Databases:
# ###########################
# Count Instance Numbers:
INS_COUNT=$( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|wc -l )
# Exit if No DBs are running:
if [[ $INS_COUNT -eq 0 ]]
then
echo "No Database is Running !"
echo
return
fi
# If there is ONLY one DB set it as default without prompt for selection:
if [[ $INS_COUNT -eq 1 ]]
then
export ORACLE_SID=$( 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" )
# If there is more than one DB ASK the user to select:
elif [[ $INS_COUNT -gt 1 ]]
then
echo
echo "Select the ORACLE_SID:[Enter the number]"
echo "---------------------"
select DB_ID 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
integ='^[0-9]+$'
if ! [[ ${REPLY} =~ ${integ} ]] || [ ${REPLY} -gt ${INS_COUNT} ] || [ ${REPLY} -eq 0 ]
then
echo
echo "Error: Not a valid number!"
echo
echo "Enter a valid NUMBER from the displayed list !: i.e. Enter a number from [1 to ${INS_COUNT}]"
echo "----------------------------------------------"
else
export ORACLE_SID=$DB_ID
echo
printf "`echo "Selected Instance: ["` `echo -e "\033[33;5m${DB_ID}\033[0m"` `echo "]"`\n"
echo
break
fi
done
fi
# Exit if the user selected a Non Listed Number:
if [[ -z "${ORACLE_SID}" ]]
then
echo "You've Entered An INVALID ORACLE_SID"
exit
fi
# #########################
# 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 [[ -f /etc/oratab ]]
then
ORATAB=/etc/oratab
export ORATAB
## If OS is Solaris:
elif [[ -f /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 [[ ! -f ${ORACLE_HOME}/bin/sqlplus ]]
then
## If OS is Linux:
if [[ -f /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 [[ -f /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 [[ ! -f ${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 [[ ! -f ${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 [[ ! -f ${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 [[ ! -f ${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 [[ ! -f ${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
# ########################################
# Exit if the user is not the Oracle Owner:
# ########################################
CURR_USER=`whoami`
if [[ ${ORA_USER} != ${CURR_USER} ]]; then
echo ""
echo "You're Running This Sctipt with User: \"${CURR_USER}\" !!!"
echo "Please Run This Script With The Right OS User: \"${ORA_USER}\""
echo "Script Terminated!"
exit
fi
# ########################
# Getting ORACLE_BASE:
# ########################
# Get ORACLE_BASE from user's profile if not set:
if [[ -z "${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
# #########################
# EXPORT Section:
# #########################
# VARIABLES:
# #########
# Date Stamp:
DUMPDATE=`date +%d-%b-%Y`
#PASSHALF=`echo $((RANDOM % 999+7000))`
PASSHALF=`date '+%s'`
# If expdp version is 10g don't use REUSE_DUMPFILES parameter in the script:
VERSION=`strings ${ORACLE_HOME}/bin/expdp|grep Release|awk '{print $3}'`
case ${VERSION} in
10g) REUSE_DUMP='';;
*) REUSE_DUMP='REUSE_DUMPFILES=Y';;
# *) REUSE_DUMP='REUSE_DUMPFILES=Y COMPRESSION=ALL';;
esac
# Capturing the CURRENT_SCN to use it for a consistent DATA PUMP export:
#CURRENT_SCN_RAW=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
#set pages 0 lines 1000 feedback off;
#col current_scn for 99999999999999999999999999999999999
#select current_scn from v\$database;
#EOF
#)
#CURRENT_SCN=`echo ${CURRENT_SCN_RAW}| awk '{print $NF}'`
# case ${CURRENT_SCN} in
# *[0-9]*) export EXPORTSCN="FLASHBACK_SCN=${CURRENT_SCN}";;
# *) export EXPORTSCN="";;
# esac
VAL33=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
set pages 0 feedback off;
SELECT STATUS FROM V\$INSTANCE;
EOF
)
VAL44=`echo ${VAL33}| awk '{print $NF}'`
case ${VAL44} in
"OPEN") echo ;;
*) echo;echo "ERROR: INSTANCE [${ORACLE_SID}] IS IN STATUS: ${VAL44} !"
echo; echo "PLEASE OPEN INSTANCE [${ORACLE_SID}] AND RE-RUN THIS SCRIPT.";echo; exit ;;
esac
USER_OBJECTS_COUNT_RAW=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
set pages 0 feedback off;
SELECT COUNT(*) FROM DBA_OBJECTS WHERE OWNER='DBA_BUNDLEEXP7';
EOF
)
USER_OBJECTS_COUNT=`echo ${USER_OBJECTS_COUNT_RAW}| awk '{print $NF}'`
if [ ${USER_OBJECTS_COUNT} -gt 0 ]
then
echo
printf "`echo "The Exporter User [DBA_BUNDLEEXP7] is already EXIST in the database and has [${USER_OBJECTS_COUNT}] objects and "` `echo -e "\033[33;5mwill be DROPPED\033[0m"` `echo " by this script."`\n"
echo
fi
# ############################################
# Checking if PARALLELISM option is available:
# ############################################
# Computing the default PARALLEL DEGREE based on CPU count:
case `uname` in
Linux ) export PARALLEL_DEGREE=`cat /proc/cpuinfo| grep processor|wc -l`;;
AIX ) export PARALLEL_DEGREE=`lsdev -C|grep Process|wc -l`;;
SunOS ) export PARALLEL_DEGREE=`kstat cpu_info|grep core_id|sort -u|wc -l`;;
HP-UX) export PARALLEL_DEGREE=`lsdev -C|grep Process|wc -l`;;
esac
if [[ ! -z "${PARALLEL_DEGREE##[0-9]*}" ]]
then
export PARALLEL_DEGREE=1
fi
CHK_PARALLELISM_OPTION_RAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF
set pages 0 feedback off echo off;
SELECT count(*) from v\$option where parameter='Parallel execution' and value='TRUE';
exit;
EOF
)
export CHK_PARALLELISM_OPTION=`echo ${CHK_PARALLELISM_OPTION_RAW} | awk '{print $NF}'`
# ##############################
# Prompt for EMAIL Confirmation:
# ##############################
echo "Enter your EMAIL to receive a notification upon the completion of the Export job: [Leave it BLANK or Enter N to Skip the notification]"
echo "================================================================================="
while read EMAILANS
do
case ${EMAILANS} in
""|"N"|"n"|"NO"|"No"|"no")export EMAILANS=""; export SENDEMAIL=""; echo; break;;
*@*.*) export SENDEMAIL="mail -s \"\${JOBSTATUS} on Server ${SRV_NAME}\" \${EMAILID} < \${LOGFILE}"; echo; break;;
*)echo ""
echo -e "\033[32;5mThis doesn't sound like a valid Email? ${EMAILANS}\033[0m"
echo ""
echo "Please Enter your Email: [Leave it BLANK or Enter N to Skip this!]"
echo "------------------------"
echo "i.e. john.smith@xyzcompany.com"
echo "";;
esac
done
echo "Enter the FULL LOCATION PATH where the EXPORT FILE will be saved under: [e.g. /backup/export]"
echo "======================================================================"
while read LOC1
do
case ${LOC1} in
'') export LOC1=`pwd`; echo; echo "DIRECTORY TRANSLATED TO: ${LOC1}";;
'.') export LOC1=`pwd`; echo; echo "DIRECTORY TRANSLATED TO: ${LOC1}";;
'~') export LOC1=${HOME}; echo; echo "DIRECTORY TRANSLATED TO: ${LOC1}";;
esac
if [[ -d "${LOC1}" ]] && [[ -r "${LOC1}" ]] && [[ -w "${LOC1}" ]]
then
echo "Export File will be saved under: ${LOC1}"; break
else
echo; printf "`echo "Please make sure that oracle user has"` `echo -e "\033[33;5mREAD/WRITE\033[0m"` `echo "permissions on the provided directory."`\n"; echo; echo "Enter the complete PATH where the dump file will be saved: [e.g. /backup/export]"
echo "----------------------------------------------------------"
fi
done
# ##############################
# Prompt for EMAIL Confirmation:
# ##############################
echo
echo "Do you want to Enable FLASHBACK SCN? [Y|N] [AKA: Export the data in CONSISTENT mode | Default [Y]]"
echo "===================================="
while read FLASCN
do
case ${FLASCN} in
""|"Y"|"y"|"YES"|"Yes"|"yes")
# Capturing the CURRENT_SCN to use it for a consistent DATA PUMP export:
CURRENT_SCN_RAW=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
set pages 0 lines 1000 feedback off;
col current_scn for 99999999999999999999999999999999999
select current_scn from v\$database;
EOF
)
CURRENT_SCN=`echo ${CURRENT_SCN_RAW}| awk '{print $NF}'`
export EXPORTSCN="FLASHBACK_SCN=${CURRENT_SCN}"
echo
echo "Data will be exported at the current SCN: [${CURRENT_SCN}]"
echo
echo "[Note: If the exported data is too big; make sure the UNDO_RETENTION & UNDO tablespace are big enough.]"
echo
break ;;
*)
echo
echo "FLASHBACK_SCN is DISABLED."
echo
export EXPORTSCN=""
break ;;
esac
done
# ######################
# Export Options:
# ######################
echo
echo "Please Select the EXPORT MODE: [Enter a number]"
echo "=============================="
echo "1. EXPORT FULL DATABASE"
echo "2. EXPORT SCHEMAS"
echo "3. EXPORT TABLES"
echo "[Enter a number from 1 to 3]"
echo ""
while read ANS
do
case $ANS in
1|"EXPORT FULL DATABASE"|"database"|"DATABASE"|"full"|"FULL")echo;echo "Entering EXPORT FULL DATABASE MODE ...";sleep 1
# #######################
# EXPORT DATABASE SECTION:
# #######################
echo
echo "WHICH EXPORT UTILITY YOU WANT TO USE: [DEFAULT IS DATAPUMP EXPDP]"
echo "===================================="
echo "1) DATAPUMP [EXPDP] |Pros: Faster when import, Cloud/PARALLELISM compatible, can Exclude schema/tables |Cons: COMPRESSION requires license"
echo "2) LEGACY EXPORT [EXP] |Pros: COMPRESSION can happen on the fly without license |Cons: Slower when import, No Cloud/PARALLELISM compatibility"
while read EXP_TOOL
do
case $EXP_TOOL in
""|"1"|"DATAPUMP"|"datapump"|"DATAPUMP [EXPDP]"|"[EXPDP]"|"EXPDP"|"expdp")
# Prompt the user the PARALLELISM option only if it's available in the DB Edition:
export INT='^[0-9]+$'
if [[ ${CHK_PARALLELISM_OPTION} =~ ${INT} ]]
then
if [ ${CHK_PARALLELISM_OPTION} -eq 1 ]
then
echo
echo "Enter the PARALLEL DEGREE you want to perform the export with PARALLELISM? [If used, The final dump file will be divided into multiple files!]"
echo "========================================================================="
echo "[Current CPU Count on this Server is: ${PARALLEL_DEGREE}]"
echo "Enter a number bigger than 1 to utilize PARALLELISM or enter 0 to disable PARALLELISM"
echo ""
while read PARALLEL_ANS
do
# Check if the input is an integer:
if [[ -z ${PARALLEL_ANS} ]]; then
export PARALLEL_ANS=0
fi
if [[ ${PARALLEL_ANS} =~ ${INT} ]]
then
# Check if the input is greater than 1:
if [ "${PARALLEL_ANS}" -gt 1 ]
then
export PARALLEL="PARALLEL=${PARALLEL_ANS}"
export PARA="_%u"
echo -e "\033[32;5mPARALLELISM ENABLED | The final dump file will be divided into multiple files based on the degree of parallelism you used.\033[0m"
echo
else
echo "PARALLELISM DISABLED.";echo ""
fi
break
fi
done
else
echo;echo -e "\033[32;5mPARALLELISM option is not available in the current Database Edition.\033[0m"
fi
fi
# PARAMETER FILE CREATION:
export DUMPFILENAME="EXPORT_FULL_DB_${ORACLE_SID}_${DUMPDATE}${PARA}.dmp"
export LOGFILE="${LOC1}/EXPORT_FULL_DB_${ORACLE_SID}_${DUMPDATE}.log"
PARFILE=${LOC1}/EXPORT_FULL_DB_${ORACLE_SID}.par
echo "# FULL DATABASE EXPORT PARAMETER FILE CREATED BY export_data.sh SCRIPT on [${DUMPDATE}]: [${ORACLE_SID}]" > ${PARFILE}
echo "FULL=Y" >> ${PARFILE}
echo "DIRECTORY=EXPORT_FILES_DBA_BUNDLE" >> ${PARFILE}
echo "DUMPFILE=${DUMPFILENAME}" >> ${PARFILE}
echo "LOGFILE=EXPORT_FULL_DB_${ORACLE_SID}_${DUMPDATE}.log" >> ${PARFILE}
echo "${EXPORTSCN}" >> ${PARFILE}
echo "${REUSE_DUMP}" >> ${PARFILE}
echo "${PARALLEL}" >> ${PARFILE}
printf "`echo "Do you want to enable the COMPRESSION [Y|N] [N] [Do NOT answer with YES unless you already acquired the"` `echo -e "\033[33;5mAdvanced Compression License\033[0m"` `echo "]"`\n"
echo "====================================="
while read COMP_ANS
do
case $COMP_ANS in
y|Y|yes|YES|Yes) echo;echo "COMPRESSION=ALL" >> ${PARFILE};echo -e "\033[32;5mCompression Enabled.\033[0m";echo; break ;;
""|n|N|no|NO|No) echo; echo "COMPRESSION DISABLED."; echo; break ;;
*) echo;echo "Please Enter a Valid Answer [Y|N]"
echo "---------------------------------";;
esac
done
echo
echo "Enter the SCHEMAS you want to EXCLUDE from the export, separating them by comma:"
echo "==============================================================================="
echo "i.e. ANONYMOUS,APPQOSSYS,AUDSYS,BI,CTXSYS,DBSNMP,DIP,DMSYS,DVF,DVSYS,EXDSYS,EXFSYS,GSMADMIN_INTERNAL,GSMCATUSER,GSMUSER,LBACSYS,MDSYS,MGMT_VIEW,MDDATA,MTSSYS,ODM,ODM_MTR,OJVMSYS,OLAPSYS,ORACLE_OCM,ORDDATA,ORDPLUGINS,ORDSYS,OUTLN,SI_INFORMTN_SCHEMA,SPATIAL_CSW_ADMIN,SPATIAL_CSW_ADMIN_USR,SPATIAL_WFS_ADMIN,SPATIAL_WFS_ADMIN_USR,SYS,SYSBACKUP,SYSDG,SYSKM,SYSMAN,SYSTEM,TSMSYS,WKPROXY,WKSYS,WK_TEST,WMSYS,XDB,XTISYS,DSSYS,PERFSTAT,REPADMIN,OEM_ADVISOR,OEM_MONITOR,OLAP_DBA,OLAP_USER,OWBSYS,OWBSYS_AUDIT,APEX_030200"
echo "[Leave it BLANK and hit Enter if you do NOT want to exclude any SCHEMAS]"
echo ""
while read EXCLUDESCHEMAVAR
do
case ${EXCLUDESCHEMAVAR} in
"") echo; export EXCLUDESCHEMA=""; break ;;
*) echo; export EXCLUDESCHEMA="EXCLUDE=SCHEMA:\"IN('$(sed s/,/\',\'/g <<<${EXCLUDESCHEMAVAR}| tr '[:lower:]' '[:upper:]')')\""
echo ${EXCLUDESCHEMA} >> ${PARFILE}; break ;;
esac
done
echo "Enter the TABLES you want to EXCLUDE from the export, separating them by comma:"
echo "=============================================================================="
echo "i.e. EMP,DEPT"
echo "[Leave it BLANK and hit Enter if you do NOT want to exclude any TABLES]"
echo ""
while read EXCLUDETABLEVAR
do
case ${EXCLUDETABLEVAR} in
"") echo; export EXCLUDETABLE=""; break ;;
*) echo; export EXCLUDETABLE="EXCLUDE=TABLE:\"IN('$(sed s/,/\',\'/g <<<${EXCLUDETABLEVAR}| tr '[:lower:]' '[:upper:]')')\""
echo ${EXCLUDETABLE} >> ${PARFILE}; break ;;
esac
done
echo
echo "Enter the CONTENT of data you want to Export:"
echo "============================================="
echo "1. DATA+METADATA [DEFAULT]"
echo "2. METADATA_ONLY [DDL]"
echo "3. DATA_ONLY"
echo ""
while read CONTENTVAR
do
case ${CONTENTVAR} in
""|"DATA+METADATA"|1) echo; echo "EXPORT MODE IS SET TO: [DATA + METADATA]"; echo; break ;;
"METADATA_ONLY"|"metadata_only"|"METADATA"|"metadata"|"DDL"|"ddl"|2) echo; export CONTENTVAR="CONTENT=METADATA_ONLY"; echo ${CONTENTVAR} >> ${PARFILE}; echo "EXPORT MODE IS SET TO: [METADATA_ONLY]"; echo; break ;;
"DATA_ONLY"|"data_only"|"DATA"|"data"|3) echo; export CONTENTVAR="CONTENT=DATA_ONLY"; echo ${CONTENTVAR} >> ${PARFILE}; echo "EXPORT MODE IS SET TO: [DATA_ONLY]"; echo; break ;;
*) echo; echo "Enter a correct option number between 1 to 3:"
echo "--------------------------------------------";;
esac
done
echo
echo "Enter the VERSION: [In case you want to import this dump later on a DB with LOWER version] | [Allowed value start from 9.2 and above] "
echo "================="
echo "e.g. If you will import this dump on a 10g DB then enter 10"
echo "For DEFAULT compatibility leave it BLANK."
echo ""
while read VERSION
do
case ${VERSION} in
""|"COMPATIBLE"|"compatible") echo; echo "DUMPFILE COMPATIBILITY version is set to the current DB compatibility level."; echo; break ;;
[0-9]) echo; echo "Wrong version number, this value cannot be set lower than 9.2!"
echo; echo "Enter a correct version higher than 9.2:"
echo "----------------------------------------";;
*) echo; VERSION="VERSION=${VERSION}"; echo ${VERSION} >> ${PARFILE}; echo "DUMPFILE COMPATIBILITY version is set to ${VERSION}."; echo; break ;;
esac
done
echo
echo "You are almost done!"; echo
sleep 1
echo "Please verify the export settings summary:"
echo "------------------------------------------"
cat ${PARFILE}
echo
sleep 1
echo "Shall we start the EXPORT job now? [[YES] | NO]"
echo "=================================="
while read STARTNOW
do
case ${STARTNOW} in
N|n|NO|no) echo; echo "SCRIPT TERMINATED! "; echo; exit;;
""|Y|y|YES|yes) echo; echo "STARTING THE IMPORT ..."; echo; break;;
*) echo "Please enter a valid answer: [YES|NO]";;
esac
done
cd ${LOC1}
SPOOLFILE2=${LOC1}/AFTER_IMPORT_DATABASE_${ORACLE_SID}_${DUMPDATE}.sql
echo "Creating the Exporter User DBA_BUNDLEEXP7 ..."
echo "Preparing the BEFORE and AFTER import script which will help you import the dump file later ..."
VAL11=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
PROMPT CREATE USER DBA_BUNDLEEXP7 [EXPORTER USER] (WILL BE DROPPED AFTER THE EXPORT) ...
CREATE USER DBA_BUNDLEEXP7 IDENTIFIED BY "BUNdle_#-^${PASSHALF}";
ALTER USER DBA_BUNDLEEXP7 IDENTIFIED BY "BUNdle_#-^${PASSHALF}" ACCOUNT UNLOCK;
GRANT CREATE SESSION TO DBA_BUNDLEEXP7;
GRANT DBA TO DBA_BUNDLEEXP7;
-- The following privileges to workaround Bug 6392040:
GRANT EXECUTE ON SYS.DBMS_DEFER_IMPORT_INTERNAL TO DBA_BUNDLEEXP7;
GRANT EXECUTE ON SYS.DBMS_EXPORT_EXTENSION TO DBA_BUNDLEEXP7;
PROMPT
PROMPT CREATING DIRECTORY EXPORT_FILES_DBA_BUNDLE POINTING TO ${LOC1} ...
CREATE OR REPLACE DIRECTORY EXPORT_FILES_DBA_BUNDLE AS '${LOC1}';
PROMPT
PROMPT CREATING AFTER DATABASE IMPORT SCRIPT ...
PROMPT
SET PAGES 0 TERMOUT OFF LINESIZE 157 ECHO OFF FEEDBACK OFF
SPOOL ${SPOOLFILE2}
SELECT 'PROMPT ' FROM DUAL;
SELECT 'PROMPT COMPILING DATABASE INVALID OBJECTS ...' FROM DUAL;
SELECT '@?/rdbms/admin/utlrp' FROM DUAL;
SELECT '@?/rdbms/admin/utlrp' FROM DUAL;
SELECT 'PROMPT ' FROM DUAL;
SELECT 'PROMPT THE FOLLOWING TRIGGERS ARE OWNED BY SYS SCHEMA AND MAY NOT BE EXIST AFTER THE IMPORT' FROM DUAL;
SELECT 'PROMPT YOU MAY CONSIDER CREATING THE NON EXIST TRIGGERS IF YOU NEED SO:' FROM DUAL;
SELECT 'PROMPT ***************************************************************' FROM DUAL;
SELECT 'PROMPT '||TRIGGER_TYPE||' TRIGGER: '||TRIGGER_NAME FROM DBA_TRIGGERS WHERE OWNER=UPPER('SYS') ORDER BY 1;
SELECT 'PROMPT ' FROM DUAL;
SELECT 'PROMPT CHECK IF THESE DIRECTORIES ARE POINTING TO THE RIGHT PATHS? ' FROM DUAL;
SELECT 'PROMPT *********************************************************** ' FROM DUAL;
COL DIRECTORY FOR A50
COL DIRECTORY_PATH FOR A100
SELECT 'PROMPT '||OWNER||'.'||DIRECTORY_NAME||': '||DIRECTORY_PATH FROM DBA_DIRECTORIES;
SELECT 'PROMPT ' FROM DUAL;
SPOOL OFF
EOF
)
echo
# Creation of the Export Script:
export EXPORTSCRIPT=${LOC1}/EXPORTSCRIPT.sh
export EXPORTSCRIPTRUNNER=${LOC1}/EXPORTSCRIPTRUNNER.sh
echo "# Export Script: [Created By DBA_BUNDLE]" > ${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"While the Export job is running, you can check the STATUS using:\"" >>${EXPORTSCRIPT}
echo "echo \"--------------------------------------------------------------- \"" >>${EXPORTSCRIPT}
echo "echo \"SELECT job_name, operation, job_mode, DEGREE, state FROM dba_datapump_jobs where OPERATION='EXPORT' and state='EXECUTING' and owner_name='DBA_BUNDLEEXP7';\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"Then you can ATTACH to the export job and control it using:\"" >>${EXPORTSCRIPT}
echo "echo \"---------------------------------------------------------- \"" >>${EXPORTSCRIPT}
echo "echo \"expdp DBA_BUNDLEEXP7/\"BUNdle_#-^${PASSHALF}\" ATTACH=<JOB_NAME_FROM_ABOVE_COMMAND>\"" >>${EXPORTSCRIPT}
echo "echo \"i.e.\"" >>${EXPORTSCRIPT}
echo "echo \"expdp DBA_BUNDLEEXP7/\"BUNdle_#-^${PASSHALF}\" ATTACH=SYS_EXPORT_FULL_01\"" >>${EXPORTSCRIPT}
echo "echo \"To Show the STATUS:....... STATUS\"" >>${EXPORTSCRIPT}
echo "echo \"To KILL the export:....... KILL_JOB\"" >>${EXPORTSCRIPT}
echo "echo \"To PAUSE the export:...... STOP_JOB\"" >>${EXPORTSCRIPT}
echo "echo \"To RESUME a paused export: START_JOB\"" >>${EXPORTSCRIPT}
echo "export ORACLE_SID=${ORACLE_SID}" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo 'Running The Export Job Now ...'" >>${EXPORTSCRIPT}
echo "${ORACLE_HOME}/bin/expdp DBA_BUNDLEEXP7/\"BUNdle_#-^${PASSHALF}\" PARFILE=${PARFILE}" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo 'Running Post Export Steps ...'" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF" >>${EXPORTSCRIPT}
echo "PROMPT" >>${EXPORTSCRIPT}
echo "PROMPT DROPPING THE EXPORTER USER DBA_BUNDLEEXP7 ..." >>${EXPORTSCRIPT}
echo "DROP USER DBA_BUNDLEEXP7 CASCADE;" >>${EXPORTSCRIPT}
echo "EOF" >>${EXPORTSCRIPT}
echo "echo \"*****************\"" >>${EXPORTSCRIPT}
echo "echo \"IMPORT GUIDELINES:\"" >>${EXPORTSCRIPT}
echo "echo \"*****************\"" >>${EXPORTSCRIPT}
echo "echo \"FLASHBACK SCN used for this export is: ${CURRENT_SCN}\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"Later, AFTER IMPORTING THE DUMPFILE, RUN THIS SQL SCRIPT: ${SPOOLFILE2}\"" >>${EXPORTSCRIPT}
echo "echo \" => IT INCLUDES (HINT FOR TRIGGERS OWNED BY SYS) WHICH WILL NOT BE CREATED BY THE IMPORT PROCESS + COMPILING INVALID OBJECTS.\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"*************************\"" >>${EXPORTSCRIPT}
echo "echo \"EXPORT DUMP FILE LOCATION: ${LOC1}/${DUMPFILENAME}\"" >>${EXPORTSCRIPT}
echo "echo \"*************************\"" >>${EXPORTSCRIPT}
echo "export JOBSTATUS=\`grep \"successfully\\|stopped\\|completed\" ${LOGFILE}|tail -1\`" >>${EXPORTSCRIPT}
echo "export LOGFILE=${LOGFILE}" >>${EXPORTSCRIPT}
echo "export EMAILID=\"${EMAILANS}\"" >>${EXPORTSCRIPT}
echo "${SENDEMAIL}" >>${EXPORTSCRIPT}
chmod 740 ${EXPORTSCRIPT}
echo
echo "#!/bin/bash" > ${EXPORTSCRIPTRUNNER}
echo "nohup sh ${EXPORTSCRIPT}| tee ${LOGFILE} 2>&1 &" >>${EXPORTSCRIPTRUNNER}
chmod 740 ${EXPORTSCRIPTRUNNER}
echo -e "\033[32;5mFeel free to EXIT from this session as the EXPORT SCRIPT is running in the BACKGROUND.\033[0m"
source ${EXPORTSCRIPTRUNNER}
## Export METADATA ONLY: <using Legacy EXP because it's more reliable than EXPDP in exporting DDLs>
#echo;echo "CREATING A FILE CONTAINS ALL CREATION [DDL] STATEMENT OF ALL USERS|OBJECTS ...";sleep 1
#${ORACLE_HOME}/bin/exp DBA_BUNDLEEXP7/"BUNdle_#-^${PASSHALF}" FULL=y ROWS=N STATISTICS=NONE FILE=${LOC1}/${ORACLE_SID}_METADATA_${DUMPDATE}.dmp log=${LOC1}/${ORACLE_SID}_METADATA_${DUMPDATE}.log
## Getting READABLE export script: [DUMP REFINING]
#/usr/bin/strings ${LOC1}/${ORACLE_SID}_METADATA_${DUMPDATE}.dmp > ${LOC1}/${ORACLE_SID}_METADATA_REFINED_${DUMPDATE}.trc
echo; exit ;;
# In case the user will export the FULL database using EXP legacy tool:
"2"|"LEGACY EXPORT"|"LEGACY"|"EXPORT"|"LEGACY EXPORT [EXP]"|"EXP"|"[EXP]"|"exp"|"legacy export"|"legacy"|"export")
echo
printf "`echo "Do you want to enable the COMPRESSION [Y|N] [N] [COMPRESSION will happen on the fly using mknod] | "` `echo -e "\033[33;5mNo License required\033[0m"` `echo "]"`\n"
echo "====================================="
while read COMP_ANS
do
case $COMP_ANS in
y|Y|yes|YES|Yes) echo;export EXPORTDUMP="${LOC1}/EXPORT_FULL_DB_${ORACLE_SID}_${DUMPDATE}_pipe.dmp"
export MKNOD="rm -f ${EXPORTDUMP}; mknod ${EXPORTDUMP} p"
export ZIP="nohup bzip2 -fz < ${EXPORTDUMP} > ${LOC1}/EXPORT_FULL_DB_${ORACLE_SID}_${DUMPDATE}.dmp.bz2 &"
export EXPORTDUMPOUTPUT="${LOC1}/EXPORT_FULL_DB_${ORACLE_SID}_${DUMPDATE}.dmp.bz2"
export REMOVEMKDON="rm -f ${EXPORTDUMP}"
export UNZIPMESSAGE="First DE-COMPRESS the file using this command: bunzip2 -f ${EXPORTDUMPOUTPUT}"
echo -e "\033[32;5mCompression Enabled.\033[0m";echo; break ;;
""|n|N|no|NO|No) echo;export MKNOD=""
export ZIP=""
export EXPORTDUMP="${LOC1}/EXPORT_FULL_DB_${ORACLE_SID}_${DUMPDATE}.dmp"
export EXPORTDUMPOUTPUT="${LOC1}/EXPORT_FULL_DB_${ORACLE_SID}_${DUMPDATE}.dmp";break ;;
*) echo;echo "Please Enter a Valid Answer [Y|N]"
echo "---------------------------------";;
esac
done
echo
echo "EXPORTING DATABASE $ORACLE_SID [USING LEGACY EXP] ..."
sleep 1
cd ${LOC1}
SPOOLFILE2=${LOC1}/AFTER_IMPORT_DATABASE_${ORACLE_SID}_${DUMPDATE}.sql
echo "Creating the Exporter User DBA_BUNDLEEXP7 ..."
echo "Preparing the BEFORE and AFTER import script which will help you import the dump file later ..."
VAL11=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
PROMPT CREATE USER DBA_BUNDLEEXP7 [EXPORTER USER] (WILL BE DROPPED AFTER THE EXPORT) ...
CREATE USER DBA_BUNDLEEXP7 IDENTIFIED BY "BUNdle_#-^${PASSHALF}" ACCOUNT UNLOCK;
ALTER USER DBA_BUNDLEEXP7 IDENTIFIED BY "BUNdle_#-^${PASSHALF}" ACCOUNT UNLOCK;
GRANT CREATE SESSION TO DBA_BUNDLEEXP7;
GRANT EXP_FULL_DATABASE TO DBA_BUNDLEEXP7;
GRANT EXECUTE ON SYS.DBMS_FLASHBACK TO DBA_BUNDLEEXP7;
-- The following privileges to workaround Bug 6392040:
GRANT EXECUTE ON SYS.DBMS_DEFER_IMPORT_INTERNAL TO DBA_BUNDLEEXP7;
GRANT EXECUTE ON SYS.DBMS_EXPORT_EXTENSION TO DBA_BUNDLEEXP7;
PROMPT
PROMPT CREATING DIRECTORY EXPORT_FILES_DBA_BUNDLE POINTING TO ${LOC1} ...
CREATE OR REPLACE DIRECTORY EXPORT_FILES_DBA_BUNDLE AS '${LOC1}';
PROMPT
PROMPT CREATING AFTER DATABASE IMPORT SCRIPT ...
PROMPT
SET PAGES 0 TERMOUT OFF LINESIZE 157 ECHO OFF FEEDBACK OFF
SPOOL ${SPOOLFILE2}
SELECT 'PROMPT COMPILING DATABASE INVALID OBJECTS ...' FROM DUAL;
SELECT '@?/rdbms/admin/utlrp' FROM DUAL;
SELECT '@?/rdbms/admin/utlrp' FROM DUAL;
SELECT 'PROMPT ' FROM DUAL;
SELECT 'PROMPT THE FOLLOWING TRIGGERS ARE OWNED BY SYS SCHEMA AND MAY NOT BE EXIST AFTER THE IMPORT' FROM DUAL;
SELECT 'PROMPT YOU MAY CONSIDER CREATING THE NON EXIST TRIGGERS IF YOU NEED SO:' FROM DUAL;
SELECT 'PROMPT ***************************************************************' FROM DUAL;
SELECT 'PROMPT '||TRIGGER_TYPE||' TRIGGER: '||TRIGGER_NAME FROM DBA_TRIGGERS WHERE OWNER=UPPER('SYS') ORDER BY 1;
SELECT 'PROMPT ARE THESE DIRECTORIES POINTING TO THE RIGHT PATHS? ' FROM DUAL;
COL DIRECTORY FOR A50
COL DIRECTORY_PATH FOR A100
SELECT 'PROMPT '||OWNER||'.'||DIRECTORY_NAME||': '||DIRECTORY_PATH FROM DBA_DIRECTORIES;
SPOOL OFF
EOF
)
# Creation of the Post Export Script:
export DUMPFILENAME="EXPORT_FULL_DB_${ORACLE_SID}_${DUMPDATE}${PARA}.dmp"
export LOGFILE="${LOC1}/EXPORT_FULL_DB_${ORACLE_SID}_${DUMPDATE}.log"
export EXPORTSCRIPT=${LOC1}/EXPORTSCRIPT.sh
export EXPORTSCRIPTRUNNER=${LOC1}/EXPORTSCRIPTRUNNER.sh
echo "# Export Script: [Created By DBA_BUNDLE]" > ${EXPORTSCRIPT}
echo "export ORACLE_SID=${ORACLE_SID}" >>${EXPORTSCRIPT}
echo "echo 'Running The Export Job Now ...'" >>${EXPORTSCRIPT}
echo "${MKNOD}" >>${EXPORTSCRIPT}
echo "sleep 1" >>${EXPORTSCRIPT}
echo "${ZIP}" >>${EXPORTSCRIPT}
echo "${ORACLE_HOME}/bin/exp DBA_BUNDLEEXP7/\"BUNdle_#-^${PASSHALF}\" FULL=y DIRECT=y CONSISTENT=y STATISTICS=NONE FEEDBACK=100000 ${EXPORTSCN} RESUMABLE=y RESUMABLE_NAME=DBA_BUNDLE_EXPORT RESUMABLE_TIMEOUT=86400 FILE=${EXPORTDUMP} log=${LOC1}/EXPORT_FULL_DB_${ORACLE_SID}_${DUMPDATE}.log" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo 'Running Post Export Steps ...'" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF" >>${EXPORTSCRIPT}
echo "PROMPT" >>${EXPORTSCRIPT}
echo "PROMPT DROPPING THE EXPORTER USER DBA_BUNDLEEXP7 ..." >>${EXPORTSCRIPT}
echo "DROP USER DBA_BUNDLEEXP7 CASCADE;" >>${EXPORTSCRIPT}
echo "EOF" >>${EXPORTSCRIPT}
echo "sleep 3" >>${EXPORTSCRIPT}
echo "${REMOVEMKDON}" >>${EXPORTSCRIPT}
echo "echo \"*****************\"" >>${EXPORTSCRIPT}
echo "echo \"IMPORT GUIDELINES:\"" >>${EXPORTSCRIPT}
echo "echo \"*****************\"" >>${EXPORTSCRIPT}
echo "echo \"FLASHBACK SCN used for this export is: ${CURRENT_SCN}\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"${UNZIPMESSAGE}\"" >>${EXPORTSCRIPT}
echo "echo \"Later, AFTER IMPORTING THE DUMPFILE, RUN THIS SQL SCRIPT: ${SPOOLFILE2}\"" >>${EXPORTSCRIPT}
echo "echo \" => IT INCLUDES (HINT FOR TRIGGERS OWNED BY SYS) WHICH WILL NOT BE CREATED BY THE IMPORT PROCESS + COMPILING INVALID OBJECTS.\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"**************************\"" >>${EXPORTSCRIPT}
echo "echo \"EXPORT DUMP FILE LOCATION: ${EXPORTDUMPOUTPUT}\"" >>${EXPORTSCRIPT}
echo "echo \"**************************\"" >>${EXPORTSCRIPT}
echo "export JOBSTATUS=\`grep \"successfully\\|stopped\\|completed\" ${LOGFILE}|tail -1\`" >>${EXPORTSCRIPT}
echo "export LOGFILE=${LOGFILE}" >>${EXPORTSCRIPT}
echo "export EMAILID=\"${EMAILANS}\"" >>${EXPORTSCRIPT}
echo "${SENDEMAIL}" >>${EXPORTSCRIPT}
chmod 740 ${EXPORTSCRIPT}
echo
echo "#!/bin/bash" > ${EXPORTSCRIPTRUNNER}
echo "nohup sh ${EXPORTSCRIPT}| tee ${LOGFILE} 2>&1 &" >>${EXPORTSCRIPTRUNNER}
chmod 740 ${EXPORTSCRIPTRUNNER}
echo -e "\033[32;5mFeel free to EXIT from this session as the EXPORT SCRIPT is running in the BACKGROUND.\033[0m"
source ${EXPORTSCRIPTRUNNER}
## Export METADATA ONLY: <using Legacy EXP because it's more reliable than EXPDP in exporting DDLs>
#echo
#echo "CREATING A FILE CONTAINS ALL CREATION [DDL] STATEMENT OF ALL USERS|OBJECTS ..."
#sleep 1
#${ORACLE_HOME}/bin/exp DBA_BUNDLEEXP7/"BUNdle_#-^${PASSHALF}" FULL=y ROWS=N STATISTICS=NONE FILE=${LOC1}/${ORACLE_SID}_METADATA_${DUMPDATE}.dmp log=${LOC1}/${ORACLE_SID}_METADATA_${DUMPDATE}.log
## Removing Extra Bad characters: [DUMP REFINING]
#/usr/bin/strings ${LOC1}/${ORACLE_SID}_METADATA_${DUMPDATE}.dmp > ${LOC1}/${ORACLE_SID}_METADATA_REFINED_${DUMPDATE}.trc
#echo
#echo "EXTRA FILES:"
#echo "-----------"
#echo "METADATA ONLY DUMP FILE <IMPORTABLE with [legacy exp utility]>: ${LOC1}/${ORACLE_SID}_METADATA_${DUMPDATE}.dmp"
#echo "DDL Script FILE <READABLE | Cannot be Imported>: ${LOC1}/${ORACLE_SID}_METADATA_REFINED_${DUMPDATE}.trc"
#echo "*****************************************************************"
echo; exit ;;
*) echo "Enter a valid number:"
echo "====================="
echo "i.e."
echo "1 for expdp tool"
echo "2 for exp tool"
echo ;;
esac
done
break;;
2|"EXPORT SCHEMAS"|"database"|"DATABASE"|"schema"|"schemas"|"SCHEMA"|"SCHEMAS")
echo
echo "Entering EXPORT SCHEMA MODE ..."
sleep 1
# ######################
# EXPORT SCHEMA SECTION:
# ######################
echo
echo "WHICH EXPORT UTILITY YOU WANT TO USE: [1) DATAPUMP [EXPDP]]"
echo "===================================="
echo "1) DATAPUMP [EXPDP] |Pros: Faster when import, Cloud/PARALLELISM compatible, can Exclude schema/tables |Cons: COMPRESSION requires license"
echo "2) LEGACY EXPORT [EXP] |Pros: COMPRESSION can happen on the fly without license |Cons: Slower when import, No Cloud/PARALLELISM compatibility"
while read EXP_TOOL
do
case $EXP_TOOL in
""|"1"|"DATAPUMP"|"datapump"|"DATAPUMP [EXPDP]"|"[EXPDP]"|"EXPDP"|"expdp")
if [[ ${CHK_PARALLELISM_OPTION} =~ ${INT} ]]
then
if [ ${CHK_PARALLELISM_OPTION} -eq 1 ]
then
echo
echo "Enter the PARALLEL DEGREE you want to perform the export with PARALLELISM? [If used, The final dump file will be divided into multiple files!]"
echo "========================================================================="
echo "[Current CPU Count on this Server is: ${PARALLEL_DEGREE}]"
echo "Enter a number bigger than 1 to utilize PARALLELISM or enter 0 to disable PARALLELISM"
echo ""
while read PARALLEL_ANS
do
# Check if the input is an integer:
if [[ -z ${PARALLEL_ANS} ]]; then
export PARALLEL_ANS=0
fi
if [[ ${PARALLEL_ANS} =~ ${INT} ]]
then
# Check if the input is greater than 1:
if [ "${PARALLEL_ANS}" -gt 1 ]
then
export PARALLEL="PARALLEL=${PARALLEL_ANS}"
export PARA="_%u"
echo -e "\033[32;5mPARALLELISM ENABLED | The final dump file will be divided into multiple files based on the degree of parallelism you used.\033[0m"
echo
else
echo "PARALLELISM DISABLED.";echo ""
fi
break
fi
done
else
echo;echo -e "\033[32;5mPARALLELISM option is not available in the current Database Edition.\033[0m"
fi
fi
# PARAMETER FILE CREATION:
export DUMPFILENAME="EXPORT_SCHEMA_${ORACLE_SID}_${DUMPDATE}${PARA}.dmp"
export LOGFILE="${LOC1}/EXPORT_SCHEMA_${ORACLE_SID}_${DUMPDATE}.log"
# PARAMETER FILE CREATION:
PARFILE=${LOC1}/EXPORT_SCHEMA_DB_${ORACLE_SID}.par
echo "# SCHEMA EXPORT PARAMETER FILE CREATED BY export_data.sh SCRIPT on [${DUMPDATE}]: [${ORACLE_SID}]" > ${PARFILE}
echo "DIRECTORY=EXPORT_FILES_DBA_BUNDLE" >> ${PARFILE}
echo "DUMPFILE=${DUMPFILENAME}" >> ${PARFILE}
echo "LOGFILE=EXPORT_SCHEMA_${ORACLE_SID}_${DUMPDATE}.log" >> ${PARFILE}
echo "${EXPORTSCN}" >> ${PARFILE}
echo "${REUSE_DUMP}" >> ${PARFILE}
echo "${PARALLEL}" >> ${PARFILE}
echo
echo "Enter the SCHEMAS you want to export, separating them by comma:"
echo "=============================================================="
echo "i.e. HR,SCOTT,OE"
echo ""
while read SCHEMASVAR
do
case ${SCHEMASVAR} in
"") echo; echo "Please Enter the Schema Name you want to export:"
echo "-----------------------------------------------"
echo "i.e. SCOTT,HR,OE"
echo "";;
*) echo
# Convert User's input into UPPERCASE:
export SCHEMASVAR="$(echo ${SCHEMASVAR}| tr [:lower:] [:upper:])"
export SCHEMA="SCHEMAS=${SCHEMASVAR}"
echo ${SCHEMA} >> ${PARFILE}
export SCHEMALIST="'$(sed s/,/\',\'/g <<<${SCHEMASVAR}| tr '[:lower:]' '[:upper:]')'"; break ;;
esac
done
echo ""
echo "Enter the TABLES you want to EXCLUDE from the export, separating them by comma:"
echo "==============================================================================="
echo "i.e. EMP,DEPT"
echo "[Leave it BLANK and hit Enter if you do NOT want to exclude any TABLES]"
echo ""
while read EXCLUDETABLEVAR
do
case ${EXCLUDETABLEVAR} in
"") echo; export EXCLUDETABLE=""; break ;;
*) echo; export EXCLUDETABLE="EXCLUDE=TABLE:\"IN('$(sed s/,/\',\'/g <<<${EXCLUDETABLEVAR}| tr '[:lower:]' '[:upper:]')')\""
echo ${EXCLUDETABLE} >> ${PARFILE}; break ;;
esac
done
echo
printf "`echo "Do you want to enable the COMPRESSION [Y|N] [N] [Do NOT answer with YES unless you already acquired the"` `echo -e "\033[33;5mAdvanced Compression License\033[0m"` `echo "]"`\n"
echo "====================================="
while read COMP_ANS
do
case $COMP_ANS in
y|Y|yes|YES|Yes) echo;echo "COMPRESSION=ALL" >> ${PARFILE};echo -e "\033[32;5mCompression Enabled.\033[0m";echo; break ;;
""|n|N|no|NO|No) echo; echo "COMPRESSION DISABLED."; echo; break ;;
*) echo;echo "Please Enter a Valid Answer: [Y|N]"
echo "----------------------------";;
esac
done
echo
echo "Enter the CONTENT of data you want to Export:"
echo "============================================="
echo "1. DATA+METADATA [DEFAULT]"
echo "2. METADATA_ONLY [DDL]"
echo "3. DATA_ONLY"
echo ""
while read CONTENTVAR
do
case ${CONTENTVAR} in
""|"DATA+METADATA"|1) echo; echo "EXPORT MODE IS SET TO: [DATA + METADATA]"; echo; break ;;
"METADATA_ONLY"|"metadata_only"|"METADATA"|"metadata"|"DDL"|"ddl"|2) echo; export CONTENTVAR="CONTENT=METADATA_ONLY"; echo ${CONTENTVAR} >> ${PARFILE}; echo "EXPORT MODE IS SET TO: [METADATA_ONLY]"; echo; break ;;
"DATA_ONLY"|"data_only"|"DATA"|"data"|3) echo; export CONTENTVAR="CONTENT=DATA_ONLY"; echo ${CONTENTVAR} >> ${PARFILE}; echo "EXPORT MODE IS SET TO: [DATA_ONLY]"; echo; break ;;
*) echo; echo "Enter a correct option number between 1 to 3:"
echo "--------------------------------------------";;
esac
done
echo
echo "Enter the VERSION: [In case you want to import this dump later on a DB with LOWER version] | [Allowed value start from 9.2 and above] "
echo "================="
echo "e.g. If you will import this dump on a 10g DB then enter 10"
echo "For DEFAULT compatibility leave it BLANK."
echo ""
while read VERSION
do
case ${VERSION} in
""|"COMPATIBLE"|"compatible") echo; echo "DUMPFILE COMPATIBILITY version is set to the current DB compatibility level."; echo; break ;;
[0-9]) echo; echo "Wrong version number, this value cannot be set lower than 9.2!"
echo; echo "Enter a correct version higher than 9.2:"
echo "----------------------------------------";;
*) echo; VERSION="VERSION=${VERSION}"; echo ${VERSION} >> ${PARFILE}; echo "DUMPFILE COMPATIBILITY version is set to ${VERSION}."; echo; break ;;
esac
done
echo
echo "You are almost done!"; echo
sleep 1
echo "Please verify the export settings summary:"
echo "------------------------------------------"
cat ${PARFILE}
echo
sleep 1
echo "Shall we start the EXPORT job now? [[YES] | NO]"
echo "=================================="
while read STARTNOW
do
case ${STARTNOW} in
N|n|NO|no) echo; echo "SCRIPT TERMINATED! "; echo; exit;;
""|Y|y|YES|yes) echo; echo "STARTING THE IMPORT ..."; echo; break;;
*) echo "Please enter a valid answer: [YES|NO]";;
esac
done
cd ${LOC1}
SPOOLFILE1=${LOC1}/BEFORE_IMPORT_SCHEMA_${ORACLE_SID}_${DUMPDATE}.sql
SPOOLFILE2=${LOC1}/AFTER_IMPORT_SCHEMA_${ORACLE_SID}_${DUMPDATE}.sql
echo "Creating the Exporter User DBA_BUNDLEEXP7 ..."
echo "Preparing the BEFORE and AFTER import script which will help you import the dump file later ..."
VAL11=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
PROMPT CREATE USER DBA_BUNDLEEXP7 [EXPORTER USER] (WILL BE DROPPED AFTER THE EXPORT) ...
CREATE USER DBA_BUNDLEEXP7 IDENTIFIED BY "BUNdle_#-^${PASSHALF}";
ALTER USER DBA_BUNDLEEXP7 IDENTIFIED BY "BUNdle_#-^${PASSHALF}" ACCOUNT UNLOCK;
GRANT CREATE SESSION TO DBA_BUNDLEEXP7;
GRANT DBA TO DBA_BUNDLEEXP7;
-- The following privileges to workaround Bug 6392040:
GRANT EXECUTE ON SYS.DBMS_DEFER_IMPORT_INTERNAL TO DBA_BUNDLEEXP7;
GRANT EXECUTE ON SYS.DBMS_EXPORT_EXTENSION TO DBA_BUNDLEEXP7;
PROMPT
PROMPT CREATING DIRECTORY EXPORT_FILES_DBA_BUNDLE POINTING TO ${LOC1} ...
CREATE OR REPLACE DIRECTORY EXPORT_FILES_DBA_BUNDLE AS '${LOC1}';
PROMPT
PROMPT CREATING BEFORE SCHEMA IMPORT SCRIPT ...
PROMPT
SET PAGES 0 TERMOUT OFF LINESIZE 157 ECHO OFF FEEDBACK OFF
SPOOL ${SPOOLFILE1}
SELECT 'CREATE USER ' || u.username ||' IDENTIFIED ' ||' BY VALUES ''' || c.password || ''' DEFAULT TABLESPACE ' || u.default_tablespace ||' TEMPORARY TABLESPACE ' || u.temporary_tablespace ||' PROFILE ' || u.profile || case when account_status= 'OPEN' then ';' else ' Account LOCK;' end "--Creation Statement"
FROM dba_users u,user$ c where u.username=c.name and u.username in (${SCHEMALIST})
UNION
SELECT 'CREATE ROLE '||GRANTED_ROLE||';' FROM DBA_ROLE_PRIVS WHERE GRANTEE in (${SCHEMALIST})
UNION
select 'GRANT '||GRANTED_ROLE||' TO '||GRANTEE|| case when ADMIN_OPTION='YES' then ' WITH ADMIN OPTION;' else ';' end "Granted Roles"
from dba_role_privs where grantee in (${SCHEMALIST})
UNION
select 'GRANT '||PRIVILEGE||' TO '||GRANTEE|| case when ADMIN_OPTION='YES' then ' WITH ADMIN OPTION;' else ';' end "Granted System Privileges"
from dba_sys_privs where grantee in (${SCHEMALIST})
UNION
select 'GRANT '||PRIVILEGE||' ON '||OWNER||'.'||TABLE_NAME||' TO '||GRANTEE||case when GRANTABLE='YES' then ' WITH GRANT OPTION;' else ';' end "Granted Object Privileges" from DBA_TAB_PRIVS where GRANTEE in (${SCHEMALIST});
SPOOL OFF
PROMPT CREATING AFTER SCHEMA IMPORT SCRIPT ...
PROMPT
SPOOL ${SPOOLFILE2}
select 'GRANT '||PRIVILEGE||' ON '||OWNER||'.'||TABLE_NAME||' TO '||GRANTEE||case when GRANTABLE='YES' then ' WITH GRANT OPTION;' else ';' end "Granted Object Privileges" from DBA_TAB_PRIVS where OWNER in (${SCHEMALIST})
UNION
SELECT 'CREATE PUBLIC SYNONYM '||SYNONYM_NAME||' FOR '||TABLE_OWNER||'.'||TABLE_NAME||';' FROM DBA_SYNONYMS WHERE TABLE_OWNER in (${SCHEMALIST}) AND OWNER=UPPER('PUBLIC');
PROMPT
SELECT 'PROMPT COMPILING DATABASE INVALID OBJECTS ...' FROM DUAL;
SELECT '@?/rdbms/admin/utlrp' FROM DUAL;
SELECT '@?/rdbms/admin/utlrp' FROM DUAL;
SELECT 'PROMPT ' FROM DUAL;
SELECT 'PROMPT THE FOLLOWING TRIGGERS ARE OWNED BY OTHER USERS BUT ARE DEPENDANT ON THE EXPORTED SCHEMAS OBJECTS' FROM DUAL;
SELECT 'PROMPT YOU MAY CONSIDER TO CREATE THEM AFTER THE SCHEMA IMPORT IF YOU NEED SO:' FROM DUAL;
SELECT 'PROMPT **********************************************************************' FROM DUAL;
SELECT 'PROMPT '||TRIGGER_TYPE||' TRIGGER: '||OWNER||'.'||TRIGGER_NAME||' =>ON TABLE: '||TABLE_OWNER||'.'||TABLE_NAME FROM DBA_TRIGGERS WHERE TABLE_OWNER IN (${SCHEMALIST}) AND OWNER NOT IN (${SCHEMALIST}) ORDER BY 1;
SPOOL OFF
EOF
)
echo
# Creation of the Export Script:
export EXPORTSCRIPT=${LOC1}/EXPORTSCRIPT.sh
export EXPORTSCRIPTRUNNER=${LOC1}/EXPORTSCRIPTRUNNER.sh
echo "# Export Script: [Created By DBA_BUNDLE]" > ${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"While the Export job is running, you can check the STATUS using:\"" >>${EXPORTSCRIPT}
echo "echo \"--------------------------------------------------------------- \"" >>${EXPORTSCRIPT}
echo "echo \"SELECT job_name, operation, job_mode, DEGREE, state FROM dba_datapump_jobs where OPERATION='EXPORT' and state='EXECUTING' and owner_name='DBA_BUNDLEEXP7';\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"Then you can ATTACH to the export job and control it using:\"" >>${EXPORTSCRIPT}
echo "echo \"---------------------------------------------------------- \"" >>${EXPORTSCRIPT}
echo "echo \"expdp DBA_BUNDLEEXP7/\"BUNdle_#-^${PASSHALF}\" ATTACH=<JOB_NAME_FROM_ABOVE_COMMAND>\"" >>${EXPORTSCRIPT}
echo "echo \"i.e.\"" >>${EXPORTSCRIPT}
echo "echo \"expdp DBA_BUNDLEEXP7/\"BUNdle_#-^${PASSHALF}\" ATTACH=SYS_EXPORT_SCHEMA_01\"" >>${EXPORTSCRIPT}
echo "echo \"To Show the STATUS:....... STATUS\"" >>${EXPORTSCRIPT}
echo "echo \"To KILL the export:....... KILL_JOB\"" >>${EXPORTSCRIPT}
echo "echo \"To PAUSE the export:...... STOP_JOB\"" >>${EXPORTSCRIPT}
echo "echo \"To RESUME a paused export: START_JOB\"" >>${EXPORTSCRIPT}
echo "export ORACLE_SID=${ORACLE_SID}" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo 'Running The Export Job Now ...'" >>${EXPORTSCRIPT}
echo "${ORACLE_HOME}/bin/expdp DBA_BUNDLEEXP7/\"BUNdle_#-^${PASSHALF}\" PARFILE=${PARFILE}" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo 'Running Post Export Steps ...'" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF" >>${EXPORTSCRIPT}
echo "PROMPT" >>${EXPORTSCRIPT}
echo "PROMPT DROPPING THE EXPORTER USER DBA_BUNDLEEXP7 ..." >>${EXPORTSCRIPT}
echo "DROP USER DBA_BUNDLEEXP7 CASCADE;" >>${EXPORTSCRIPT}
echo "EOF" >>${EXPORTSCRIPT}
echo "echo \"*****************\"" >>${EXPORTSCRIPT}
echo "echo \"IMPORT GUIDELINES:\"" >>${EXPORTSCRIPT}
echo "echo \"*****************\"" >>${EXPORTSCRIPT}
echo "echo \"FLASHBACK SCN used for this export is: ${CURRENT_SCN}\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"BEFORE IMPORTING THE DUMPFILE IT'S RECOMMENDED TO RUN THIS SQL SCRIPT: ${SPOOLFILE1}\"" >>${EXPORTSCRIPT}
echo "echo \"It includes (USER|ROLES|GRANTED PRIVILEGES CREATION STATEMENTS), WHICH WILL NOT BE CREATED DURING THE IMPORT PROCESS.\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"AFTER IMPORTING THE DUMPFILE, RUN THIS SQL SCRIPT: ${SPOOLFILE2}\"" >>${EXPORTSCRIPT}
echo "echo \"It includes (Public Synonyms DDLs, Privileges granted to others, Hints for Triggers owned by others but depending on the exported schemas objects) + COMPILING INVALID OBJECTS, SUCH STUFF WILL NOT BE CARRIED OUT BY THE IMPORT PROCESS.\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"**************************\"" >>${EXPORTSCRIPT}
echo "echo \"EXPORT DUMP FILE LOCATION: ${LOC1}/${DUMPFILENAME}\"" >>${EXPORTSCRIPT}
echo "echo \"**************************\"" >>${EXPORTSCRIPT}
echo "export JOBSTATUS=\`grep \"successfully\\|stopped\\|completed\" ${LOGFILE}|tail -1\`" >>${EXPORTSCRIPT}
echo "export LOGFILE=${LOGFILE}" >>${EXPORTSCRIPT}
echo "export EMAILID=\"${EMAILANS}\"" >>${EXPORTSCRIPT}
echo "${SENDEMAIL}" >>${EXPORTSCRIPT}
chmod 740 ${EXPORTSCRIPT}
echo
echo "#!/bin/bash" > ${EXPORTSCRIPTRUNNER}
echo "nohup sh ${EXPORTSCRIPT}| tee ${LOGFILE} 2>&1 &" >>${EXPORTSCRIPTRUNNER}
chmod 740 ${EXPORTSCRIPTRUNNER}
echo -e "\033[32;5mFeel free to EXIT from this session as the EXPORT SCRIPT is running in the BACKGROUND.\033[0m"
source ${EXPORTSCRIPTRUNNER}
## Export METADATA ONLY: <using Legacy EXP because it's more reliable than EXPDP in exporting DDLs>
#echo;echo "CREATING A FILE CONTAINS ALL CREATION [DDL] STATEMENT OF ALL USERS|OBJECTS ...";sleep 1
#${ORACLE_HOME}/bin/exp DBA_BUNDLEEXP7/"BUNdle_#-^${PASSHALF}" FULL=y ROWS=N STATISTICS=NONE FILE=${LOC1}/${ORACLE_SID}_METADATA_${DUMPDATE}.dmp log=${LOC1}/${ORACLE_SID}_METADATA_${DUMPDATE}.log
## Getting READABLE export script: [DUMP REFINING]
#/usr/bin/strings ${LOC1}/${ORACLE_SID}_METADATA_${DUMPDATE}.dmp > ${LOC1}/${ORACLE_SID}_METADATA_REFINED_${DUMPDATE}.trc
echo; exit ;;
"2"|"LEGACY EXPORT"|"LEGACY"|"EXPORT"|"LEGACY EXPORT [EXP]"|"EXP"|"[EXP]"|"exp"|"legacy export"|"legacy"|"export")
DUMPFILE="${LOC1}/EXPORT_SCHEMA_${ORACLE_SID}_${DUMPDATE}.dmp"
LOGFILE="${LOC1}/EXPORT_SCHEMA_${ORACLE_SID}_${DUMPDATE}.log"
echo
echo "Enter the SCHEMAS you want to export, separating them by comma:"
echo "=============================================================="
echo "i.e. HR,SCOTT,OE"
echo ""
while read SCHEMASVAR
do
case ${SCHEMASVAR} in
"") echo; echo "Please Enter the Schema Name you want to export: [i.e. SCOTT,HR,OE]"
echo "-----------------------------------------------";;
*) echo
# Convert User's input into UPPERCASE:
export SCHEMASVAR="$(echo ${SCHEMASVAR}| tr [:lower:] [:upper:])"
export SCHEMALIST="'$(sed s/,/\',\'/g <<<${SCHEMASVAR}| tr '[:lower:]' '[:upper:]')'"; break ;;
esac
done
export EXPORTDUMP="${LOC1}/EXPORT_SCHEMA_${ORACLE_SID}_${DUMPDATE}.dmp"
export LOGFILE="${LOC1}/EXPORT_SCHEMA_${ORACLE_SID}_${DUMPDATE}.log"
echo
printf "`echo "Do you want to enable the COMPRESSION [Y|N] [N] [COMPRESSION will happen on the fly using mknod |"` `echo -e "\033[33;5mNo License required\033[0m"` `echo "]"`\n"
echo "====================================="
while read COMP_ANS
do
case $COMP_ANS in
y|Y|yes|YES|Yes) echo;export EXPORTDUMP="${LOC1}/EXPORT_SCHEMA_${ORACLE_SID}_${DUMPDATE}_pipe.dmp"
export MKNOD="rm -f ${EXPORTDUMP}; mknod ${EXPORTDUMP} p"
export ZIP="nohup bzip2 -fz < ${EXPORTDUMP} > ${LOC1}/EXPORT_SCHEMA_${ORACLE_SID}_${DUMPDATE}.dmp.bz2 &"
export EXPORTDUMPOUTPUT="${LOC1}/EXPORT_SCHEMA_${ORACLE_SID}_${DUMPDATE}.dmp.bz2"
export REMOVEMKDON="rm -f ${EXPORTDUMP}"
export UNZIPMESSAGE="First DE-COMPRESS the file using this command: bunzip2 -f ${EXPORTDUMPOUTPUT}"
echo -e "\033[32;5mCompression Enabled.\033[0m";echo; break ;;
""|n|N|no|NO|No) echo;export MKNOD=""
export ZIP=""
export EXPORTDUMP="${LOC1}/EXPORT_SCHEMA_${ORACLE_SID}_${DUMPDATE}.dmp"
export EXPORTDUMPOUTPUT="${LOC1}/EXPORT_SCHEMA_${ORACLE_SID}_${DUMPDATE}.dmp";break ;;
*) echo;echo "Please Enter a Valid Answer [Y|N]"
echo "---------------------------------";;
esac
done
cd ${LOC1}
SPOOLFILE1=${LOC1}/BEFORE_IMPORT_SCHEMA_${ORACLE_SID}_${DUMPDATE}.sql
SPOOLFILE2=${LOC1}/AFTER_IMPORT_SCHEMA_${ORACLE_SID}_${DUMPDATE}.sql
echo "Creating the Exporter User DBA_BUNDLEEXP7 ..."
echo "Preparing the BEFORE and AFTER import script which will help you import the dump file later ..."
VAL11=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
PROMPT CREATE USER DBA_BUNDLEEXP7 [EXPORTER USER] (WILL BE DROPPED AFTER THE EXPORT) ...
CREATE USER DBA_BUNDLEEXP7 IDENTIFIED BY "BUNdle_#-^${PASSHALF}";
ALTER USER DBA_BUNDLEEXP7 IDENTIFIED BY "BUNdle_#-^${PASSHALF}" ACCOUNT UNLOCK;
GRANT CREATE SESSION TO DBA_BUNDLEEXP7;
GRANT DBA TO DBA_BUNDLEEXP7;
-- The following privileges to workaround Bug 6392040:
GRANT EXECUTE ON SYS.DBMS_DEFER_IMPORT_INTERNAL TO DBA_BUNDLEEXP7;
GRANT EXECUTE ON SYS.DBMS_EXPORT_EXTENSION TO DBA_BUNDLEEXP7;
PROMPT
PROMPT CREATING DIRECTORY EXPORT_FILES_DBA_BUNDLE POINTING TO ${LOC1} ...
CREATE OR REPLACE DIRECTORY EXPORT_FILES_DBA_BUNDLE AS '${LOC1}';
PROMPT
PROMPT CREATING BEFORE SCHEMA IMPORT SCRIPT ...
PROMPT
SET PAGES 0 TERMOUT OFF LINESIZE 157 ECHO OFF FEEDBACK OFF
SPOOL ${SPOOLFILE1}
SELECT 'CREATE USER ' || u.username ||' IDENTIFIED ' ||' BY VALUES ''' || c.password || ''' DEFAULT TABLESPACE ' || u.default_tablespace ||' TEMPORARY TABLESPACE ' || u.temporary_tablespace ||' PROFILE ' || u.profile || case when account_status= 'OPEN' then ';' else ' Account LOCK;' end "--Creation Statement"
FROM dba_users u,user$ c where u.username=c.name and u.username in (${SCHEMALIST})
UNION
SELECT 'CREATE ROLE '||GRANTED_ROLE||';' FROM DBA_ROLE_PRIVS WHERE GRANTEE in (${SCHEMALIST})
UNION
select 'GRANT '||GRANTED_ROLE||' TO '||GRANTEE|| case when ADMIN_OPTION='YES' then ' WITH ADMIN OPTION;' else ';' end "Granted Roles"
from dba_role_privs where grantee in (${SCHEMALIST})
UNION
select 'GRANT '||PRIVILEGE||' TO '||GRANTEE|| case when ADMIN_OPTION='YES' then ' WITH ADMIN OPTION;' else ';' end "Granted System Privileges"
from dba_sys_privs where grantee in (${SCHEMALIST})
UNION
select 'GRANT '||PRIVILEGE||' ON '||OWNER||'.'||TABLE_NAME||' TO '||GRANTEE||case when GRANTABLE='YES' then ' WITH GRANT OPTION;' else ';' end "Granted Object Privileges" from DBA_TAB_PRIVS where GRANTEE in (${SCHEMALIST});
SPOOL OFF
PROMPT CREATING AFTER SCHEMA IMPORT SCRIPT ...
PROMPT
SPOOL ${SPOOLFILE2}
select 'GRANT '||PRIVILEGE||' ON '||OWNER||'.'||TABLE_NAME||' TO '||GRANTEE||case when GRANTABLE='YES' then ' WITH GRANT OPTION;' else ';' end "Granted Object Privileges" from DBA_TAB_PRIVS where OWNER in (${SCHEMALIST})
UNION
SELECT 'CREATE PUBLIC SYNONYM '||SYNONYM_NAME||' FOR '||TABLE_OWNER||'.'||TABLE_NAME||';' FROM DBA_SYNONYMS WHERE TABLE_OWNER in (${SCHEMALIST}) AND OWNER=UPPER('PUBLIC');
PROMPT
SELECT 'PROMPT COMPILING DATABASE INVALID OBJECTS ...' FROM DUAL;
SELECT '@?/rdbms/admin/utlrp' FROM DUAL;
SELECT '@?/rdbms/admin/utlrp' FROM DUAL;
SELECT 'PROMPT ' FROM DUAL;
SELECT 'PROMPT THE FOLLOWING TRIGGERS ARE OWNED BY OTHER USERS BUT ARE DEPENDANT ON THE EXPORTED SCHEMA OBJECTS' FROM DUAL;
SELECT 'PROMPT YOU MAY CONSIDER TO CREATE THEM AFTER THE SCHEMA IMPORT IF YOU NEED SO:' FROM DUAL;
SELECT 'PROMPT **********************************************************************' FROM DUAL;
SELECT 'PROMPT '||TRIGGER_TYPE||' TRIGGER: '||OWNER||'.'||TRIGGER_NAME||' =>ON TABLE: '||TABLE_OWNER||'.'||TABLE_NAME FROM DBA_TRIGGERS WHERE TABLE_OWNER in (${SCHEMALIST}) AND OWNER not in (${SCHEMALIST}) ORDER BY 1;
SPOOL OFF
EOF
)
# Creation of the Post Export Script:
export EXPORTSCRIPT=${LOC1}/EXPORTSCRIPT.sh
export EXPORTSCRIPTRUNNER=${LOC1}/EXPORTSCRIPTRUNNER.sh
echo "# Export Script: [Created By DBA_BUNDLE]" > ${EXPORTSCRIPT}
echo "export ORACLE_SID=${ORACLE_SID}" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo 'Running The Export Job Now ...'" >>${EXPORTSCRIPT}
echo "${MKNOD}" >>${EXPORTSCRIPT}
echo "sleep 1" >>${EXPORTSCRIPT}
echo "${ZIP}" >>${EXPORTSCRIPT}
echo "${ORACLE_HOME}/bin/exp DBA_BUNDLEEXP7/\"BUNdle_#-^${PASSHALF}\" OWNER=${SCHEMASVAR} DIRECT=y CONSISTENT=y STATISTICS=NONE FEEDBACK=100000 ${EXPORTSCN} RESUMABLE=y RESUMABLE_NAME=DBA_BUNDLE_EXPORT RESUMABLE_TIMEOUT=86400 FILE=${EXPORTDUMP} log=${LOGFILE}">>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo 'Running Post Export Steps ...'" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF" >>${EXPORTSCRIPT}
echo "PROMPT" >>${EXPORTSCRIPT}
echo "PROMPT DROPPING THE EXPORTER USER DBA_BUNDLEEXP7 ..." >>${EXPORTSCRIPT}
echo "DROP USER DBA_BUNDLEEXP7 CASCADE;" >>${EXPORTSCRIPT}
echo "EOF" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "sleep 3" >>${EXPORTSCRIPT}
echo "${REMOVEMKDON}" >>${EXPORTSCRIPT}
echo "echo \"*****************\"" >>${EXPORTSCRIPT}
echo "echo \"IMPORT GUIDELINES:\"" >>${EXPORTSCRIPT}
echo "echo \"*****************\"" >>${EXPORTSCRIPT}
echo "echo \"FLASHBACK SCN used for this export is: ${CURRENT_SCN}\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"${UNZIPMESSAGE}\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"BEFORE IMPORTING THE DUMPFILE IT'S RECOMMENDED TO RUN THIS SQL SCRIPT: ${SPOOLFILE1}\"" >>${EXPORTSCRIPT}
echo "echo \"It includes (USER|ROLES|GRANTED PRIVILEGES CREATION STATEMENTS), WHICH WILL NOT BE CREATED DURING THE IMPORT PROCESS.\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"AFTER IMPORTING THE DUMPFILE, RUN THIS SQL SCRIPT: ${SPOOLFILE2}\"" >>${EXPORTSCRIPT}
echo "echo \"It includes (Public Synonyms DDLs, Privileges granted to others, Hints for Triggers owned by others but depending on the exported schemas objects) + COMPILING INVALID OBJECTS, SUCH STUFF WILL NOT BE CARRIED OUT BY THE IMPORT PROCESS.\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"**************************\"" >>${EXPORTSCRIPT}
echo "echo \"EXPORT DUMP FILE LOCATION: ${EXPORTDUMPOUTPUT}\"" >>${EXPORTSCRIPT}
echo "echo \"**************************\"" >>${EXPORTSCRIPT}
echo "export JOBSTATUS=\`grep \"successfully\\|stopped\\|completed\" ${LOGFILE}|tail -1\`" >>${EXPORTSCRIPT}
echo "export LOGFILE=${LOGFILE}" >>${EXPORTSCRIPT}
echo "export EMAILID=\"${EMAILANS}\"" >>${EXPORTSCRIPT}
echo "${SENDEMAIL}" >>${EXPORTSCRIPT}
chmod 740 ${EXPORTSCRIPT}
echo
echo "#!/bin/bash" > ${EXPORTSCRIPTRUNNER}
echo "nohup sh ${EXPORTSCRIPT}| tee ${LOGFILE} 2>&1 &" >>${EXPORTSCRIPTRUNNER}
chmod 740 ${EXPORTSCRIPTRUNNER}
echo -e "\033[32;5mFeel free to EXIT from this session as the EXPORT SCRIPT is running in the BACKGROUND.\033[0m"
source ${EXPORTSCRIPTRUNNER}
## Export METADATA ONLY: <using Legacy EXP because it's more reliable than EXPDP in exporting DDLs>
#echo
#echo "CREATING A FILE CONTAINS ALL CREATION [DDL] STATEMENT OF ALL USERS|OBJECTS ..."
#sleep 1
#${ORACLE_HOME}/bin/exp DBA_BUNDLEEXP7/"BUNdle_#-^${PASSHALF}" OWNER=${SCHEMA_NAME} ROWS=N STATISTICS=NONE FILE=${LOC1}/${SCHEMA_NAME}_${ORACLE_SID}_METADATA_${DUMPDATE}.dmp log=${LOC1}/${SCHEMA_NAME}_${ORACLE_SID}_METADATA_${DUMPDATE}.log
## Removing Extra Bad characters: [DUMP REFINING]
#/usr/bin/strings ${LOC1}/${SCHEMA_NAME}_${ORACLE_SID}_METADATA_${DUMPDATE}.dmp > ${LOC1}/${SCHEMA_NAME}_${ORACLE_SID}_METADATA_REFINED_${DUMPDATE}.trc
echo; exit ;;
*) echo "Enter a valid number:"
echo "====================="
echo "i.e."
echo "1 for expdp tool"
echo "2 for exp tool"
echo ;;
esac
done
break;;
3|"EXPORT TABLES"|"TABLES"|"tables"|"table") echo; echo "Entering EXPORT TABLE MODE ...";echo;sleep 1
# #####################
# EXPORT TABLE SECTION:
# #####################
echo
echo "Enter the TABLES you want to export, separating them by comma:"
echo "=============================================================="
echo "i.e. HR.EMPLOYEES,HR.DEPARTMENTS,SCOTT.BONUS"
echo ""
while read TABLESVAR
do
case ${TABLESVAR} in
"") echo; echo "Please mention the tables you want to export:"
echo "--------------------------------------------"
echo "i.e. HR.EMPLOYEES,HR.DEPARTMENTS,SCOTT.BONUS"
echo "";;
*) echo
# Convert User's input into UPPERCASE:
export TABLESVAR="$(echo ${TABLESVAR}| tr [:lower:] [:upper:])"
export TABLELIST="'$(sed s/,/\',\'/g <<<${TABLESVAR}| tr '[:lower:]' '[:upper:]')'"; break ;;
esac
done
echo "WHICH EXPORT UTILITY YOU WANT TO USE: [1) DATAPUMP [EXPDP]]"
echo "===================================="
echo "1) DATAPUMP [EXPDP] |Pros: Faster when import, Cloud/PARALLELISM compatible, can Exclude schema/tables |Cons: COMPRESSION requires license"
echo "2) LEGACY EXPORT [EXP] |Pros: COMPRESSION can happen on the fly without license |Cons: Slower when import, No Cloud/PARALLELISM compatibility"
while read EXP_TOOL
do
case $EXP_TOOL in
""|"1"|"DATAPUMP"|"datapump"|"DATAPUMP [EXPDP]"|"[EXPDP]"|"EXPDP"|"expdp")
if [[ ${CHK_PARALLELISM_OPTION} =~ ${INT} ]]
then
if [ ${CHK_PARALLELISM_OPTION} -eq 1 ]
then
echo
echo "Enter the PARALLEL DEGREE you want to perform the export with PARALLELISM? [If used, The final dump file will be divided into multiple files!]"
echo "========================================================================="
echo "[Current CPU Count on this Server is: ${PARALLEL_DEGREE}]"
echo "Enter a number bigger than 1 to utilize PARALLELISM or enter 0 to disable PARALLELISM"
echo ""
while read PARALLEL_ANS
do
# Check if the input is an integer:
if [[ -z ${PARALLEL_ANS} ]]; then
export PARALLEL_ANS=0
fi
if [[ ${PARALLEL_ANS} =~ ${INT} ]]
then
# Check if the input is greater than 1:
if [ "${PARALLEL_ANS}" -gt 1 ]
then
export PARALLEL="PARALLEL=${PARALLEL_ANS}"
export PARA="_%u"
echo -e "\033[32;5mPARALLELISM ENABLED | The final dump file will be divided into multiple files based on the degree of parallelism you used.\033[0m"
echo
else
echo "PARALLELISM DISABLED.";echo ""
fi
break
fi
done
else
echo;echo -e "\033[32;5mPARALLELISM option is not available in the current Database Edition.\033[0m"
fi
fi
# PARAMETER FILE CREATION:
export DUMPFILENAME="EXPORT_TABLE_${ORACLE_SID}_${DUMPDATE}${PARA}.dmp"
export LOGFILE="${LOC1}/EXPORT_TABLE_${ORACLE_SID}_${DUMPDATE}.log"
# PARAMETER FILE CREATION:
PARFILE=${LOC1}/EXPORT_TABLE_DB_${ORACLE_SID}.par
echo "# TABLE EXPORT PARAMETER FILE CREATED BY export_data.sh SCRIPT on [${DUMPDATE}]: [${ORACLE_SID}]" > ${PARFILE}
echo "DIRECTORY=EXPORT_FILES_DBA_BUNDLE" >> ${PARFILE}
echo "DUMPFILE=${DUMPFILENAME}" >> ${PARFILE}
echo "LOGFILE=EXPORT_TABLE_${ORACLE_SID}_${DUMPDATE}.log" >> ${PARFILE}
echo "${EXPORTSCN}" >> ${PARFILE}
echo "${REUSE_DUMP}" >> ${PARFILE}
echo "TABLES=${TABLESVAR}" >> ${PARFILE}
echo "${PARALLEL}" >> ${PARFILE}
echo
printf "`echo "Do you want to enable the COMPRESSION [Y|N] [N] [Do NOT answer with YES unless you already acquired the"` `echo -e "\033[33;5mAdvanced Compression License\033[0m"` `echo "]"`\n"
echo "====================================="
while read COMP_ANS
do case $COMP_ANS in
y|Y|yes|YES|Yes) echo;echo "COMPRESSION=ALL" >> ${PARFILE};echo -e "\033[32;5mCompression Enabled.\033[0m";echo; break ;;
""|n|N|no|NO|No) echo; echo "COMPRESSION DISABLED."; echo; break ;;
*) echo;echo "Please Enter a Valid Answer: [Y|N]"
echo "----------------------------";;
esac
done
echo
echo "Enter the CONTENT of data you want to Export:"
echo "============================================="
echo "1. DATA+METADATA [DEFAULT]"
echo "2. METADATA_ONLY [DDL]"
echo "3. DATA_ONLY"
echo ""
while read CONTENTVAR
do
case ${CONTENTVAR} in
""|"DATA+METADATA"|1) echo; echo "EXPORT MODE IS SET TO: [DATA + METADATA]"; echo; break ;;
"METADATA_ONLY"|"metadata_only"|"METADATA"|"metadata"|"DDL"|"ddl"|2) echo; export CONTENTVAR="CONTENT=METADATA_ONLY"; echo ${CONTENTVAR} >> ${PARFILE}; echo "EXPORT MODE IS SET TO: [METADATA_ONLY]"; echo; break ;;
"DATA_ONLY"|"data_only"|"DATA"|"data"|3) echo; export CONTENTVAR="CONTENT=DATA_ONLY"; echo ${CONTENTVAR} >> ${PARFILE}; echo "EXPORT MODE IS SET TO: [DATA_ONLY]"; echo; break ;;
*) echo; echo "Enter a correct option number between 1 to 3:"
echo "--------------------------------------------";;
esac
done
echo
echo "Enter the VERSION: [In case you want to import this dump later on a DB with LOWER version] | [Allowed value start from 9.2 and above] "
echo "================="
echo "e.g. If you will import this dump on a 10g DB then enter 10"
echo "For DEFAULT compatibility leave it BLANK."
echo ""
while read VERSION
do
case ${VERSION} in
""|"COMPATIBLE"|"compatible") echo; echo "DUMPFILE COMPATIBILITY version is set to the current DB compatibility level."; echo; break ;;
[0-9]) echo; echo "Wrong version number, this value cannot be set lower than 9.2!"
echo; echo "Enter a correct version higher than 9.2:"
echo "----------------------------------------";;
*) echo; VERSION="VERSION=${VERSION}"; echo ${VERSION} >> ${PARFILE}; echo "DUMPFILE COMPATIBILITY version is set to ${VERSION}."; echo; break ;;
esac
done
echo
echo "You are almost done!"; echo
sleep 1
echo "Please verify the export settings summary:"
echo "------------------------------------------"
cat ${PARFILE}
echo
sleep 1
echo "Shall we start the EXPORT job now? [[YES] | NO]"
echo "=================================="
while read STARTNOW
do
case ${STARTNOW} in
N|n|NO|no) echo; echo "SCRIPT TERMINATED! "; echo; exit;;
""|Y|y|YES|yes) echo; echo "STARTING THE IMPORT ..."; echo; break;;
*) echo "Please enter a valid answer: [YES|NO]";;
esac
done
echo "Creating the Exporter User DBA_BUNDLEEXP7 ..."
echo "Preparing the BEFORE and AFTER import script which will help you import the dump file later ..."
SPOOLFILE2=${LOC1}/AFTER_IMPORT_TABLE_${DUMPDATE}.sql
VAL11=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
PROMPT CREATE USER DBA_BUNDLEEXP7 [EXPORTER USER] (WILL BE DROPPED AFTER THE EXPORT) ...
CREATE USER DBA_BUNDLEEXP7 IDENTIFIED BY "BUNdle_#-^${PASSHALF}";
ALTER USER DBA_BUNDLEEXP7 IDENTIFIED BY "BUNdle_#-^${PASSHALF}" ACCOUNT UNLOCK;
GRANT CREATE SESSION TO DBA_BUNDLEEXP7;
GRANT DBA TO DBA_BUNDLEEXP7;
-- The following privileges to workaround Bug 6392040:
GRANT EXECUTE ON SYS.DBMS_DEFER_IMPORT_INTERNAL TO DBA_BUNDLEEXP7;
GRANT EXECUTE ON SYS.DBMS_EXPORT_EXTENSION TO DBA_BUNDLEEXP7;
PROMPT CREATING DIRECTORY EXPORT_FILES_DBA_BUNDLE POINTING TO ${LOC1} ...
CREATE OR REPLACE DIRECTORY EXPORT_FILES_DBA_BUNDLE AS '${LOC1}';
PROMPT
PROMPT CREATING AFTER TABLE IMPORT SCRIPT ...
PROMPT
SET PAGES 0 TERMOUT OFF LINESIZE 157 ECHO OFF FEEDBACK OFF
SPOOL ${SPOOLFILE2}
SELECT 'CREATE SYNONYM '||OWNER||'.'||SYNONYM_NAME||' FOR '||TABLE_OWNER||'.'||TABLE_NAME||';' FROM DBA_SYNONYMS
WHERE TABLE_OWNER||'.'||TABLE_NAME in (${TABLELIST}) AND OWNER <> UPPER('PUBLIC')
UNION
SELECT 'CREATE PUBLIC SYNONYM '||SYNONYM_NAME||' FOR '||TABLE_OWNER||'.'||TABLE_NAME||';' FROM DBA_SYNONYMS
WHERE TABLE_OWNER||'.'||TABLE_NAME in (${TABLELIST}) AND OWNER=UPPER('PUBLIC');
SPOOL OFF
EOF
)
# Creation of the Export Script:
export EXPORTSCRIPT=${LOC1}/EXPORTSCRIPT.sh
export EXPORTSCRIPTRUNNER=${LOC1}/EXPORTSCRIPTRUNNER.sh
echo "# Export Script: [Created By DBA_BUNDLE]" > ${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"While the Export job is running, you can check the STATUS using:\"" >>${EXPORTSCRIPT}
echo "echo \"--------------------------------------------------------------- \"" >>${EXPORTSCRIPT}
echo "echo \"SELECT job_name, operation, job_mode, DEGREE, state FROM dba_datapump_jobs where OPERATION='EXPORT' and state='EXECUTING' and owner_name='DBA_BUNDLEEXP7';\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"Then you can ATTACH to the export job and control it using:\"" >>${EXPORTSCRIPT}
echo "echo \"---------------------------------------------------------- \"" >>${EXPORTSCRIPT}
echo "echo \"expdp DBA_BUNDLEEXP7/\"BUNdle_#-^${PASSHALF}\" ATTACH=<JOB_NAME_FROM_ABOVE_COMMAND>\"" >>${EXPORTSCRIPT}
echo "echo \"i.e.\"" >>${EXPORTSCRIPT}
echo "echo \"expdp DBA_BUNDLEEXP7/\"BUNdle_#-^${PASSHALF}\" ATTACH=SYS_EXPORT_TABLE_01\"" >>${EXPORTSCRIPT}
echo "echo \"To Show the STATUS:....... STATUS\"" >>${EXPORTSCRIPT}
echo "echo \"To KILL the export:....... KILL_JOB\"" >>${EXPORTSCRIPT}
echo "echo \"To PAUSE the export:...... STOP_JOB\"" >>${EXPORTSCRIPT}
echo "echo \"To RESUME a paused export: START_JOB\"" >>${EXPORTSCRIPT}
echo "export ORACLE_SID=${ORACLE_SID}" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo 'Running The Export Job Now ...'" >>${EXPORTSCRIPT}
echo "${ORACLE_HOME}/bin/expdp DBA_BUNDLEEXP7/\"BUNdle_#-^${PASSHALF}\" PARFILE=${PARFILE}" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo 'Running Post Export Steps ...'" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF" >>${EXPORTSCRIPT}
echo "PROMPT" >>${EXPORTSCRIPT}
echo "PROMPT DROPPING THE EXPORTER USER DBA_BUNDLEEXP7 ..." >>${EXPORTSCRIPT}
echo "DROP USER DBA_BUNDLEEXP7 CASCADE;" >>${EXPORTSCRIPT}
echo "EOF" >>${EXPORTSCRIPT}
echo "echo \"*****************\"" >>${EXPORTSCRIPT}
echo "echo \"IMPORT GUIDELINES:\"" >>${EXPORTSCRIPT}
echo "echo \"*****************\"" >>${EXPORTSCRIPT}
echo "echo \"FLASHBACK SCN used for this export is: ${CURRENT_SCN}\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"AFTER IMPORTING THE DUMPFILE, RUN THIS SQL SCRIPT: ${SPOOLFILE2}\"" >>${EXPORTSCRIPT}
echo "echo \"IT INCLUDES (PRIVATE & PUBLIC SYNONYMS DDLS) WHICH WILL NOT BE HANDELED BY THE IMPORT PROCESS.\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"**************************\"" >>${EXPORTSCRIPT}
echo "echo \"EXPORT DUMP FILE LOCATION: ${LOC1}/${DUMPFILENAME}\"" >>${EXPORTSCRIPT}
echo "echo \"**************************\"" >>${EXPORTSCRIPT}
echo "export JOBSTATUS=\`grep \"successfully\\|stopped\\|completed\" ${LOGFILE}|tail -1\`" >>${EXPORTSCRIPT}
echo "export LOGFILE=${LOGFILE}" >>${EXPORTSCRIPT}
echo "export EMAILID=\"${EMAILANS}\"" >>${EXPORTSCRIPT}
echo "${SENDEMAIL}" >>${EXPORTSCRIPT}
chmod 740 ${EXPORTSCRIPT}
echo
echo "#!/bin/bash" > ${EXPORTSCRIPTRUNNER}
echo "nohup sh ${EXPORTSCRIPT}| tee ${LOGFILE} 2>&1 &" >>${EXPORTSCRIPTRUNNER}
chmod 740 ${EXPORTSCRIPTRUNNER}
echo -e "\033[32;5mFeel free to EXIT from this session as the EXPORT SCRIPT is running in the BACKGROUND.\033[0m"
source ${EXPORTSCRIPTRUNNER}
echo; exit ;;
"2"|"LEGACY EXPORT"|"LEGACY"|"EXPORT"|"LEGACY EXPORT [EXP]"|"EXP"|"[EXP]"|"exp"|"legacy export"|"legacy"|"export")
export EXPORTDUMP="${LOC1}/EXPORT_TABLE_${ORACLE_SID}_${DUMPDATE}.dmp"
export LOGFILE="${LOC1}/EXPORT_TABLE_${ORACLE_SID}_${DUMPDATE}.log"
echo
printf "`echo "Do you want to enable the COMPRESSION [Y|N] [N] [COMPRESSION will happen on the fly using mknod |"` `echo -e "\033[33;5mNo License required\033[0m"` `echo "]"`\n"
echo "====================================="
while read COMP_ANS
do
case $COMP_ANS in
y|Y|yes|YES|Yes) echo;export EXPORTDUMP="${LOC1}/EXPORT_TABLE_${ORACLE_SID}_${DUMPDATE}_pipe.dmp"
export MKNOD="rm -f ${EXPORTDUMP}; mknod ${EXPORTDUMP} p"
export ZIP="nohup bzip2 -fz < ${EXPORTDUMP} > ${LOC1}/EXPORT_TABLE_${ORACLE_SID}_${DUMPDATE}.dmp.bz2 &"
export EXPORTDUMPOUTPUT="${LOC1}/EXPORT_TABLE_${ORACLE_SID}_${DUMPDATE}.dmp.bz2"
export REMOVEMKDON="rm -f ${EXPORTDUMP}"
export UNZIPMESSAGE="First DE-COMPRESS the file using this command: bunzip2 -f ${EXPORTDUMPOUTPUT}"
echo -e "\033[32;5mCompression Enabled.\033[0m";echo; break ;;
""|n|N|no|NO|No) echo;export MKNOD=""
export ZIP=""
export EXPORTDUMP="${LOC1}/EXPORT_TABLE_${ORACLE_SID}_${DUMPDATE}.dmp"
export EXPORTDUMPOUTPUT="${LOC1}/EXPORT_TABLE_${ORACLE_SID}_${DUMPDATE}.dmp";break ;;
*) echo;echo "Please Enter a Valid Answer [Y|N]"
echo "---------------------------------";;
esac
done
SPOOLFILE2=${LOC1}/AFTER_IMPORT_TABLE_DB_${ORACLE_SID}_${DUMPDATE}.sql
echo "Creating the Exporter User DBA_BUNDLEEXP7 ..."
echo "Preparing the BEFORE and AFTER import script which will help you import the dump file later ..."
VAL11=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
PROMPT CREATE USER DBA_BUNDLEEXP7 [EXPORTER USER] (WILL BE DROPPED AFTER THE EXPORT) ...
CREATE USER DBA_BUNDLEEXP7 IDENTIFIED BY "BUNdle_#-^${PASSHALF}";
ALTER USER DBA_BUNDLEEXP7 IDENTIFIED BY "BUNdle_#-^${PASSHALF}" ACCOUNT UNLOCK;
GRANT CREATE SESSION TO DBA_BUNDLEEXP7;
GRANT DBA TO DBA_BUNDLEEXP7;
-- The following privileges to workaround Bug 6392040:
GRANT EXECUTE ON SYS.DBMS_DEFER_IMPORT_INTERNAL TO DBA_BUNDLEEXP7;
GRANT EXECUTE ON SYS.DBMS_EXPORT_EXTENSION TO DBA_BUNDLEEXP7;
PROMPT CREATING DIRECTORY EXPORT_FILES_DBA_BUNDLE POINTING TO ${LOC1} ...
CREATE OR REPLACE DIRECTORY EXPORT_FILES_DBA_BUNDLE AS '${LOC1}';
PROMPT
PROMPT CREATING AFTER TABLE IMPORT SCRIPT ...
PROMPT
SET PAGES 0 TERMOUT OFF LINESIZE 157 ECHO OFF FEEDBACK OFF
SPOOL ${SPOOLFILE2}
SELECT 'CREATE SYNONYM '||OWNER||'.'||SYNONYM_NAME||' FOR '||TABLE_OWNER||'.'||TABLE_NAME||';' FROM DBA_SYNONYMS
WHERE TABLE_OWNER||'.'||TABLE_NAME in (${TABLELIST}) AND OWNER <> UPPER('PUBLIC')
UNION
SELECT 'CREATE PUBLIC SYNONYM '||SYNONYM_NAME||' FOR '||TABLE_OWNER||'.'||TABLE_NAME||';' FROM DBA_SYNONYMS
WHERE TABLE_OWNER||'.'||TABLE_NAME in (${TABLELIST}) AND OWNER=UPPER('PUBLIC');
SPOOL OFF
EOF
)
# Creation of the Post Export Script:
export EXPORTSCRIPT=${LOC1}/EXPORTSCRIPT.sh
export EXPORTSCRIPTRUNNER=${LOC1}/EXPORTSCRIPTRUNNER.sh
echo "# Export Script: [Created By DBA_BUNDLE]" > ${EXPORTSCRIPT}
echo "export ORACLE_SID=${ORACLE_SID}" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo 'Running The Export Job Now ...'" >>${EXPORTSCRIPT}
echo "${MKNOD}" >>${EXPORTSCRIPT}
echo "sleep 1" >>${EXPORTSCRIPT}
echo "${ZIP}" >>${EXPORTSCRIPT}
echo "${ORACLE_HOME}/bin/exp DBA_BUNDLEEXP7/\"BUNdle_#-^${PASSHALF}\" TABLES=${TABLESVAR} DIRECT=y CONSISTENT=y STATISTICS=NONE FEEDBACK=100000 ${EXPORTSCN} RESUMABLE=y RESUMABLE_NAME=DBA_BUNDLE_EXPORT RESUMABLE_TIMEOUT=86400 FILE=${EXPORTDUMP} log=${LOGFILE}" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo 'Running Post Export Steps ...'" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF" >>${EXPORTSCRIPT}
echo "PROMPT" >>${EXPORTSCRIPT}
echo "PROMPT DROPPING THE EXPORTER USER DBA_BUNDLEEXP7 ..." >>${EXPORTSCRIPT}
echo "DROP USER DBA_BUNDLEEXP7 CASCADE;" >>${EXPORTSCRIPT}
echo "EOF" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "sleep 3" >>${EXPORTSCRIPT}
echo "${REMOVEMKDON}" >>${EXPORTSCRIPT}
echo "echo \"*****************\"" >>${EXPORTSCRIPT}
echo "echo \"IMPORT GUIDELINES:\"" >>${EXPORTSCRIPT}
echo "echo \"*****************\"" >>${EXPORTSCRIPT}
echo "echo \"FLASHBACK SCN used for this export is: ${CURRENT_SCN}\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"${UNZIPMESSAGE}\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"AFTER IMPORTING THE DUMPFILE, RUN THIS SQL SCRIPT: ${SPOOLFILE2}\"" >>${EXPORTSCRIPT}
echo "echo \"IT INCLUDES (PRIVATE & PUBLIC SYNONYMS DDLS) WHICH WILL NOT BE HANDELED BY THE IMPORT PROCESS.\"" >>${EXPORTSCRIPT}
echo "echo ''" >>${EXPORTSCRIPT}
echo "echo \"**************************\"" >>${EXPORTSCRIPT}
echo "echo \"EXPORT DUMP FILE LOCATION: ${EXPORTDUMPOUTPUT}\"" >>${EXPORTSCRIPT}
echo "echo \"**************************\"" >>${EXPORTSCRIPT}
echo "export JOBSTATUS=\`grep \"successfully\\|stopped\\|completed\" ${LOGFILE}|tail -1\`" >>${EXPORTSCRIPT}
echo "export LOGFILE=${LOGFILE}" >>${EXPORTSCRIPT}
echo "export EMAILID=\"${EMAILANS}\"" >>${EXPORTSCRIPT}
echo "${SENDEMAIL}" >>${EXPORTSCRIPT}
chmod 740 ${EXPORTSCRIPT}
echo
echo "#!/bin/bash" > ${EXPORTSCRIPTRUNNER}
echo "nohup sh ${EXPORTSCRIPT}| tee ${LOGFILE} 2>&1 &" >>${EXPORTSCRIPTRUNNER}
chmod 740 ${EXPORTSCRIPTRUNNER}
echo -e "\033[32;5mFeel free to EXIT from this session as the EXPORT SCRIPT is running in the BACKGROUND.\033[0m"
source ${EXPORTSCRIPTRUNNER}
echo; exit ;;
*) echo "Enter a valid number:"
echo "====================="
echo "i.e."
echo "1 for expdp tool"
echo "2 for exp tool"
echo ;;
esac
done
break;;
*) echo "Enter a NUMBER between 1 to 3 boss:"
echo "==================================" ;;
esac
done
# #############
# END OF SCRIPT
# #############
# DISCLAIMER: THIS SCRIPT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY. IT IS PROVIDED "AS IS".
# Do not live under a rock :-) Every month a new version of DBA_BUNDLE get released, download it by visiting:
# http://dba-tips.blogspot.com/2014/02/oracle-database-administration-scripts.html
# REPORT BUGs to: mahmmoudadel@hotmail.com
view raw export_data hosted with ❤ by GitHub

Friday, February 14, 2014

Extract Oracle Audit Records Script

Today I'll share with you one of my scripts I'm using to easily retrieve the audit records of an oracle database user.

Note: Auditing should be enabled on the database or the script will return no rows.
              To enable auditing please check this article:
              http://www.oracle-base.com/articles/10g/auditing-10gr2.php

Download the script from this link:

Once you run this script it will let you choose the database you want to retrieve data from (in case that you have multiple running databases on the server), then it will ask you to enter the username, and lastly will ask you to enter the number of days back you want to retrieve audit data or enter a specific date.

This script is very easy to use, it has been tested on Linux and SUN environments.

DISCLAIMER: THIS SCRIPT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY. IT IS PROVIDED "AS IS".


Here is the script code, in case the download link is not working with you:

# ##############################################################################################
# This script shows AUDIT records for DB User.
# To be run by ORACLE user
# # # #
# Author: Mahmmoud ADEL # # # # ###
# Created: 25-04-2013 # # # # #
#
# Modified: 07-03-2019 Allow the user to control the display of LOGIN/LOGOFF data.
# 10-03-2019 Added the option of excluding specific audit action from the report.
# ##############################################################################################
# ###########################
# Listing Available Instances:
# ###########################
echo
echo "=================================================================="
echo "This Script Retreives AUDIT data for a user if auditing is enabled."
echo "=================================================================="
echo
sleep 1
# #######################################
# Excluded INSTANCES:
# #######################################
# Here you can mention the instances the script 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" #Excluded INSTANCES [Will not get reported offline].
# Count Instance Numbers:
INS_COUNT=$( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|wc -l )
# Exit if No DBs are running:
if [ $INS_COUNT -eq 0 ]
then
echo No Database Running !
exit
fi
# If there is ONLY one DB set it as default without prompt for selection:
if [ $INS_COUNT -eq 1 ]
then
export ORACLE_SID=$( 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" )
# If there is more than one DB ASK the user to select:
elif [ $INS_COUNT -gt 1 ]
then
echo
echo "Select the Instance You Want To Run this script Against:[Enter the number]"
echo "-------------------------------------------------------"
select DB_ID 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
if [ -z "${REPLY##[0-9]*}" ]
then
export ORACLE_SID=$DB_ID
echo Selected Instance:
echo
echo "********"
echo $DB_ID
echo "********"
echo
break
else
export ORACLE_SID=${REPLY}
break
fi
done
fi
# Exit if the user selected a Non Listed Number:
if [ -z "${ORACLE_SID}" ]
then
echo "You've Entered An INVALID ORACLE_SID"
exit
fi
# #########################
# Getting ORACLE_HOME
# #########################
ORA_USER=`ps -ef|grep ${ORACLE_SID}|grep pmon|grep -v grep|egrep -v ${EXL_DB}|awk '{print $1}'|tail -1`
USR_ORA_HOME=`grep ${ORA_USER} /etc/passwd| cut -f6 -d ':'|tail -1`
# SETTING ORATAB:
if [ -f /etc/oratab ]
then
ORATAB=/etc/oratab
export ORATAB
## If OS is Solaris:
elif [ -f /var/opt/oracle/oratab ]
then
ORATAB=/var/opt/oracle/oratab
export ORATAB
fi
# ATTEMPT1: Get ORACLE_HOME using pwdx command:
PMON_PID=`pgrep -lf _pmon_${ORACLE_SID}|awk '{print $1}'`
export PMON_PID
ORACLE_HOME=`pwdx ${PMON_PID}|awk '{print $NF}'|sed -e 's/\/dbs//g'`
export ORACLE_HOME
#echo "ORACLE_HOME from PWDX is ${ORACLE_HOME}"
# ATTEMPT2: If ORACLE_HOME not found get it from oratab file:
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ]
then
## If OS is Linux:
if [ -f /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 [ -f /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
#echo "ORACLE_HOME from oratab is ${ORACLE_HOME}"
fi
# ATTEMPT3: If ORACLE_HOME is still not found, search for the environment variable: [Less accurate]
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ]
then
ORACLE_HOME=`env|grep -i ORACLE_HOME|sed -e 's/ORACLE_HOME=//g'`
export ORACLE_HOME
#echo "ORACLE_HOME from environment is ${ORACLE_HOME}"
fi
# ATTEMPT4: If ORACLE_HOME is not found in the environment search user's profile: [Less accurate]
if [ ! -f ${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
#echo "ORACLE_HOME from User Profile is ${ORACLE_HOME}"
fi
# ATTEMPT5: If ORACLE_HOME is still not found, search for orapipe: [Least accurate]
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ]
then
ORACLE_HOME=`locate -i orapipe|head -1|sed -e 's/\/bin\/orapipe//g'`
export ORACLE_HOME
#echo "ORACLE_HOME from orapipe search is ${ORACLE_HOME}"
fi
# TERMINATE: If all above attempts failed to get ORACLE_HOME location, EXIT the script:
if [ ! -f ${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
# ########################################
# Exit if the user is not the Oracle Owner:
# ########################################
CURR_USER=`whoami`
if [ ${ORA_USER} != ${CURR_USER} ]; then
echo ""
echo "You're Running This Sctipt with User: \"${CURR_USER}\" !!!"
echo "Please Run This Script With The Right OS User: \"${ORA_USER}\""
echo "Script Terminated!"
exit
fi
# #########################
# SQLPLUS Section:
# #########################
# PROMPT FOR VARIABLES:
# ####################
echo
echo "Enter The USERNAME you want to retrieve its Audit Data: [Blank Value means ALL Users]"
echo "======================================================"
while read DB_USERNAME
do
case $DB_USERNAME in
# NO VALUE PROVIDED:
"") USERNAME_COND="";break ;;
#*) USERNAME_COND="USERNAME=upper('${DB_USERNAME}') or OS_USERNAME='${DB_USERNAME}' AND";break ;;
*) USERNAME_COND="USERNAME=upper('${DB_USERNAME}') AND";break ;;
esac
done
echo
echo "Do you want to include LOGIN/LOGOFF information: [Y|N Default [N]]"
echo "==============================================="
while read LOGININFO
do
case ${LOGININFO} in
# NO VALUE PROVIDED:
""|N|n|NO|no|No) export EXCLUDELOGINDATA="AND ACTION_NAME not like 'LOGO%' AND";break ;;
Y|y|YES|yes|Yes) export EXCLUDELOGINDATA="";break ;;
*) echo "Please enter a VALID answer [Y|N]" ;;
esac
done
echo
echo "Do you want to EXCLUDE a specific Action from the list:"
echo "======================================================"
echo "[Blank means INCLUDE ALL Actions Or Provide One of These Action to exclude: SELECT, ALTER, DROP, CREATE, TRUNCATE, GRANT or REVOKE]"
while read EXCLUDEDACTION
do
case ${EXCLUDEDACTION} in
# NO VALUE PROVIDED:
"") export EXCLUDEDACTION="null";break ;;
*) export EXCLUDEDACTION;break ;;
esac
done
echo
echo "How [MANY DAYS BACK] you want to retrieve AUDIT data? [Default 1]"
echo "====================================================="
echo "OR: Enter A Specific DATE in this FORMAT [DD-MM-YYYY] e.g. 25-01-2011"
echo "== ================================================================="
while read NUM_DAYS
do
case $NUM_DAYS in
# User PROVIDED a NON NUMERIC value:
*[!0-9]*) echo;echo "Retreiving AUDIT data for User [${DB_USERNAME}] on [${NUM_DAYS}] ..."
${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set linesize 157
col OS_USERNAME for a15
col DB_USERNAME for a15
--col EXTENDED_TIMESTAMP for a36
col DATE for a22
col OWNER for a10
col OBJ_NAME for a25
col USERHOST for a21
col ACTION_NAME for a25
col ACTION_OWNER_OBJECT for a55
--select extended_timestamp,OS_USERNAME,USERNAME DB_USERNAME,USERHOST,ACTION_NAME||' '||OWNER||' . '||OBJ_NAME ACTION_OWNER_OBJECT
select to_char(extended_timestamp,'DD-Mon-YYYY HH24:MI:SS')"DATE",OS_USERNAME,USERNAME DB_USERNAME,USERHOST,ACTION_NAME||' '||OWNER||' . '||OBJ_NAME ACTION_OWNER_OBJECT
from dba_audit_trail
where ${USERNAME_COND}
timestamp > SYSDATE-${NUM_DAYS} ${EXCLUDELOGINDATA}
ACTION_NAME not like upper ('%${EXCLUDEDACTION}%')
--AND TRUNC(extended_timestamp) = TO_DATE('${NUM_DAYS}','DD-MM-YYYY')
order by EXTENDED_TIMESTAMP;
PROMPT
EOF
exit
break ;;
# NO VALUE PROVIDED:
"") export NUM_DAYS=1;echo;echo "Retreiving AUDIT data in the last 24 Hours ... [Please Wait]";break ;;
# A NUMERIC VALUE PROVIDED:
*) export NUM_DAYS;echo;echo "Retreiving AUDIT data in the last ${NUM_DAYS} Days ... [Please Wait]";break ;;
esac
done
# Execution of SQL Statement:
# ##########################
${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set linesize 190 pages 1000
col OS_USERNAME for a15
col DB_USERNAME for a15
--col EXTENDED_TIMESTAMP for a36
col DATE for a22
col OWNER for a10
col OBJ_NAME for a25
col USERHOST for a21
col ACTION_NAME for a25
col ACTION_OWNER_OBJECT for a80
--select extended_timestamp,OS_USERNAME,USERNAME,USERHOST,ACTION_NAME||' '||OWNER||' . '||OBJ_NAME ACTION_OWNER_OBJECT
select to_char(extended_timestamp,'DD-Mon-YYYY HH24:MI:SS')"DATE",OS_USERNAME,USERNAME DB_USERNAME,USERHOST,ACTION_NAME||' '||OWNER||' . '||OBJ_NAME ACTION_OWNER_OBJECT
from dba_audit_trail
where ${USERNAME_COND}
timestamp > SYSDATE-${NUM_DAYS} ${EXCLUDELOGINDATA}
ACTION_NAME not like upper ('%${EXCLUDEDACTION}%')
order by EXTENDED_TIMESTAMP;
PROMPT
EOF
# #############
# END OF SCRIPT
# #############
# REPORT BUGS to: <mahmmoudadel@hotmail.com>.
# DISCLAIMER: THIS SCRIPT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY. IT IS PROVIDED "AS IS".
# DOWNLOAD THE LATEST VERSION OF DATABASE ADMINISTRATION BUNDLE FROM:
# http://dba-tips.blogspot.com/2014/02/oracle-database-administration-scripts.html
view raw audit_records hosted with ❤ by GitHub

Script to TRACE Oracle Session

In order to simplify the steps of enabling, stopping the trace on Oracle sessions and make the output trace data readable, I've written two scripts, start_tracing.sh will let you enable tracing on a specific session, and stop_tracing.sh to stop tracing the session and provide the original trace file along with another readable version of the trace file using TKPROF utility.

Download links:


start_tracing.sh

https://www.dropbox.com/s/dkhjteqckcuykqd/start_tracing.sh?dl=0

stop_tracing.sh

https://www.dropbox.com/s/41krahxx8m67uyg/stop_tracing.sh?dl=0

Those scripts are part of the DBA bundle which equipped with many of easy to use scripts that simplify day to day database administration tasks:
http://dba-tips.blogspot.ae/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".

start_tracing.sh
# #####################################################################################################
# Script to Enable the trace on an Oracle Session.
# # # #
# Author: Mahmmoud ADEL # # # # ###
# Created: 24-12-11 # # # # #
#
# Modified: 31-12-13 Customized the script to run on various environments.
# 04-05-14 Enhanced trace file search criteria.
# 16-06-20 Enhanced trace file search criteria.
#
# #####################################################################################################
# ###########
# Description:
# ###########
echo
echo "=================================================="
echo "This script Enables tracing for an Oracle Session."
echo "=================================================="
echo
sleep 1
# #######################################
# Excluded INSTANCES:
# #######################################
# Here you can mention the instances the script 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].
# ###########################
# Listing Available Databases:
# ###########################
# Count Instance Numbers:
INS_COUNT=$( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|wc -l )
# Exit if No DBs are running:
if [ $INS_COUNT -eq 0 ]
then
echo No Database Running !
exit
fi
# If there is ONLY one DB set it as default without prompt for selection:
if [ $INS_COUNT -eq 1 ]
then
export ORACLE_SID=$( 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" )
# If there is more than one DB ASK the user to select:
elif [ $INS_COUNT -gt 1 ]
then
echo
echo "Select the ORACLE_SID:[Enter the number]"
echo ---------------------
select DB_ID 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
if [ -z "${REPLY##[0-9]*}" ]
then
export ORACLE_SID=$DB_ID
echo Selected Instance:
echo
echo "********"
echo $DB_ID
echo "********"
echo
break
else
export ORACLE_SID=${REPLY}
break
fi
done
fi
# Exit if the user selected a Non Listed Number:
if [ -z "${ORACLE_SID}" ]
then
echo "You've Entered An INVALID ORACLE_SID"
exit
fi
# #########################
# Getting ORACLE_HOME
# #########################
ORA_USER=`ps -ef|grep ${ORACLE_SID}|grep pmon|grep -v grep|egrep -v ${EXL_DB}|awk '{print $1}'|tail -1`
USR_ORA_HOME=`grep ${ORA_USER} /etc/passwd| cut -f6 -d ':'|tail -1`
# SETTING ORATAB:
if [ -f /etc/oratab ]
then
ORATAB=/etc/oratab
export ORATAB
## If OS is Solaris:
elif [ -f /var/opt/oracle/oratab ]
then
ORATAB=/var/opt/oracle/oratab
export ORATAB
fi
# ATTEMPT1: Get ORACLE_HOME using pwdx command:
PMON_PID=`pgrep -lf _pmon_${ORACLE_SID}|awk '{print $1}'`
export PMON_PID
ORACLE_HOME=`pwdx ${PMON_PID}|awk '{print $NF}'|sed -e 's/\/dbs//g'`
export ORACLE_HOME
#echo "ORACLE_HOME from PWDX is ${ORACLE_HOME}"
# ATTEMPT2: If ORACLE_HOME not found get it from oratab file:
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ]
then
## If OS is Linux:
if [ -f /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 [ -f /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
#echo "ORACLE_HOME from oratab is ${ORACLE_HOME}"
fi
# ATTEMPT3: If ORACLE_HOME is still not found, search for the environment variable: [Less accurate]
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ]
then
ORACLE_HOME=`env|grep -i ORACLE_HOME|sed -e 's/ORACLE_HOME=//g'`
export ORACLE_HOME
#echo "ORACLE_HOME from environment is ${ORACLE_HOME}"
fi
# ATTEMPT4: If ORACLE_HOME is not found in the environment search user's profile: [Less accurate]
if [ ! -f ${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
#echo "ORACLE_HOME from User Profile is ${ORACLE_HOME}"
fi
# ATTEMPT5: If ORACLE_HOME is still not found, search for orapipe: [Least accurate]
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ]
then
ORACLE_HOME=`locate -i orapipe|head -1|sed -e 's/\/bin\/orapipe//g'`
export ORACLE_HOME
#echo "ORACLE_HOME from orapipe search is ${ORACLE_HOME}"
fi
# TERMINATE: If all above attempts failed to get ORACLE_HOME location, EXIT the script:
if [ ! -f ${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
# ########################################
# Exit if the user is not the Oracle Owner:
# ########################################
CURR_USER=`whoami`
if [ ${ORA_USER} != ${CURR_USER} ]; then
echo ""
echo "You're Running This Sctipt with User: \"${CURR_USER}\" !!!"
echo "Please Run This Script With The Right OS User: \"${ORA_USER}\""
echo "Script Terminated!"
exit
fi
# #########################
# Getting BDUMP Location:
# #########################
VAL_DUMP=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off;
prompt
select value from V\$DIAG_INFO where NAME='Diag Trace';
exit;
EOF
)
BDUMP=`echo ${VAL_DUMP} | perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'`
export BDUMP
if [ ! -d ${BDUMP} ]
then
VAL_DUMP=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off;
prompt
SELECT value from v\$parameter where NAME='user_dump_dest';
exit;
EOF
)
BDUMP=`echo ${VAL_DUMP} | perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'`
export BDUMP
fi
# #################################
# SQLPLUS: Start Tracing a Session:
# #################################
# Variables:
# #########
echo ""
echo "Please enter the Username you want to trace its session:"
echo "========================================================"
read USERNAME
${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
set linesize 143
set pagesize 1000
set feedback off
set trim on
set echo off
col USERNAME for a35
col MODULE for a30
Select username,module,SQL_ID "Curr_SQLID",prev_sql_id "Prev_SQLID",status,sid,serial#
from v\$session
where username like upper ('%$USERNAME%');
EOF
# Unlock Execution part:
echo
echo "Enter the session SID:"
echo "---------------------"
read SESSIONID
if [ -z "${SESSIONID}" ]
then
echo No Value Entered!
echo Script Terminated.
exit
fi
echo "Enter the session SERIAL#:"
echo "-------------------------"
read SESSIONSERIAL
if [ -z "${SESSIONSERIAL}" ]
then
echo "No Value Entered!"
echo "Script Terminated."
exit
fi
VAL1=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
begin
dbms_monitor.session_trace_enable (
session_id => '$SESSIONID',
serial_num => '$SESSIONSERIAL',
waits => true,
binds => true
);
end;
/
EOF
)
VAL2=`echo $VAL1| grep "successfully completed"`
if [ -z "${VAL2}" ]
then
echo
echo "The Session with Provided SID & SERIAL# is NOT EXIST!"
echo "Script Terminated."
echo
exit
fi
echo
VAL11=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
set pages 0 feedback off;
SELECT p.spid FROM v\$session s,v\$process p WHERE p.addr = s.paddr and s.sid='$SESSIONID' and s.serial#='$SESSIONSERIAL';
EOF
)
VAL22=`echo $VAL11| awk '{print $NF}'`
VAL33=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
set pages 0 feedback off;
SELECT INSTANCE_NAME FROM V\$INSTANCE;
EOF
)
VAL44=`echo $VAL33| awk '{print $NF}'`
echo "TRACING has been ENABLED for session SID:${SESSIONID} / SERIAL#:${SESSIONSERIAL}"
TRACEFILE=`find ${BDUMP}/${VAL44}_ora_${VAL22}.trc -mmin -10|tail -1`
sleep 1
echo
echo "Trace File Location:"
echo "-------------------"
if [ -z ${TRACEFILE} ]
then
echo "Once the session start doing activities, try to find the TRACE FILE using the following command:"
echo "find ${BDUMP}/${VAL44}_ora_${VAL22}.trc -mmin -10"
else
echo "Trace File is: ${TRACEFILE}"
fi
echo
sleep 2
echo -e "\033[33;9mDon't forget to STOP the Tracing once you Finish, Using 'stoptrace' Script.\033[0m"
echo
# #############
# END OF SCRIPT
# #############
# REPORT BUGS to: <mahmmoudadel@hotmail.com>.
# DISCLAIMER: THIS SCRIPT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY. IT IS PROVIDED "AS IS".
# DOWNLOAD THE LATEST VERSION OF DATABASE ADMINISTRATION BUNDLE FROM:
# http://dba-tips.blogspot.com/2014/02/oracle-database-administration-scripts.html
view raw start_tracing hosted with ❤ by GitHub


stop_tracing.sh
# #################################################
# Script to STOP tracing an Oracle Traced Session.
# # # #
# Author: Mahmmoud ADEL # # # # ###
# Created: 24-12-11 # # # # #
# Modified: 31-12-13
# Customized the script to run on
# various environments.
# 04-05-14 Enhanced search criteria
# for generated trace file.
#
# #################################################
# ###########
# Description:
# ###########
echo
echo "================================================="
echo "This script STOP Tracing a TRACED Oracle Session."
echo "================================================="
echo
sleep 1
# #######################################
# Excluded INSTANCES:
# #######################################
# Here you can mention the instances the script 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].
# ###########################
# Listing Available Databases:
# ###########################
# Count Instance Numbers:
INS_COUNT=$( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|wc -l )
# Exit if No DBs are running:
if [ $INS_COUNT -eq 0 ]
then
echo No Database Running !
exit
fi
# If there is ONLY one DB set it as default without prompt for selection:
if [ $INS_COUNT -eq 1 ]
then
export ORACLE_SID=$( 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" )
# If there is more than one DB ASK the user to select:
elif [ $INS_COUNT -gt 1 ]
then
echo
echo "Select the ORACLE_SID:[Enter the number]"
echo ---------------------
select DB_ID 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
if [ -z "${REPLY##[0-9]*}" ]
then
export ORACLE_SID=$DB_ID
echo Selected Instance:
echo
echo "********"
echo $DB_ID
echo "********"
echo
break
else
export ORACLE_SID=${REPLY}
break
fi
done
fi
# Exit if the user selected a Non Listed Number:
if [ -z "${ORACLE_SID}" ]
then
echo "You've Entered An INVALID ORACLE_SID"
exit
fi
# #########################
# Getting ORACLE_HOME
# #########################
ORA_USER=`ps -ef|grep ${ORACLE_SID}|grep pmon|grep -v grep|egrep -v ${EXL_DB}|awk '{print $1}'|tail -1`
USR_ORA_HOME=`grep ${ORA_USER} /etc/passwd| cut -f6 -d ':'|tail -1`
# SETTING ORATAB:
if [ -f /etc/oratab ]
then
ORATAB=/etc/oratab
export ORATAB
## If OS is Solaris:
elif [ -f /var/opt/oracle/oratab ]
then
ORATAB=/var/opt/oracle/oratab
export ORATAB
fi
# ATTEMPT1: Get ORACLE_HOME using pwdx command:
PMON_PID=`pgrep -lf _pmon_${ORACLE_SID}|awk '{print $1}'`
export PMON_PID
ORACLE_HOME=`pwdx ${PMON_PID}|awk '{print $NF}'|sed -e 's/\/dbs//g'`
export ORACLE_HOME
#echo "ORACLE_HOME from PWDX is ${ORACLE_HOME}"
# ATTEMPT2: If ORACLE_HOME not found get it from oratab file:
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ]
then
## If OS is Linux:
if [ -f /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 [ -f /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
#echo "ORACLE_HOME from oratab is ${ORACLE_HOME}"
fi
# ATTEMPT3: If ORACLE_HOME is still not found, search for the environment variable: [Less accurate]
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ]
then
ORACLE_HOME=`env|grep -i ORACLE_HOME|sed -e 's/ORACLE_HOME=//g'`
export ORACLE_HOME
#echo "ORACLE_HOME from environment is ${ORACLE_HOME}"
fi
# ATTEMPT4: If ORACLE_HOME is not found in the environment search user's profile: [Less accurate]
if [ ! -f ${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
#echo "ORACLE_HOME from User Profile is ${ORACLE_HOME}"
fi
# ATTEMPT5: If ORACLE_HOME is still not found, search for orapipe: [Least accurate]
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ]
then
ORACLE_HOME=`locate -i orapipe|head -1|sed -e 's/\/bin\/orapipe//g'`
export ORACLE_HOME
#echo "ORACLE_HOME from orapipe search is ${ORACLE_HOME}"
fi
# TERMINATE: If all above attempts failed to get ORACLE_HOME location, EXIT the script:
if [ ! -f ${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
# ########################################
# Exit if the user is not the Oracle Owner:
# ########################################
CURR_USER=`whoami`
if [ ${ORA_USER} != ${CURR_USER} ]; then
echo ""
echo "You're Running This Sctipt with User: \"${CURR_USER}\" !!!"
echo "Please Run This Script With The Right OS User: \"${ORA_USER}\""
echo "Script Terminated!"
exit
fi
# #########################
# Getting BDUMP Location:
# #########################
VAL_DUMP=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off;
prompt
select value from V\$DIAG_INFO where NAME='Diag Trace';
exit;
EOF
)
BDUMP=`echo ${VAL_DUMP} | perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'`
export BDUMP
if [ ! -d ${BDUMP} ]
then
VAL_DUMP=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off;
prompt
SELECT value from v\$parameter where NAME='user_dump_dest';
exit;
EOF
)
BDUMP=`echo ${VAL_DUMP} | perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'`
export BDUMP
fi
# ###############################
# SQLPLUS: Stop Tracing a Session:
# ###############################
echo ""
${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
set linesize 143
set pagesize 1000
set feedback off
set trim on
set echo off
col USERNAME for a35
col MODULE for a30
PROMPT The following are the session that are being TRACED:
select username,module,status,sid,serial# from v\$session where sql_trace='ENABLED';
EOF
# Unlock Execution part:
echo
echo "Enter the User's session SID:"
echo "============================="
read SESSIONID
if [ -z "${SESSIONID}" ]
then
echo No Value Entered!
echo Script Terminated.
exit
fi
echo
echo "Enter the User's session SERIAL#:"
echo "================================="
read SESSIONSERIAL
if [ -z "${SESSIONSERIAL}" ]
then
echo "No Value Entered!"
echo "Script Terminated."
exit
fi
VAL11=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
set pages 0 feedback off;
SELECT p.spid FROM v\$session s,v\$process p WHERE p.addr = s.paddr and s.sid='$SESSIONID' and s.serial#='$SESSIONSERIAL';
EOF
)
VAL22=`echo $VAL11| awk '{print $NF}'`
VAL33=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
set pages 0 feedback off;
SELECT INSTANCE_NAME FROM V\$INSTANCE;
EOF
)
VAL44=`echo $VAL33| awk '{print $NF}'`
VAL1=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
begin
dbms_monitor.session_trace_disable (
session_id => '$SESSIONID',
serial_num => '$SESSIONSERIAL');
end;
/
EOF
)
VAL2=`echo $VAL1| grep "successfully completed"`
if [ -z "${VAL2}" ]
then
echo
echo "The Session with Provided SID & SERIAL# Is NOT Being Traced!"
echo "Script Terminated."
echo
exit
fi
echo
sleep 1
echo "Tracing Has been STOPPED Successfully."
TRACEFILE=`find ${BDUMP}/${VAL44}_ora_${VAL22}.trc -mmin -10|tail -1`
echo
echo "Trace File Location:"
echo "-------------------"
if [ -z ${TRACEFILE} ]
then
echo "You can find the TRACE file Under: ${BDUMP}"
else
sleep 1
echo "${TRACEFILE}"
${ORACLE_HOME}/bin/tkprof ${TRACEFILE} ${TRACEFILE}_tkprofed.log sys=no waits=yes
sleep 3
echo "The TKPROFED version [Readable version] of the TRACE FILE is:"
echo "--------------------"
echo "${TRACEFILE}_tkprofed.log"
fi
echo
# #############
# END OF SCRIPT
# #############
# REPORT BUGS to: <mahmmoudadel@hotmail.com>.
# DISCLAIMER: THIS SCRIPT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY. IT IS PROVIDED "AS IS".
# DOWNLOAD THE LATEST VERSION OF DATABASE ADMINISTRATION BUNDLE FROM:
# http://dba-tips.blogspot.com/2014/02/oracle-database-administration-scripts.html
view raw stop_tracing hosted with ❤ by GitHub

Oracle Logs CLEANUP Script

In this post, I'll share a script to backup & cleanup Oracle logs associated with a specific database on the Oracle server.

This script was tested on Linux & SUN environments.

You can download the script from here:
https://www.dropbox.com/s/eytsv5duxe95lrh/oracle_cleanup.sh?dl=0

Once you run it, it will ask you to select a database (in case you have multiple running databases on the server), then it will ask you the location you want to back up the logs, then it will start to clean up all logs under udump, bdump, cdump folder plus the audit logs and also will clean up the logs of the listener associated with the selected database.

Note: This script will backup and delete all logs and will keep the logs of the last 5 days only.

Note: it's recommended to test this script on a test environment before you run it on production.

Also, you can download the whole DBA bundle which having many other smart and easy to use scripts for database administration tasks:
http://dba-tips.blogspot.ae/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".

Below is the code of this script in case the download link didn't work:

# ###################################################################################
# This script Backup & Cleanup the database logs.
# To be run by ORACLE user
# [Ver 2.0]
# # # #
# Author: Mahmmoud ADEL # # # # ###
# Created: 03-06-2013 # # # # #
# Modified: 02-07-2013
# 14-01-2014 Customized the script to run on various environments.
# 14-06-2017 Increased the script accuracy and elimiated tar bug.
# 15-05-2018 Added the option of archiving Audit log files.
# 27-12-2018 Verify the trace/log locations are valid before cleaning.
# 23-01-2019 Added the option of Skipping backing up the trace/logs.
# 03-07-2020 Enhance locating the listener's log.
# 03-07-2020 Enhance locating the alertlog/bdump/cdump location.
#
#
# ###################################################################################
SCRIPT_NAME="oracle_cleanup"
# ###########
# Description:
# ###########
echo
echo "=================================================================="
echo "This script will Back up & Delete the database logs and Audit logs ..."
echo "=================================================================="
echo
sleep 1
# #######################################
# Excluded INSTANCES:
# #######################################
# Here you can mention the instances the script 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].
# ###########################
# Listing Available Instances:
# ###########################
# Count Instance Numbers:
INS_COUNT=$( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|wc -l )
# Exit if No DBs are running:
if [ $INS_COUNT -eq 0 ]
then
echo No Database Running !
exit
fi
# If there is ONLY one DB set it as default without prompt for selection:
if [ $INS_COUNT -eq 1 ]
then
export ORACLE_SID=$( 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" )
# If there is more than one DB ASK the user to select:
elif [ $INS_COUNT -gt 1 ]
then
echo
echo "Select the Instance You Want To Backup & Delete It's Logs: [Enter the Number]"
echo "----------------------------------------------------------"
select DB_ID 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
if [ -z "${REPLY##[0-9]*}" ]
then
export ORACLE_SID=$DB_ID
echo
echo Selected Instance:
echo "********"
echo $DB_ID
echo "********"
break
else
export ORACLE_SID=${REPLY}
break
fi
done
fi
# Exit if the user selected a Non Listed Number:
if [ -z "${ORACLE_SID}" ]
then
echo "You've Entered An INVALID ORACLE_SID"
exit
fi
# #########################
# 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 [ -f /etc/oratab ]
then
ORATAB=/etc/oratab
export ORATAB
## If OS is Solaris:
elif [ -f /var/opt/oracle/oratab ]
then
ORATAB=/var/opt/oracle/oratab
export ORATAB
fi
# ATTEMPT1: Get ORACLE_HOME using pwdx command:
PMON_PID=`pgrep -lf _pmon_${ORACLE_SID}|awk '{print $1}'`
export PMON_PID
ORACLE_HOME=`pwdx ${PMON_PID}|awk '{print $NF}'|sed -e 's/\/dbs//g'`
export ORACLE_HOME
# ATTEMPT2: If ORACLE_HOME not found get it from oratab file:
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ]
then
## If OS is Linux:
if [ -f /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 [ -f /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 [ ! -f ${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 [ ! -f ${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 [ ! -f ${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 [ ! -f ${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 [ ! -f ${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
# ########################################
# Exit if the user is not the Oracle Owner:
# ########################################
CURR_USER=`whoami`
if [ ${ORA_USER} != ${CURR_USER} ]; then
echo ""
echo "You're Running This Sctipt with User: \"${CURR_USER}\" !!!"
echo "Please Run This Script With The Right OS User: \"${ORA_USER}\""
echo "Script Terminated!"
exit
fi
# ########################
# Getting ORACLE_BASE:
# ########################
echo "Setting 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
# Neutralize login.sql file:
# #########################
# Existance of login.sql file under current working directory eliminates many functions during the execution of this script:
if [ -f ./login.sql ]
then
mv ./login.sql ./login.sql_NeutralizedBy${SCRIPT_NAME}
fi
if [ -f ${USR_ORA_HOME}/login.sql ]
then
mv ${USR_ORA_HOME}/login.sql ${USR_ORA_HOME}/login.sql_NeutralizedBy${SCRIPT_NAME}
fi
# #########################
# Getting DB_NAME:
# #########################
echo "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 ALERTLOG path:
# #########################
# First Attempt:
VAL_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 ${VAL_DUMP} | perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'`
ALERTDB=${ALERTZ}/alert_${ORACLE_SID}.log
export ALERTDB
# Second Attempt:
if [ ! -f ${ALERTDB} ]
then
VAL_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 ${VAL_DUMP} | perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'`
ALERTDB=${ALERTZ}/alert_${ORACLE_SID}.log
export ALERTDB
fi
# Third Attempt:
if [ ! -f ${ALERTDB} ]
then
VAL_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 ${VAL_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 [ ! -f ${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 [ ! -f ${ALERTDB} ]
then
if [ -x /usr/bin/locate ]
then
ALERTDB=`ls -rtl \`locate alert_${ORACLE_SID}\`|tail -1|awk '{print $NF}'`
export ALERTDB
fi
fi
if [ -f ${ALERTDB} ]
then
BDUMP=`echo ${VAL_DUMP} | perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'`
DUMP=`echo ${BDUMP} | sed 's/\/trace//g'`
CDUMP=${DUMP}/cdump
export BDUMP
export DUMP
export CDUMP
fi
echo DUMP location is: ${DUMP}
echo BDUMP location is: ${BDUMP}
# #########
# Variables:
# #########
echo ""
echo "Do you want to BACK UP the LOGFILES before Cleaning them up? [Y|N] Default is NO"
echo "============================================================"
while read ANS
do
case $ANS in
y|Y|yes|YES|Yes) export BACKUP_FLAG="ON"; break ;;
""|n|N|NO|no|No) echo; export BACKUP_FLAG=""; break ;;
*) echo; echo "Please enter a VALID answer [Y|N]" ;;
esac
done
export HASH_BKP="echo #"
case $BACKUP_FLAG in
ON)
export HASH_BKP=""
echo ""
echo "Please Enter The Full Path of Backup Location: [i.e. /tmp]"
echo "============================================="
while read LOC1
do
if [ ! -w "${LOC1}" ]; then
echo "Provided Backup Location is NOT Exist/Writable !"
echo
echo "Please Provide a VALID Backup Location:"
echo "--------------------------------------"
else
BKP_LOC_DB=${LOC1}/${ORACLE_SID}_DB_LOGS/`date +%d-%b-%y`
/bin/mkdir -p ${BKP_LOC_DB}
echo "Backup Location is: ${BKP_LOC_DB}"
break
fi
done
# Exit if the user has pressed Ctrl+D:
if [ ! -w "${LOC1}" ]; then
exit
fi
esac
# Setting a Verifier:
echo ""
echo "Shall we go ahead with CLEANING UP LOGS and TRACES of Database \"${ORACLE_SID}\" and its Listener: [Y|N] Y"
echo "==========================================================================================="
while read ANS
do
case $ANS in
""|y|Y|yes|YES|Yes) break ;;
n|N|NO|no|No) echo; echo "Script Terminated !";echo; exit; break ;;
*) echo; echo "Please enter a VALID answer [Y|N]" ;;
esac
done
echo ""
echo "Do you want to Cleanup Database Audit Logs: [Y|N] Y"
echo "=========================================="
while read ANS
do
case $ANS in
""|y|Y|yes|YES|Yes) echo;export AUDIT_FILES_CLEANUP=Y ;break ;;
n|N|NO|no|No) echo;export AUDIT_FILES_CLEANUP=N ;break ;;
*) echo;echo "Please enter a VALID answer [Y|N]" ;;
esac
done
INS=${ORACLE_SID}
export INS
# ######################
# Getting Listener name:
# ######################
LSNR_COUNT=$( ps -ef|grep tnslsnr|grep -v grep|wc -l )
if [ ${LSNR_COUNT} -eq 1 ]
then
LSNR_NAME=$( ps -ef|grep tnslsnr|grep -v grep|awk '{print $(9)}' )
else
LSNR_NAME=$( ps -ef|grep tnslsnr|grep -i "${ORACLE_SID} "|grep -v grep|awk '{print $(9)}' )
fi
if [ -z "${LSNR_NAME}" ]
then
LSNR_NAME=LISTENER
fi
LISTENER_NAME=${LSNR_NAME}
# #######################
# Backup & Delete DB logs:
# #######################
# Exit if DUMP/BDUMP/CDUMP variables are NULL:
if [ -z "${DUMP}" ]
then
echo "DUMP variable is NULL."
echo "Script Terminated."
exit
fi
if [ -z "${BDUMP}" ]
then
echo "BDUMP variable is NULL."
echo "Script Terminated."
exit
fi
if [ -z "${CDUMP}" ]
then
echo "CDUMP variable is NULL."
echo "Script Terminated."
exit
fi
# Exit if DUMP/BDUMP/CDUMP locations are not ACCESSIBLE:
if [ ! -d ${DUMP} ]
then
echo "The Parent Log DUMP location cannot be Located!"
echo
exit
fi
if [ ! -d ${BDUMP} ]
then
echo "The Log BDUMP location cannot be Located!"
echo
exit
fi
if [ ! -d ${CDUMP} ]
then
echo "The Log CDUMP location cannot be Located!"
echo
exit
fi
echo "Backing up & removing DB & Listener Logs ..."
sleep 1
tail -1000 ${ALERTDB} > ${BDUMP}/alert_${INS}.log.keep
echo
echo -e "\033[32;5mAlertlog Cleanup\033[0m"
echo "Zipping the Alertlog ..."
gzip -f9 ${BDUMP}/alert_${INS}.log
${HASH_BKP} echo "Backing up the Alertlog ..."
${HASH_BKP} mv -f ${BDUMP}/alert_${INS}.log.gz ${BKP_LOC_DB}
echo "Rotating the Alertlog ..."
mv -f ${BDUMP}/alert_${INS}.log.keep ${BDUMP}/alert_${INS}.log
#tar zcvfP ${BKP_LOC_DB}/${INS}-dump-logs.tar.gz ${DUMP}
${HASH_BKP} echo "Backing up ${DUMP} ..."
#find ${DUMP} -name '*' -print > ${BKP_LOC_DB}/dump_files_list.txt
#tar zcfP ${BKP_LOC_DB}/${INS}-dump-logs.tar.gz --files-from ${BKP_LOC_DB}/dump_files_list.txt
cd ${DUMP}
${HASH_BKP} tar zcfP ${BKP_LOC_DB}/${INS}-dump-logs.tar.gz *
# Delete DB logs older than 5 days:
echo
echo -e "\033[32;5mDatabase Logs Cleanup\033[0m"
echo "Deleting DB logs older than 5 days under ${BDUMP} ..."
find ${BDUMP} -type f -name '*.trc' -mtime +5 -exec rm -f {} \;
find ${BDUMP} -type f -name '*.trm' -mtime +5 -exec rm -f {} \;
find ${BDUMP} -type f -name '*.log' -mtime +5 -exec rm -f {} \;
echo "Deleting DB logs older than 5 days under ${DUMP}/alert ..."
find ${DUMP}/alert -type f -name '*.xml' -mtime +5 -exec rm -f {} \;
echo "Deleting DB logs older than 5 days under ${DUMP}/incident ..."
find ${DUMP}/incident -type f -name '*.trc' -mtime +5 -exec rm -f {} \;
find ${DUMP}/incident -type f -name '*.trm' -mtime +5 -exec rm -f {} \;
find ${DUMP}/incident -type f -name '*.log' -mtime +5 -exec rm -f {} \;
echo "Deleting DB logs older than 5 days under ${CDUMP} ..."
find ${CDUMP} -type f -name '*.trc' -mtime +5 -exec rm -f {} \;
find ${CDUMP} -type f -name '*.trm' -mtime +5 -exec rm -f {} \;
find ${CDUMP} -type f -name '*.log' -mtime +5 -exec rm -f {} \;
# Backup & Delete listener's logs:
# ################################
#LISTENER_HOME=`ps -ef|grep -v grep|grep tnslsnr|grep -i ${LSNR_NAME}|awk '{print $(NF-2)}' |sed -e 's/\/bin\/tnslsnr//g'|grep -v sed|grep -v "s///g"|head -1`
echo
echo -e "\033[32;5mListener Logs Cleanup\033[0m"
LISTENER_HOME=`ps -ef|grep -v grep|grep tnslsnr|grep "${LSNR_NAME} "|awk '{print $(8)}' |sed -e 's/\/bin\/tnslsnr//g'|grep -v sed|grep -v "s///g"|head -1`
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'`
LISTENER_LOG=${LISTENER_LOGDIR}/trace/${LISTENER_NAME}.log
echo LISTENER_NAME: $LISTENER_NAME
echo LISTENER_HOME: $LISTENER_HOME
echo TNS_ADMIN: $TNS_ADMIN
# Determine if the listener name is in Upper/Lower case:
if [ ! -r ${LISTENER_LOG} ]
then
# Listner_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
if [ ! -r ${LISTENER_LOG} ]
then
# Listener_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
echo LISTENER_LOG: $LISTENER_LOG
else
echo LISTENER_LOG: $LISTENER_LOG
fi
fi
# Exit if LISTENER LOG directory is NULL:
if [ -z "${LISTENER_LOGDIR}" ]
then
echo "LISTENER_LOGDIR variable is NULL."
echo "Script Terminated."
exit
fi
# Exit if LISTENER LOG directory is IN-ACCESSIBLE:
if [ ! -d ${LISTENER_LOGDIR} ]
then
echo 'Listener Logs Location Cannot be Found!'
echo "Script Terminated."
exit
fi
${HASH_BKP} echo "Backing up listener logs under: ${LISTENER_LOGDIR}/trace ..."
${HASH_BKP} cd ${LISTENER_LOGDIR}/trace
${HASH_BKP} tar zcfP ${BKP_LOC_DB}/${LISTENER_NAME}_trace.tar.gz *
${HASH_BKP} echo "Backing up listener logs under: ${LISTENER_LOGDIR}/alert ..."
${HASH_BKP} cd ${LISTENER_LOGDIR}/alert
${HASH_BKP} tar zcfP ${BKP_LOC_DB}/${LISTENER_NAME}_alert.tar.gz *
tail -10000 ${LISTENER_LOGDIR}/trace/${LISTENER_NAME}.log > ${LISTENER_LOGDIR}/${LISTENER_NAME}.log.keep
echo "Deleting listener logs older than 5 days under: ${LISTENER_LOGDIR}/trace ..."
find ${LISTENER_LOGDIR}/trace -type f -name '*.trc' -mtime +5 -exec rm -f {} \;
find ${LISTENER_LOGDIR}/trace -type f -name '*.trm' -mtime +5 -exec rm -f {} \;
find ${LISTENER_LOGDIR}/trace -type f -name '*.log' -mtime +5 -exec rm -f {} \;
echo "Deleting listener logs older than 5 days under: ${LISTENER_LOGDIR}/alert ..."
find ${LISTENER_LOGDIR}/alert -type f -name '*.xml' -mtime +5 -exec rm -f {} \;
echo "Rotating listener log ${LISTENER_LOGDIR}/trace/${LISTENER_NAME}.log ..."
mv -f ${LISTENER_LOGDIR}/${LISTENER_NAME}.log.keep ${LISTENER_LOGDIR}/trace/${LISTENER_NAME}.log
# ############################
# Backup & Delete AUDIT logs:
# ############################
# Getting Audit Files Location:
# ############################
case ${AUDIT_FILES_CLEANUP} in
Y)
echo
echo -e "\033[32;5mAudit Logs Cleanup\033[0m"
VAL_AUD=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off;
prompt
SELECT value from v\$parameter where NAME='audit_file_dest';
exit;
EOF
)
AUD_LOC=`echo ${VAL_AUD} | perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'`
# Exit if AUDIT LOG variable is NULL:
if [ -z "${AUD_LOC}" ]
then
echo "AUD_LOC variable is NULL."
echo "Script Terminated."
exit
fi
if [ -d ${AUD_LOC} ]
then
#tar zcvfP ${BKP_LOC_DB}/audit_files.tar.gz ${AUD_LOC}/${ORACLE_SID}_*
#find ${AUD_LOC} -type f -name '${ORACLE_SID}_*.aud' -print > ${BKP_LOC_DB}/audit_files_list.txt
#tar zcvfP ${BKP_LOC_DB}/${INS}-audit-logs.tar.gz --files-from ${BKP_LOC_DB}/audit_files_list.txt
${HASH_BKP} echo "Backing up Audit files under: ${AUD_LOC} ..."
${HASH_BKP} cd ${AUD_LOC}
${HASH_BKP} tar zcfP ${BKP_LOC_DB}/${INS}-audit-logs.tar.gz ${ORACLE_SID}_*.aud
# Delete Audit logs older than 5 days
echo "Deleting Audit files older than 5 days under: ${AUD_LOC} ..."
find ${AUD_LOC} -type f -name "${ORACLE_SID}_*.aud" -mtime +5 -exec rm -f {} \;
else
# Exit if AUDIT LOG directory is IN-ACCESSIBLE:
echo "Audit Files Location Cannot be Found!"
exit
fi
;;
esac
echo ""
echo "------------------------------------"
${HASH_BKP} echo "Old logs are backed up under: ${BKP_LOC_DB}"
echo "The Last 5 Days Logs are KEPT."
echo "CLEANUP COMPLETED."
echo "------------------------------------"
echo
# De-Neutralize login.sql file:
# ############################
# If login.sql was renamed during the execution of the script revert it back to its original name:
if [ -f ./login.sql_NeutralizedBy${SCRIPT_NAME} ]
then
mv ./login.sql_NeutralizedBy${SCRIPT_NAME} ./login.sql
fi
if [ -f ${USR_ORA_HOME}/login.sql_NeutralizedBy${SCRIPT_NAME} ]
then
mv ${USR_ORA_HOME}/login.sql_NeutralizedBy${SCRIPT_NAME} ${USR_ORA_HOME}/login.sql
fi
# #############
# END OF SCRIPT
# #############
# REPORT BUGS to: <mahmmoudadel@hotmail.com>.
# DISCLAIMER: THIS SCRIPT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY. IT IS PROVIDED "AS IS".
# DOWNLOAD THE LATEST VERSION OF DATABASE ADMINISTRATION BUNDLE FROM:
# http://dba-tips.blogspot.com/2014/02/oracle-database-administration-scripts.html
view raw oracle_cleanup hosted with ❤ by GitHub


Oracle Database COLD BACKUP Shell Script

Creating a script to take a cold backup of a database may be a time-consuming task, but creating a script to restore this cold backup later is certainly a daunting task.

The shell script I'm sharing will take a database cold backup and then will create a restore script (to be used in case you will restore the cold backup later).

Script download:
https://www.dropbox.com/s/sjibiupwic9oxt1/COLD_BACKUP.sh?dl=0

How it works:

The script checks the current running databases on the server and will ask you to select the number of the database you want to back up from the list (The database you want to back it up should be up and running in order to get the script know the database files location).

It will shut down the database, take a cold backup, create a script to restore the cold backup and finally startup the database.

This script is RAC aware, it will detect if your database is RAC or a standalone one, if it's a RAC DB the script will ensure that there is no other instances are currently running for the same database before starting the cold backup procedure.

Note: This script is not designed for databases having their files located on ASM  :-)

DISCLAIMER: THIS SCRIPT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY. IT IS PROVIDED "AS IS".

The script is part of the database administration bundle, this bundle includes more than 45 scripts covering day to day database administration tasks, you can download the DBA BUNDLE from here: 
[http://dba-tips.blogspot.com/2014/02/oracle-database-administration-scripts.html.



# ##################################################################################################
# Database COLD Backup Script.
# [Ver 1.6] # # #
# Author: Mahmmoud ADEL # # # # ###
# Created: 22-12-13 # # # # #
#
# Modified: 16-05-14 Increased linesize to avoid line breaking.
#
#
# ##################################################################################################
# ###########
# Description:
# ###########
echo
echo "==============================================="
echo "This script Takes a COLD BACKUP for a database."
echo "==============================================="
echo
sleep 1
# #######################################
# Excluded INSTANCES:
# #######################################
# Here you can mention the instances the script 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].
# ###########################
# Listing Available Databases:
# ###########################
# Count Instance Numbers:
INS_COUNT=$( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|wc -l )
# Exit if No DBs are running:
if [ $INS_COUNT -eq 0 ]
then
echo No Database Running !
exit
fi
# If there is ONLY one DB set it as default without prompt for selection:
if [ $INS_COUNT -eq 1 ]
then
export ORACLE_SID=$( 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" )
# If there is more than one DB ASK the user to select:
elif [ $INS_COUNT -gt 1 ]
then
echo
echo "Select the ORACLE_SID:[Enter the number]"
echo ---------------------
select DB_ID 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
if [ -z "${REPLY##[0-9]*}" ]
then
export ORACLE_SID=$DB_ID
echo Selected Instance:
echo
echo "********"
echo $DB_ID
echo "********"
break
else
export ORACLE_SID=${REPLY}
break
fi
done
fi
# Exit if the user selected a Non Listed Number:
if [ -z "${ORACLE_SID}" ]
then
echo "You've Entered An INVALID ORACLE_SID"
exit
fi
# #########################
# 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 [ -f /etc/oratab ]
then
ORATAB=/etc/oratab
export ORATAB
## If OS is Solaris:
elif [ -f /var/opt/oracle/oratab ]
then
ORATAB=/var/opt/oracle/oratab
export ORATAB
fi
# ATTEMPT1: Get ORACLE_HOME using pwdx command:
PMON_PID=`pgrep -lf _pmon_${ORACLE_SID}|awk '{print $1}'`
export PMON_PID
ORACLE_HOME=`pwdx ${PMON_PID}|awk '{print $NF}'|sed -e 's/\/dbs//g'`
export ORACLE_HOME
# ATTEMPT2: If ORACLE_HOME not found get it from oratab file:
if [ ! -f ${ORACLE_HOME}/bin/sqlplus ]
then
## If OS is Linux:
if [ -f /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 [ -f /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 [ ! -f ${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 [ ! -f ${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 [ ! -f ${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 [ ! -f ${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 [ ! -f ${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
# #############################################
# Exit if the executer is not the Oracle Owner:
# #############################################
CURR_USER=`whoami`
if [ ${ORA_USER} != ${CURR_USER} ]; then
echo ""
echo "You're Running This Sctipt with User: \"${CURR_USER}\" !!!"
echo "Please Run This Script With The Right OS User: \"${ORA_USER}\""
echo "Script Terminated!"
exit
fi
# Neutralize login.sql file:
# #########################
# Existance of login.sql file under current working directory eliminates many functions during the execution of this script:
if [ -f ./login.sql ]
then
mv ./login.sql ./login.sql_NeutralizedBy${SCRIPT_NAME}
fi
# ################################
# Creating Backup & Restore Script:
# ################################
echo
echo "Enter the Backup location: [Full Path]"
echo "-------------------------"
while read LOC1
do
EXTEN=${ORACLE_SID}_`date '+%F'`
LOC2=${LOC1}/COLDBACKUP_${EXTEN}
/bin/mkdir -p ${LOC2}
if [ ! -d "${LOC2}" ]; then
echo "Provided Backup Location is NOT Exist/Writable !"
echo
echo "Please Provide a VALID Backup Location:"
echo "---------------------------------------"
else
echo
sleep 1
echo "Backup Location Validated."
echo
break
fi
done
BKPSCRIPT=${LOC2}/Cold_Backup.sh
RSTSCRIPT=${LOC2}/Restore_Cold_Backup.sh
BKPSCRIPTLOG=${LOC2}/Cold_Backup.log
RSTSCRIPTLOG=${LOC2}/Restore_Cold_Backup.log
# Creating the Cold Backup script:
echo
echo "Creating Cold Backup and Cold Restore Scripts ..."
sleep 1
cd ${LOC2}
${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0
set termout off echo off feedback off linesize 400;
spool Cold_Backup.sh
PROMPT echo "Shutting Down Database $ORACLE_SID ... [Ctrl+c to CANCEL]"
PROMPT echo "[5]"
PROMPT sleep 1
PROMPT echo "[4]"
PROMPT sleep 1
PROMPT echo "[3]"
PROMPT sleep 1
PROMPT echo "[2]"
PROMPT sleep 1
PROMPT echo "[1]"
PROMPT sleep 1
PROMPT echo "SHUTTING DOWN NOW ..."
PROMPT sleep 3
PROMPT echo ""
PROMPT ${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
PROMPT shutdown immediate;
PROMPT EOF
PROMPT echo "Database SHUTDOWN SUCCESFULLY."
PROMPT sleep 1
PROMPT echo
PROMPT echo "Starting DB FILES copy ..."
PROMPT echo
PROMPT echo "************************"
PROMPT echo "DON'T CLOSE THIS SESSION, Once the BACKUP JOB is DONE, it will return you back to the PROMPT."
PROMPT echo "************************"
PROMPT echo
PROMPT sleep 1
PROMPT
PROMPT echo -ne '...'
select 'cp -vpf '||name||' ${LOC2} ; echo ' ||'-ne '''||'...''' from v\$controlfile
union
select 'cp -vpf '||name||' ${LOC2} ; echo ' ||'-ne '''||'...''' from v\$datafile
union
select 'cp -vpf '||member||' ${LOC2} ; echo ' ||'-ne '''||'...''' from v\$logfile;
PROMPT touch ${LOC2}/verifier.log
PROMPT echo
spool off
EOF
chmod 700 ${BKPSCRIPT}
# Creating the Restore Script:
${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 termout off echo off feedback off linesize 400;
spool Restore_Cold_Backup.sh
PROMPT echo ""
PROMPT echo "Restoring Database [${ORACLE_SID}] from Cold Backup [${EXTEN}] ..."
PROMPT sleep 1
PROMPT echo ""
PROMPT echo "ARE YOU SURE YOU WANT TO RESTORE DATABASE [${ORACLE_SID}] ? [Y|N] [N]"
PROMPT while read ANS
PROMPT do
PROMPT case \$ANS in
PROMPT y|Y|yes|YES|Yes) echo "RESTORATION JOB STARTED ...";break ;;;
PROMPT ""|n|N|no|NO|No) echo "Script Terminated.";exit;break ;;;
PROMPT *) echo "Please enter a VALID answer [Y|N]" ;;;
PROMPT esac
PROMPT done
PROMPT ORACLE_SID=${ORACLE_SID}
PROMPT export ORACLE_SID
PROMPT echo "Shutting Down Database ${ORACLE_SID} ... [Ctrl+c to CANCEL]"
PROMPT echo "[5]"
PROMPT sleep 1
PROMPT echo "[4]"
PROMPT sleep 1
PROMPT echo "[3]"
PROMPT sleep 1
PROMPT echo "[2]"
PROMPT sleep 1
PROMPT echo "[1]"
PROMPT sleep 1
PROMPT echo "SHUTTING DOWN NOW ..."
PROMPT sleep 3
PROMPT echo ""
PROMPT ${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
PROMPT shutdown immediate;
PROMPT EOF
PROMPT
PROMPT echo "Restoration Job Started ..."
PROMPT echo ""
PROMPT echo -ne '...'
select 'cp -vpf ${LOC2}/'||SUBSTR(name, INSTR(name,'/', -1,1)+1)||' '||name||' ; echo ' ||'-ne '''||'...''' from v\$controlfile
union
select 'cp -vpf ${LOC2}/'||SUBSTR(name, INSTR(name,'/', -1,1)+1)||' '||name||' ; echo ' ||'-ne '''||'...''' from v\$datafile
union
select 'cp -vpf ${LOC2}/'||SUBSTR(member, INSTR(member,'/', -1,1)+1)||' '||member||' ; echo ' ||'-ne '''||'...''' from v\$logfile;
PROMPT echo
PROMPT ${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
PROMPT startup
PROMPT PROMPT
PROMPT PROMPT Adding TEMPFILES TO TEMPORARY TABLESPACES...
select 'ALTER DATABASE TEMPFILE '''||file_name||''' DROP;' from dba_temp_files;
select 'ALTER TABLESPACE '||tablespace_name||' ADD TEMPFILE '''||file_name||''' REUSE;' from dba_temp_files;
PROMPT EOF
PROMPT VAL1=\$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
PROMPT set heading off echo off feedback off termout off
PROMPT select status from v\\\$instance;;
PROMPT EOF
PROMPT )
PROMPT VAL2=\`echo \$VAL1 | perl -lpe'\$_ = reverse' |awk '{print \$1}'|perl -lpe'\$_ = reverse'\`
PROMPT case \${VAL2} in "OPEN")
PROMPT echo "******************************************************"
PROMPT echo "Database [$ORACLE_SID] has been Restored Successfully."
PROMPT echo "Database [$ORACLE_SID] is UP."
PROMPT echo "******************************************************"
PROMPT echo
PROMPT echo ;;;
PROMPT *)
PROMPT echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
PROMPT echo "Database [${ORACLE_SID}] CANNOT OPEN !"
PROMPT echo "Please check the ALERTlOG and investigate."
PROMPT echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
PROMPT echo
PROMPT echo ;;;
PROMPT esac
spool off
EOF
chmod 700 ${RSTSCRIPT}
if [ ! -f "${BKPSCRIPT}" ]; then
echo ""
echo "Backup & Restore Scripts CANNOT be Created."
echo "Script Failed to Create the Cold Backup job !"
echo "Please check the Backup Location permissions."
exit
fi
echo
echo "--------------------------------------------------------"
echo "Backup & Restore Scripts have been Created Successfully."
echo "--------------------------------------------------------"
echo
echo
sleep 1
# ############################
# Executing Cold Backup Script:
# ############################
# Checking if more than one instance is running: [RAC]
echo "Checking Other OPEN instances [RAC]."
sleep 1
VAL3=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
set heading off echo off feedback off termout off
select count(*) from gv\$instance;
EOF
)
VAL4=`echo ${VAL3} | perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'`
if [ ${VAL4} -gt 1 ]
then
echo
echo "WARNING:"
echo "-------"
echo "Please SHUTDOWN ALL other RAC INSTANCES EXCEPT the one on the CURRENT Node."
echo "Then Re-run COLD_BACKUP.sh script Again."
echo ""
exit
fi
echo
echo "VERIFIED: Only ONE INSTANCE is RUNNING for Database [${ORACLE_SID}]."
echo
sleep 1
echo "ARE YOU SURE TO SHUTDOWN DATABASE [${ORACLE_SID}] AND START THE COLD BACKUP JOB? [Y|N] [N]"
while read ANS
do
case $ANS in
y|Y|yes|YES|Yes) echo;echo "COLD BACKUP PROCEDURE STARTED ...";break ;;
""|n|N|no|NO|No) echo;echo "Script Terminated.";exit;break ;;
*) echo "Please enter a VALID answer [Y|N]" ;;
esac
done
echo
echo "Database [${ORACLE_SID}] Will SHUTDOWN within [5 Seconds] ... [To CANCEL press [Ctrl+c]]"
echo "[5]"
sleep 1
echo "[4]"
sleep 1
echo "[3]"
sleep 1
echo "[2]"
sleep 1
echo "[1]"
sleep 1
echo ""
echo "Shutting Down Database [${ORACLE_SID}] ..."
echo "Backup Files will be Copied Under: [${LOC2}] ..."
echo
sleep 1
exec ${BKPSCRIPT} |tee ${BKPSCRIPTLOG}
VAL11=${LOC2}/verifier.log
if [ ! -f ${VAL11} ]
then
echo
echo "xxxxxxxxxxxxxxxxxxx"
echo "Backup Job Failed !"
echo "xxxxxxxxxxxxxxxxxxx"
echo
else
echo
echo "Database Cold Backup is DONE."
echo "Please Note that TEMP DATAFILES are NOT included in this Backup."
echo
echo "****************************************************************"
echo "COLD BACKUP files located under: ${LOC2}"
echo "****************************************************************"
echo
echo "****************************************************************"
echo "Later, To restore database ${DB_ID} from this COLD BACKUP,"
echo "use this script to do that job automatically:"
echo "${RSTSCRIPT}"
echo "****************************************************************"
fi
rm -f ${VAL11}
echo
echo "Do You Want to STARTUP Database [${ORACLE_SID}]? [Y|N] [Y]"
echo "==========================================="
while read ANS
do
case $ANS in
""|y|Y|yes|YES|Yes) echo "STARTING UP DATABASE [${ORACLE_SID}] ..."
${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
STARTUP
EOF
echo
break ;;
n|N|no|NO|No) echo;echo "Script FINISHED."
echo "To restore this database from the COLD BACKUP, Run Script: [${RSTSCRIPT}]"
exit
break ;;
*) echo "Please enter a VALID answer [Y|N]" ;;
esac
done
# De-Neutralize login.sql file:
# ############################
# If login.sql was renamed during the execution of the script revert it back to its original name:
if [ -f ./login.sql_NeutralizedBy${SCRIPT_NAME} ]
then
mv ./login.sql_NeutralizedBy${SCRIPT_NAME} ./login.sql
fi
# #############
# END OF SCRIPT
# #############
# REPORT BUGS to: <mahmmoudadel@hotmail.com>.
# DISCLAIMER: THIS SCRIPT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY. IT IS PROVIDED "AS IS".
# DOWNLOAD THE LATEST VERSION OF DATABASE ADMINISTRATION BUNDLE FROM:
# http://dba-tips.blogspot.com/2014/02/oracle-database-administration-scripts.html
view raw COLD_BACKUP hosted with ❤ by GitHub

Oracle Database Monitoring Script



The backbone monitoring solution for Oracle databases in my environment is dbalarm.sh script. It's a kind of "deploy and forget" script where it can monitor lots of database system components in one go.

The script can report/monitor Database, ASM, Clusterware, Golden Gate and OS main events, including:
  
Database Monitoring:
  - Monitor the DB instance ALERT LOG file and report ORA and TNS errors.
  - Monitor TABLESPACES utilization.  - Monitor FLASH RECOVERY AREA (FRA) utilization.
  - Monitor ASM Disk Groups utilization.
  - Monitor BLOCKING LOCKS.
  - Monitor database named SERVICES. [Service names to be provided to SERVICEMON variable]
  - Monitor RMAN Backup Failure.
  - Monitor the database if it goes OFFLINE or gets HANGED.
  When the Paranoid mode is set to ON:
  - Startup/Shutdown events of the DB instances will be reported.
  - ALTER SYSTEM commands will be reported.
  - ALTER DATABASE commands will be reported.
  - EXPORT/IMPORT operations will be reported.

- Listener Monitoring:
  - Monitor the LISTENERS' LOG file and report TNS errors which plays a crucial rule in reporting connectivity security breaches, applications misconfiguration and network failures.

Grid Infrastructure Monitoring:
  - Monitor the ASM alert log for ORA and TNS errors.
  - Monitor the Grid Infrastructure alert log for ORA and TNS errors.
  - Monitor the Grid Infrastructure alert log for Shutdown/Startup events.
  - Monitor the Grid Infrastructure alert log for Node eviction events.
  - Monitor the Grid Infrastructure alert log for Network IP conflict.
  - Monitor the Grid Infrastructure alert log for Heart Beat failures.
  - Monitor the Grid Infrastructure alert log for service failure events.

OS/Hardware Staff:
  - Monitor the CPU for high utilization.
  - Monitor the Filesystems / Mount Points space utilization.
  - Monitor dmesg log for new entries which let you know what is going on on the OS side.

Golden Gate Monitoring:
  - Monitor the Golden Gate log for Errors and Process ABENDED events.

How it works?

The script is coded to send only new errors that are triggered since the last execution of the script, once the error gets reported once, it won't be reported again unless it appears again in the alert log file.

In order to tailor the script to fulfill your requirements, you have to follow the following simple steps:

Step 1:
Download the script from this link:


Step 2:
Open the script and change the E-mail address to your email address in the line# 60
EMAIL="youremail@yourcompany.com"

Note: sendmail service should be configured on your server to allow emails to be sent out from the DB machine.

Step 3:
By Oracle user:
In the crontab, schedule the script to run at least every 5 minutes:
# crontab -e
#Add this line: 
*/5 * * * * /home/oracle/dbalarm.sh
Note: /home/oracle/dbalarm.sh is the full path that points to dbalarm script where /home/oracle is the Oracle user home directory.

In case you will schedule this script to run from root user's crontab: [Not recommended]
# crontab -e
#Add this line to schedule the run of dbalarm.sh script every 5minutes:
*/5 * * * * su - oracle -c /home/oracle/dbalarm.sh
Now the only thing left here is to set back and relax and the script will report you all errors and all the breached predefined threshold.

One thing more, you can adjust the threshold inside the script as per your preferences by altering the below red colored values in THRESHOLDS section inside the script:

# #########################
# THRESHOLDS:
# #########################
# Modify the THRESHOLDS to the value you prefer:

HTMLENABLE=Y       # Enable HTML Email Format[DB]
FSTHRESHOLD=95 # THRESHOLD FOR FILESYSTEM %USED [OS]
CPUTHRESHOLD=95  # THRESHOLD FOR CPU %UTILIZATION [OS]
TBSTHRESHOLD=95 # THRESHOLD FOR TABLESPACE %USED [DB]
FRATHRESHOLD=95 # THRESHOLD FOR FRA %USED [DB]
FSITHRESHOLD=95   # THRESHOLD FOR FILESYSTEM INODES %USED [OS]
ASMTHRESHOLD=95 # THRESHOLD FOR ASM DISK GROUPS [DB]
BLOCKTHRESHOLD=1          # THRESHOLD FOR BLOCKED SESSIONS count [DB]
WAIT_FOR_LOCK_THRES=1 # THRESHOLD FOR REPORTING BLOCKED SESSIONS BLOCKED FOR MORE THAN N MINUTES
LAST_MIN_BKP_CHK=5 # REPORT RMAN Backups FAILURE in the last N MINUTES. Should be the same interval as the execution interval of dbalarm script in crontab.
CHKRMANBKP=Y         # Enable/Disable Checking of RMAN Backup FAILURE. [Default Enabled]
CHKLISTENER=Y         # Enable/Disable Checking Listeners: [Default Enabled]
CHKOFFLINEDB=Y      # Enable/Disable Database Down Alert: [Default Enabled]
CHKGOLDENGATE=Y   # Enable/Disable Goldengate Alert: [Default Enabled]
CPUDIGMORE=Y          # Break down to DB Active sessions when CPU hit the threshold: [RECOMMENDED TO SET =N on VERY BUSY environments]
TIMEOUTDIGMORE=Y  # Enable/Disable the display of Network Errors when TIMEOUT error gets detected. [Default Enabled]
SERVICEMON=""       # Monitor Specific Named DB Services. e.g.  SERVICEMON="'ORCL_RO','ERP_SRVC','SAP_SERVICE'"
PARANOIDMODE=N    # Paranoid mode will report more events like export/import, instance shutdown/startup. [Default Disabled]
CHKASMALERTLOG=Y  # Enable/Disable Monitoring ASM instance ALERTLOG. [Default Enabled]
CHKCLSALERTLOG=Y  # Enable/Disable Monitoring GRID INFRASTRUCTURE ALERTLOG[Default Enabled]
DEVICEDRIVERLOG=Y  # Enable/Disable Check "dmesg" Device Driver log for errors. [Default Enabled]

You can control script features like checking listener/offline databases/Golden Gate alert/show DB active sessions when CPU is high/monitor specific services by using Y to enable or N to disable it.

You can enable the script to do more checks like (reporting instance startup/shutdown, export/import operations, alter system/database commands and other major DB activities) when activating the Paranoid mode by setting its threshold PARANOIDMODE=Y

In addition, the script gives you the option to exclude specific database, tablespace, ASM Diskgroup, filesystm from having the script run against. You can do so by editing the following parameters:

# #######################################
# 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"

# #########################
# Excluded ASM Diskgroups:
# #########################
# Here you can exclude one or more ASM Disk Groups if you don't 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"
EXL_DISK_GROUP="donotremove"

# ################################
# 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:

EXL_FS="\/dev\/mapper\/|\/dev\/asm\/"                          #Excluded mount points [Will be skipped during the check].

Moreover, you can exclude specific ORA- TNS- errors in case you are OK with ignoring them, I've already excluded some minor frequent incoming errors to not get bothered about them:

# #########################
# Excluded ERRORS:
# #########################
# Here you can exclude the errors that you don't want to be alerted when they appear in the logs:
# Use pipe "|" between each error.

EXL_DB_ALERT_ERR="ORA-2396|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].


This script was tested on Linux environment.

DISCLAIMER: THIS SCRIPT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL BUT WITHOUT ANY WARRANTY. IT IS PROVIDED "AS IS".

If you're looking for a script to check the database health check on a daily basis, please follow this link: 
http://dba-tips.blogspot.ae/2015/05/oracle-database-health-check-script.html

More and more smart and "easy to use" scripts for database administration tasks can be found in the DBA Bundle:
http://dba-tips.blogspot.ae/2014/02/oracle-database-administration-scripts.html

Finally, If you have an opinion/comment/suggestion please share it with me, your feedback is highly appreciated.

In case the download link is not working, you can find the full code below:

#!/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".
view raw dbalarm hosted with ❤ by GitHub