#!/bin/bash # Fred Denis -- June 2016 -- fred.denis3@gmail.com -- http://unknowndba.blogspot.com # asmdu.sh - Shows a clear and nice summary of the ASM diskgroups used and free space (https://bit.ly/3c1pvfQ) # Copyright (C) 2021 Fred Denis # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # # More info and git repo: https://bit.ly/3c1pvfQ -- https://github.com/freddenis/oracle-scripts # # A note on the --nocp option # Note that the --nocp asmcmd option (it disables the connection pooling) has been originaly implemented # as a workaround of a bug that appeared with the April 2016 PSU # It resolves error messages like this one : # sh: -c: line 0: unexpected EOF while looking for matching `'' # sh: -c: line 1: syntax error: unexpected end of file # # # The current version of the script is 20211111 # # 20211111 - Fred Denis - GPLv3 licence # 20211018 - Fred Denis - Cosmetic, indentation, protect and quote, $() instead of `` # Use of olr.loc instead of oraenv if possible # 20190906 - Fred Denis - A new -V option to show the version of the script # 20190219 - Fred Denis - Some had issues with the instance list, I then moved from sed to cut to fix it -- Thanks Jakub ! # 20181218 - Fred Denis - A new -n option to print with no color -- DEFAULT_NOCOLOR can be used to modify the default behavior # Fixed the regexp to list the instances running # 20180827 - Fred Denis - A better regexp to list the instances running # 20180503 - Fred Denis - GI 12c introduces a "Logical_Sector" column, took this into account (Thanks Leon !) # 20180327 - Fred Denis - "Raw Used " label for the subdirectories "Mirror_used_MB" column, adjustments in the help # 20180318 - Fred Denis - Shows only mirrored sizes by default and the total non mirrored size only shown with the -v option # 20180211 - Fred Denis - Many improvements : # - -d options to list the subdirectories of a directory # - -v option to show the Raw Free and Reserverd size # - -m -g and -t to choose the Unit you want the report to be in # - Default values and verbosity can be changed using the DEFAULT_UNIT and the DEFAULT_VERBOSE variables # - A nice usage function # 20170719 - Fred Denis - Remove the --nocp option as default # # # Default values (when no option is specified in the command line) # The last uncommented value wins # DEFAULT_UNIT="MB" # asmcmd default DEFAULT_UNIT="GB" DEFAULT_UNIT="TB" DEFAULT_VERBOSE="Yes" DEFAULT_VERBOSE="No" DEFAULT_NOCOLOR="Yes" # Print with no color DEFAULT_NOCOLOR="No" # Print with colors CRITICAL=90 # Colored thresholds (Red, Yellow, Green) WARNING=75 # Colored thresholds (Red, Yellow, Green) WHITE="\033[1;37m" END_COLOR="\033[m" OLR="/etc/oracle/olr.loc" # olr.loc file to get crs home if oratab does not have ASM entry # # Show the version of the script (-V) # show_version() { VERSION=$(awk '{if ($0 ~ /^# 20[0-9][0-9][0-1][0-9]/) {print $2; exit}}' $0) printf "\n\t\033[1;36m%s\033[m\n" "The current version of "`basename $0`" is "$VERSION"." ; } # # An usage function # usage() { printf "\n\033[1;37m%-8s\033[m\n" "NAME" ; cat << END asmdu.sh - Shows a clear and nice summary of the ASM diskgroups used and free space (https://bit.ly/3c1pvfQ) END printf "\n\033[1;37m%-8s\033[m\n" "SYNOPSIS" ; cat << END $0 [-d] [-m -g -t] [-n] [-v] [-V] [-h] END printf "\n\033[1;37m%-8s\033[m\n" "DESCRIPTION" ; cat << END $0 needs to be executed as the GI owner user to be able to use asmcmd With no option $0 will be showing what instances are running and a size summary for each DiskGroup END printf "\n\033[1;37m%-8s\033[m\n" "OPTIONS" ; cat << END -d The directory you want the size details -v Verbose -- show the "Total Raw", "Raw Free" and "Reserved" size You can change the default behavior with the DEFAULT_VERBOSE variable -m Shows the output in MB -g Shows the output in GB -t Shows the output in TB -m -g -t The default Unit can be specified using the DEFAULT_UNIT variable If more than one of these options is specified, the last one wins -n Shows the output with no color (handy to send it by email) -V Shows the version of the script -h Shows this help END exit 123 } # # Parameters management # PARAM_UNIT="" PARAM_VERBOSE="" # while getopts "d:mgtnvhV" OPT; do case ${OPT} in d) D=${OPTARG} ;; m) PARAM_UNIT="MB" ;; g) PARAM_UNIT="GB" ;; t) PARAM_UNIT="TB" ;; n) PARAM_NOCOLOR="Yes" ;; v) PARAM_VERBOSE="Yes" ;; V) show_version; exit 567 ;; h) usage ;; \?) echo "Invalid option: -$OPTARG" >&2; usage ;; esac done # if [[ -z "${PARAM_UNIT}" ]]; then # No parameter specified, we use the default UNIT="${DEFAULT_UNIT}" else UNIT="${PARAM_UNIT}" fi if [[ -z "${PARAM_VERBOSE}" ]]; then # No parameter specified, we use the default VERBOSE="${DEFAULT_VERBOSE}" else VERBOSE="${PARAM_VERBOSE}" fi if [[ -z "${PARAM_NOCOLOR}" ]]; then # No parameter specified, we use the default NOCOLOR="${DEFAULT_NOCOLOR}" else NOCOLOR="${PARAM_NOCOLOR}" fi if [[ "${NOCOLOR}" == "Yes" ]]; then WHITE="" END_COLOR="" fi # # Set the ASM env # if [[ -f "${OLR}" ]]; then export ORACLE_HOME=$(cat "${OLR}" | grep "^crs_home" | awk -F "=" '{print $2}') export ORACLE_BASE=$(${ORACLE_HOME}/bin/orabase) export PATH="${PATH}:${ORACLE_HOME}/bin" else ORACLE_SID=$(ps -ef | grep pmon | grep asm | awk '{print $NF}' | sed s'/asm_pmon_//' | egrep "^[+]") export ORAENV_ASK=NO . oraenv > /dev/null 2>&1 fi # # A quick list of the instances that are running on the server # ps -ef | grep pmon | grep -v grep | awk '{print $NF}' | cut -d_ -f3,4 | sort | awk -v H="`hostname -s`" 'BEGIN {printf("\n%s", "Instances running on " H " : ")} { printf("%s, ", $0)} END{printf("\n")}' | sed s'/, $//' # # Manage parameters # if [[ -z "${D}" ]]; then # No directory provided, will check all the DG DG=$(asmcmd lsdg | grep -v State | awk '{print $NF}' | sed s'/\///') SUBDIR="No" # Do not show the subdirectories details if no directory is specified else DG=$(echo $D | sed s'/\/.*$//g') fi # # A header # printf "\n%25s%16s${WHITE}%16s${END_COLOR}" "DiskGroup" "Redundancy" "Total ${UNIT}" # "Raw Free ${UNIT}" "Reserved ${UNIT}" "Usable ${UNIT}" "% Free" if [[ "${VERBOSE}" == "Yes" ]]; then printf "%16s%16s%16s" "Raw Total ${UNIT}" "Raw Free ${UNIT}" "Reserved ${UNIT}" fi printf "${WHITE}%16s%14s${END_COLOR}\n" "Usable ${UNIT}" "% Free" printf "%25s%16s${WHITE}%16s${END_COLOR}" "---------" "-----------" "--------" if [[ "${VERBOSE}" == "Yes" ]]; then printf "%16s%16s%16s" "------------" "-----------" "-----------" fi printf "${WHITE}%16s${END_COLOR}%14s\n" "---------" "------" # # Show DG info # for X in ${DG}; do asmcmd lsdg "${X}" | tail -1 |\ awk -v DG="$X" -v W="$WARNING" -v C="$CRITICAL" -v UNIT="$UNIT" -v VERBOSE="$VERBOSE" -v NOCOLOR="$NOCOLOR" '\ BEGIN \ { if (NOCOLOR == "Yes") { COLOR_BEGIN = "" ; COLOR_END = "" ; RED = "" ; GREEN = "" ; YELLOW = "" ; WHITE = "" ; COLOR = "" ; } else { COLOR_BEGIN = "\033[1;" ; COLOR_END = "\033[m" ; RED = COLOR_BEGIN"31m" ; GREEN = COLOR_BEGIN"32m" ; YELLOW = COLOR_BEGIN"33m" ; WHITE = COLOR_BEGIN"37m" ; COLOR = GREEN ; } DIVIDER = 1 ; # Unit divider RED_DIV = 1 ; # Redundancy divider if (UNIT == "GB") { DIVIDER="1024" } ; if (UNIT == "TB") { DIVIDER="1048576"} ; # 1024 * 1024 } { if ($2 == "HIGH") {RED_DIV=3 ;} # Redundancy divider if ($2 == "NORMAL") {RED_DIV=2 ;} # Redundancy divider TOTAL = sprintf("%16.2f", $(NF-6)/DIVIDER/RED_DIV) ; # Total mirrored in Unit USABLE = sprintf("%16.2f", $(NF-3)/DIVIDER) ; # Usable space in Unit FREE = sprintf("%12d" , USABLE/TOTAL*100) ; # % Free calculated using the Usable size if ((100-FREE) > W) { COLOR=YELLOW ;} # Colored %Free thresholds if ((100-FREE) > C) { COLOR=RED ;} # Colored %Free thresholds printf("%25s%16s%16s", DG, $2, WHITE TOTAL COLOR_END) ; # DG Redundancy and Total if (VERBOSE == "Yes") { printf("%16.2f%16.2f%16.2f", $(NF-6)/DIVIDER, $(NF-5)/DIVIDER, $(NF-4)/DIVIDER); # Total Raw, Raw Free and reserved if Verbose } printf("%16s%14s\n", WHITE USABLE COLOR_END, COLOR FREE COLOR_END) ; # Usable and Free % }' done printf "\n" # # Subdirs info # if [[ -z "${SUBDIR}" ]]; then (for DIR in $(asmcmd ls "${D}"); do echo "${DIR}" $(asmcmd --nocp du "${D}/${DIR}" | tail -1) # Please look at the "About the --nocp option" notes in the header for more information # echo ${DIR} `asmcmd du ${D}/${DIR} | tail -1` done) | awk -v D="${D}" -v UNIT="${UNIT}"\ ' BEGIN { printf("\n\t\t%40s\n\n", D " subdirectories size") ; printf("%25s%16s%16s\n", "Subdir", "Used " UNIT, "Raw Used " UNIT) ; printf("%25s%16s%16s\n", "------", "-------", "-----------") ; DIVIDER=1 ; if (UNIT == "GB") { DIVIDER="1024" } ; if (UNIT == "TB") { DIVIDER="1048576" } ; # 1024 * 1024 } { use=sprintf("%16.2f", $2/DIVIDER) ; mir=sprintf("%16.2f", $3/DIVIDER) ; printf("%25s%16s%16s\n", $1, use, mir) ; total_use += $2 ; total_mir += $3 ; } END { total_use = sprintf("%16.2f", total_use/DIVIDER) ; total_mir = sprintf("%16.2f", total_mir/DIVIDER) ; printf("\n\n%25s%16s%16s\n", "------", "-------", "---------") ; printf("%25s%16s%16s\n\n", "Total", total_use, total_mir) ; } ' fi # # For information # if [[ "${VERBOSE}" == "Yes" ]]; then printf "\t\t%40s\n\n" "Note : Usable = (Raw Free - Reserved)/Redundancy" ; fi #****************************************************************************************# #* E N D O F S O U R C E *# #****************************************************************************************#