#!/bin/bash ## ## Setting variables to be used ############################################## ## ## ## COLOURS ## ## ## ############################################## RED='\033[0;31m' GREEN='\033[0;32m' LIGHT_GREEN='\033[1;32m' YELLOW='\033[1;33m' NC='\033[0m' # No colour function request_settings { ############################################## ## ## ## SETTINGS ## ## ## ############################################## # Ask the user whether the check is to be performed against the local server or if the checks are being performed against an sosreport. If an sosreport is used, # then we should set the location of the sosreport. ### Initially, we'll just ask for the location - the default will be the current directory (implying an sosreport is being checked) read -p "Please provide the relative location to be checked. Using the current directory (default), if at the root of a sosreport, will check the sosreport. Using / will check the local server) [current working directory]: " CHK_LOC CHK_LOC=${CHK_LOC:-"$PWD"} if [ "$CHK_LOC" == "/" ]; then LOCALSYS=yes else LOCALSYS=no fi echo "" # The DBA_SGA_SIZE variable should be provided by the Oracle DBA and should be the sum of the SGA sizes in megabytes. This value is used to calculate an approximate # value for the amount of RAM that should be reserved for hugepages on the system and should therefore be set slightly larger than the sum of the SGA sizes to ensure # that the entire SGA memory can be allocated to hugepages. If you do not wish to use hugepages, set this value to 0. read -p "Please enter the sum total, in megabytes, of SGA sizes (provided by your Oracle DBA) [200]: " DBA_SGA_SIZE DBA_SGA_SIZE=${DBA_SGA_SIZE:-200} echo "" # The SQL_PROCEESES variable should be provided by the Oracle DBA and should be sum of the Oracle SQL processes per database that typically run on the server. The # number of SQL processes for a database can be checked by logging onto the database and running the following command: # SQL> show parameter processes; # NAME TYPE VALUE # --------------------------- ---------- # processes integer 300 # The default value is 300 which is correct for no databases created. read -p "Please enter the sum total of SQL processes running (provided by your Oracle DBA) [300]: " SQL_PROCESSES SQL_PROCESSES=${SQL_PROCESSES:-300} echo "" # For Oracle RAC servers it is usual to have a private network created. This script checks that the reverse path filter is correctly set on the private interfaces. # If there are multiple interfaces assigned as private interfaces they should be added here separated by spaces. #PRIV_INTERFACE="enp6s0 wlp3s0" if [ "LOCAL_SYS" == "yes" ]; then ACTIVE_NICS=`ip a | grep UP | awk '{ print $2 }' | rev | cut -c 2- | rev` else ACTIVE_NICS=`cat "$CHK_LOC"/sos_commands/networking/ip_address | grep UP | awk '{ print $2 }' | rev | cut -c 2- | rev` fi echo -e "The active NICs detected for this server are: $ACTIVE_NICS" read -p "Please provide the interfaces that have been specified as private interfaces for Oracle RAC. If multiple interfaces are private, please provide as a space separated list [eth0]:" PRIV_INTERFACE PRIV_INTERFACE=${PRIV_INTERFACE:-eth0} echo "" # Oracle database environments should have increased ulimits for the oracle (and grid user if using RAC) user by modifiying a limits file. It is recommended practice # to modify a custom limits file in /etc/security/limits.d/ to make these changes. The custom file, or files, used should be specified here. read -p "If you have a custom Oracle limits.conf file please specify the location here [$CHK_LOC/etc/security/limits.d/99-oracle.conf]: " ORACLE_LIMITS_FILE ORACLE_LIMITS_FILE=${ORACLE_LIMITS_FILE:-"$CHK_LOC"/etc/security/limits.d/99-oracle.conf} read -p "If you have a custom Oracle Grid limits.conf file please specify the location here [$CHK_LOC/etc/security/limits.d/99-grid.conf]: " GRID_LIMITS_FILE GRID_LIMITS_FILE=${GRID_LIMITS_FILE:-"$CHK_LOC"/etc/security/limits.d/99-grid.conf} echo "" # Have the user enter the user account that oracle is running under - we can try and provide our best guess - but we can prompt for the user if [ "$LOCALSYS" == "no" ]; then EST_ORACLE_USER=`grep ora_ "$CHK_LOC"/ps | head -n1 | awk '{ print $1 }'` else EST_ORACLE_USER=`ps aux | grep ora_ | head -n1 | awk '{ print $1 }'` fi read -p "Please enter the user account that the Oracle database is running under [$EST_ORACLE_USER]:" ORACLE_USER ORACLE_USER=${ORACLE_USER:-$EST_ORACLE_USER} read -p "Is this server also running as an Oracle RAC node (i.e. with a grid user) [no]" RAC_RUNNING RAC_RUNNING=${RAC_RUNNING:-no} if [ "$RAC_RUNNING" == "yes" ]; then read -p "Please enter the user account that the Oracle RAC grid services are running under [grid]:" GRID_USER GRID_USER=${GRID_USER:-grid} fi # Not sure if this setting is necessary - testing only. CALC_NR_HUGEPAGES=2 echo "" echo "" } function curr_env { ## Current environment ##RHEL_DETECT=`cat /etc/redhat-release | awk '{ print $1 " " $2 " " $3 " " $4 }'` ##RHEL_VER=`cat /etc/redhat-release | awk '{ print $7 }'` ##RHEL_RELEASE=${RHEL_VER:0:1} ##RUNNING_KERNEL=`uname -r` ##PHYS_MEM=`cat /proc/meminfo | grep MemTotal | awk '{ print $2 }'` if [ -f "$CHK_LOC"/etc/os-release ]; then source "$CHK_LOC"/etc/os-release RHEL_DETECT=$NAME RHEL_VER=$VERSION_ID RHEL_RELEASE=${RHEL_VER:0:1} elif [ -f "$CHK_LOC"/etc/redhat-release ]; then RHEL_DETECT=`cat "$CHK_LOC"/etc/redhat-release | awk '{ print $1 " " $2 " " $3 " " $4 " " $5 }'` RHEL_VER=`cat "$CHK_LOC"/etc/redhat-release | awk '{ print $7 }'` RHEL_RELEASE=${RHEL_VER:0:1} else RHEL_DETECT="Unknown OS" RHEL_VER="Unknown OS version" RHEL_RELEASE="Unknown OS release" fi if [ -f "$CHK_LOC"/uname ]; then RUNNING_KERNEL=`cat "$CHK_LOC"/uname | awk '{ print $3 }'` else RUNNING_KERNEL=`uname -r` fi PHYS_MEM=`cat "$CHK_LOC"/proc/meminfo | grep MemTotal | awk '{ print $2 }'` if [ "$RHEL_DETECT" != "Red Hat Enterprise Linux Server" ]; then RHEL_DTCT_WARN="${RED}Non-RHEL operating system detected - the script may run but is not supported on this platform." else RHEL_DTCT_WARN="${GREEN}RHEL $RHEL_VER detected. If this is incorrect please let me know." fi echo -e $RHEL_DTCT_WARN echo -e "${GREEN}Detected RHEL Major Release: $RHEL_RELEASE" echo -e "${GREEN}Detected RHEL: $RHEL_VER" echo -e "${GREEN}Detected kernel: $RUNNING_KERNEL" echo -e "${GREEN}Detected physical memory: $PHYS_MEM" echo "" echo "" } function confirm_settings { if [ "$CHK_LOC" == "yes" ]; then CHK_TYPE="Local" else CHK_TYPE="sosreport" fi echo -e "${GREEN}The configured settings to be used for this Oracle DB tuning check are as follows:" echo "" echo -e "${GREEN}Server information source type: ${LIGHT_GREEN}$CHK_TYPE" echo -e "${GREEN}Server information source: ${LIGHT_GREEN}$CHK_LOC" echo -e "${GREEN}SGA Size: ${LIGHT_GREEN}$DBA_SGA_SIZE" echo -e "${GREEN}Number of SQL processes: ${LIGHT_GREEN}$SQL_PROCESSES" echo -e "${GREEN}Private network interfaces: ${LIGHT_GREEN}$PRIV_INTERFACE" echo -e "${GREEN}Custom Oracle limits file: ${LIGHT_GREEN}$ORACLE_LIMITS_FILE" echo -e "${GREEN}Custom Oracle Grid limits file: ${LIGHT_GREEN}$GRID_LIMITS_FILE" echo -e "${GREEN}Oracle user account: ${LIGHT_GREEN}$ORACLE_USER" if [ "$RAC_RUNNING" == "yes" ]; then echo -e "${GREEN}Oracle grid user account: ${LIGHT_GREEN}$GRID_USER" fi echo -e "${GREEN}###################################################################" read -p "Do you want to proceed with the Oracle check based on these values? [y]" CONFIRM_PROCEED CONFIRM_PROCEED=${CONFIRM_PROCEED:-y} echo $CONFIRM_PROCEED if [ "$CONFIRM_PROCEED" == "y" ]; then echo "" echo -e "${GREEN}***** Check Output Below *****" else exit fi } function swap_calc { ## Script to calculate the currently recommended amount of swap to configure for an Oracle database server. ## This calculation is based from the Deploying Oracle RAC 12c on RHEL 7 Tuning Guide: ## https://access.redhat.com/articles/1357883 (Section: 2.6) ## Specifically, swap is recommended to be equal to physical RAM minus any RAM allocated to hugepages (if ## < 16GB of physical RAM is present) or set to 16GB if more than 16GB of physical RAM is present. NUM_HUGEPAGES=`cat "$CHK_LOC"/proc/meminfo | grep HugePages_Total | awk '{ print $2 }'` HUGEPAGE_SZ=`cat "$CHK_LOC"/proc/meminfo | grep Hugepagesize | awk '{ print $2 }'` HUGEPAGE_MEM=$((NUM_HUGEPAGES * $HUGEPAGE_SZ)) CURR_SWAP=`cat "$CHK_LOC"/proc/meminfo | grep SwapTotal | awk '{ print $2 }'` SWAPPABLE_RAM=$((PHYS_MEM - HUGEPAGE_MEM)) SWAP_GB=$((SWAPPABLE_RAM / 1048576)) SWAP_MB=$((SWAPPABLE_RAM / 1024)) REC_HUGEPAGES=$((DBA_SGA_SIZE * 1024 / $HUGEPAGE_SZ)) if [ "$SWAPPABLE_RAM" -lt "16324560" ]; then if [ "$SWAP_GB" -eq "0" ]; then REC_SWAP="For testing purposes - advised swap size:" LOW_MEM_WARN="${RED}WARNING: There is less than 1GB of usable RAM - you might need to reduce \nthe number of hugepages or add more RAM. This system is unlikely to \nperform well.\n\n" else REC_SWAP="Swap space advised to be set to:" # LOW_MEM_WARN="" fi else REC_SWAP="Swap space advised to be set to:" SWAPPABLE_RAM="16324560" # LOW_MEM_WARN="" fi if [ "$CURR_SWAP" -gt "$SWAPPABLE_RAM" ]; then SWAP_COL="${YELLOW}" SWAP_WARN="${GREEN}INFO: The current swap size is larger than the calculated recommended \nvalue. This should be fine, however, if the server is showing signs of \nexcessive swap activity you could consider reducing the swap size.\n\n" elif [ "$CURR_SWAP" -lt "$SWAPPABLE_RAM" ]; then SWAP_COL="${RED}" SWAP_WARN="WARNING: The current swap size is smaller than the calculated advised\nvalue. You should consider increasing the swap size of this server.\n\n" else SWAP_COL="${LIGHT_GREEN}" SWAP_WARN="The current swap size is in line with the recommended swap size. No changes \nshould be necessary.\n\n" fi if [ "$NUM_HUGEPAGES" == "0" ]; then HGPG_COL="${RED}" HGPG_WARN="${RED}You have not configured hugepages on this server. Red Hat and Oracle \nrecommend the use of hugepages for optimisation.\n\n" else if [ "$NUM_HUGEPAGES" -ge "$REC_HUGEPAGES" ]; then HGPG_COL="${LIGHT_GREEN}" HGPG_WARN="${GREEN}Hugepages looks to be correctly configured on this system. If the \nrecommended number of hugepages is close to the actual number of \nhugepages configured, you should make sure Oracle is using them as expected.\n\n" else HGPG_COL="${RED}" HGPG_WARN="${RED}You have too few hugepages configured to load the entire SGA into \nhugepages. This means the SGA will not utilise hugepages, and is not the recommended setting.\n\n" fi fi echo -e "${GREEN}#########################################################################" echo -e "# #" echo -e "# Swap Settings #" echo -e "# #" echo -e "#########################################################################" echo -e "" printf "${GREEN}Physical Memory (kB) Present is: %-29s ${LIGHT_GREEN}$PHYS_MEM\n" printf "${GREEN}Number of hugepages allocated: %-31s ${HGPG_COL}$NUM_HUGEPAGES\n" printf "${GREEN}Minimum recommended number of hugepages: %-21s ${LIGHT_GREEN}$REC_HUGEPAGES\n" printf "${GREEN}Size of each hugepage (kB): %-34s ${LIGHT_GREEN}$HUGEPAGE_SZ\n" printf "${GREEN}Amount of RAM (kB) allocated to hugepages: %-19s ${LIGHT_GREEN}$HUGEPAGE_MEM\n" printf "${GREEN}Amount of (non-hupegages) RAM (kB) to calculate for swap size:%-1s${LIGHT_GREEN}$SWAPPABLE_RAM\n" printf "${GREEN}%-62s ${LIGHT_GREEN}%-10s\n" "$REC_SWAP" "$SWAPPABLE_RAM" printf "${GREEN}Current swap size (kB): %-38s ${SWAP_COL}$CURR_SWAP\n" echo -e "" printf "$HGPG_WARN" printf "$SWAP_WARN" printf "$LOW_MEM_WARN" } function selinux_check { if [ -f "$CHK_LOC"/sos_commands/selinux/sestatus_-b ]; then SELINUX_STATUS=`cat "$CHK_LOC"/sos_commands/selinux/sestatus_-b | grep "SELinux status" | awk '{ print $3 }'` SELINUX_SET_CURR=`cat "$CHK_LOC"/sos_commands/selinux/sestatus_-b | grep "Current mode" | awk '{ print $3 }'` SELINUX_SET_CFG=`cat "$CHK_LOC"/sos_commands/selinux/sestatus_-b | grep "Mode from config file" | awk '{ print $5 }'` if [ "$RHEL_RELEASE" == "7" ]; then SELINUX_POL_CFG=`cat "$CHK_LOC"/sos_commands/selinux/sestatus_-b | grep "Loaded policy name" | awk '{print $4 }'` else SELINUX_POL_CFG=`cat "$CHK_LOC"/sos_commands/selinux/sestatus_-b | grep "Policy from config file" | awk '{ print $5 }'` fi elif [ -f `type -p sestatus` ]; then SELINUX_STATUS=`sestatus | grep "SELinux status" | awk '{ print $3 }'` SELINUX_SET_CURR=`sestatus | grep "Current mode" | awk '{ print $3 }'` SELINUX_SET_CFG=`sestatus | grep "Mode from config file" | awk '{ print $5 }'` if [ "$RHEL_RELEASE" == "7" ]; then SELINUX_POL_CFG=`cat "$CHK_LOC"/sos_commands/selinux/sestatus_-b | grep "Loaded policy name" | awk '{print $4 }'` else SELINUX_POL_CFG=`sestatus | grep "Policy from config file" | awk '{ print $5 }'` fi else SELINUX_STATUS="Not Available" SELINUX_SET_CURR="Not Available" SELINUX_SET_CFG="Not Available" SELINUX_POL_CFG="Not Available" fi if [ "$SELINUX_STATUS" = "enabled" ]; then SEL_STAT="${LIGHT_GREEN}Enabled" else SEL_STAT="${RED}Disabled" SEL_POL_WARN="\n${RED}SELinux has been disabled on this system - you should fix this.\n\n" fi if [ "$SELINUX_SET_CURR" = "enforcing" ]; then SEL_SET="${LIGHT_GREEN}Enforcing" elif [ "$SELINUX_SET_CURR" = "permissive" ]; then SEL_SET="${YELLOW}Permissive" SEL_WARN="${YELLOW}\nSELinux is set to permissive mode. SELinux violations will be logged but \nnot prevented. Ideally you should set SELinux to enforcing mode.\n\n" else SEL_SET="${RED}disabled" SEL_WARN="${RED}\nSELinux has been disabled on this server. You should enable SELinux.\n\n" fi if [ "$SELINUX_SET_CURR" = "$SELINUX_SET_CFG" ]; then SEL_ALTERED="${GREEN}SELinux configuration running as specified in /etc/sysconfig/selinux \nconfiguration file.\n\n" else SEL_ALTERED="${RED}SELinux is not currently running in the configuration as specified in \n/etc/sysconfig/selinux - this will probably not survive a reboot.\n\n" fi echo -e "${GREEN}#########################################################################" echo -e "# #" echo -e "# SELinux Settings #" echo -e "# #" echo -e "#########################################################################" echo -e "" echo -e "${GREEN}SELinux status on this system: " $SEL_STAT echo -e "${GREEN}Current SELinux mode on this system: " $SEL_SET echo -e "${GREEN}Configured SELinux mode on this system: " $SELINUX_SET_CFG echo -e "${GREEN}SELinux policy on this system: " $SELINUX_POL_CFG printf "$SEL_POL_WARN" printf "$SEL_POL_TGT_WARN" printf "$SEL_WARN" printf "$SEL_ALTERED" } function vm_check { ## Virtual Memory Settings # Swappiness Check # By default, /prov/sys/vm/swappiness is set to 60 on RHEL. This is fine as a default setting, however for Oracle workloads this value should be decreased to reduce the # aggressiveness with which the kernel will try and move already allocated, but infrequently used, memory from RAM to swap. Since RHEL 6.4 it is strongly advised not to set this # value to 0 - as this can lead to OOM killing under strong memory and I/O pressure. # These values are based from the Deploying Oracle RAC 12c on RHEL 7 Tuning Guide: https://access.redhat.com/articles/1357883 (Section: 3.3.6) SWAPPINESS=`cat "$CHK_LOC"/proc/sys/vm/swappiness` if [ "$SWAPPINESS" == "1" ]; then SWPNSS_WARN="${GREEN}The value of /proc/sys/vm/swappiness on this server is currently set \nto 1 which is the advised setting.\n\n" SWPNSS_COL="${LIGHT_GREEN}" elif [ "$SWAPPINESS" == "0" ]; then SWPNSS_WARN="${RED}The value of /proc/sys/vm/swappiness on this server is currently set \nto 0. The value should be increased to 1, as a value of 0 can lead to \nout-of-memory \(OOM\) killing under strong memory and I/O pressure.\n\n" SWPNSS_COL="${RED}" else SWPNSS_WARN="${YELLOW}The value of /proc/sys/vm/swappiness on this server is currently set \nto $SWAPPINESS - it is advised to reduce this value to 1.\n\n" SWPNSS_COL="${YELLOW}" fi # echo -e "Value of /proc/sys/vm/swappiness: "$SWPNSS_COL$SWAPPINESS # Dirty Data # Dirty data is data that has been modified and held in the page cache for performance benefits. Once this data is flushed to disk it is considered clean. Two tuneables are # available - dirty_ratio and dirty_background_ratio. For a full explanation of recommended values please refer to: https://access.redhat.com/articles/1357883 DIRTY_RATIO=`cat "$CHK_LOC"/proc/sys/vm/dirty_ratio` DIRTY_BACKGROUND_RATIO=`cat "$CHK_LOC"/proc/sys/vm/dirty_background_ratio` DIRTY_EXPIRE_CENTISECS=`cat "$CHK_LOC"/proc/sys/vm/dirty_expire_centisecs` DIRTY_WRITEBACK_CENTISECS=`cat "$CHK_LOC"/proc/sys/vm/dirty_writeback_centisecs` if [ "$DIRTY_RATIO" -ge "40" ]; then # DRTY_RTIO_WARN="" DRTY_RTIO="${LIGHT_GREEN}$DIRTY_RATIO" else DRTY_RTIO_WARN="${YELLOW}The value of /proc/sys/vm/dirty_ratio on this server is set to: $DIRTY_RATIO and \nshould be changed to a value between 40 and 80. \nPlease read: \nhttps://access.redhat.com/solutions/39188 and \nhttps://access.redhat.com/articles/1357883 for details.\n\n" DRTY_RTIO="${YELLOW}$DIRTY_RATIO" fi # echo -e "${GREEN}Value of /proc/sys/vm/dirty_ratio: " $DRTY_RTIO if [ "$DIRTY_BACKGROUND_RATIO" == "3" ]; then DRTY_BCKGRD_RTIO_WARN="" DRTY_BCKGRD_RTIO="${LIGHT_GREEN}3" else DRTY_BCKGRD_RTIO_WARN="${YELLOW}The value of /proc/sys/vm/dirty_background_ratio on this server is set to: $DIRTY_BACKGROUND_RATIO this should be changed to 3. \nPlease read https://access.redhat.com/solutions/39188 and \nhttps://access.redhat.com/articles/1357883 for details.\n\n" DRTY_BCKGRD_RTIO="${YELLOW}$DIRTY_BACKGROUND_RATIO" fi # echo -e "${GREEN}Value of /proc/sys/vm/dirty_background_ratio: " $DRTY_BCKGRD_RTIO if [ "$DIRTY_EXPIRE_CENTISECS" == "500" ]; then # DRTY_CNTSCS_WARN="" DRTY_CNTSCS="${LIGHT_GREEN}500" else DRTY_CNTSCS_WARN="${YELLOW}The value of /proc/sys/vm/dirty_expire_centisecs on this server is set to: $DIRTY_EXPIRE_CENTISECS this should be changed to 500. \nPlease read https://access.redhat.com/solutions/39188 and \nhttps://access.redhat.com/articles/1357883 for details.\n\n" DRTY_CNTSCS="${YELLOW}$DIRTY_EXPIRE_CENTISECS" fi # echo -e "${GREEN}Value of /proc/sys/vm/dirty_expire_centisecs: " $DRTY_CNTSCS if [ "$DIRTY_WRITEBACK_CENTISECS" == "100" ]; then DRTY_WRBCK_CNTSCS_WARN="" DRTY_WRBCK_CNTSCS="${LIGHT_GREEN}100" else DRTY_WRBCK_CNTSCS_WARN="${YELLOW}The value of /proc/sys/vm/dirty_writeback_centisecs on this server is set to: $DIRTY_WRITEBACK_CENTISECS this should be changed to 100. \nPlease read https://access.redhat.com/solutions/39188 and \nhttps://access.redhat.com/articles/1357883 for details.\n\n" DRTY_WRBCK_CNTSCS="${YELLOW}$DIRTY_WRITEBACK_CENTISECS" fi # echo -e "${GREEN}Value of /proc/sys/vm/dirty_writeback_centisecs:" $DRTY_WRBCK_CNTSCS echo -e "${GREEN}#########################################################################" echo -e "# #" echo -e "# Virtual Memory Settings #" echo -e "# #" echo -e "#########################################################################" echo -e "" echo -e "${GREEN}Value of /proc/sys/vm/swappiness: "$SWPNSS_COL$SWAPPINESS echo -e "${GREEN}Value of /proc/sys/vm/dirty_ratio: " $DRTY_RTIO echo -e "${GREEN}Value of /proc/sys/vm/dirty_background_ratio: " $DRTY_BCKGRD_RTIO echo -e "${GREEN}Value of /proc/sys/vm/dirty_expire_centisecs: " $DRTY_CNTSCS echo -e "${GREEN}Value of /proc/sys/vm/dirty_writeback_centisecs:" $DRTY_WRBCK_CNTSCS echo -e "" printf "$SWPNSS_COL$SWPNSS_WARN" printf "$DRTY_RTIO_WARN" printf "$DRTY_BCKGRD_RTIO_WARN" printf "$DRTY_CNTSCS_WARN" printf "$DRTY_WRBCK_CNTSCS_WARN" } function shared_mem { # Shared Memory # Shared memory allows processes to communicate with each other by placing regions of memory into memory segments. In the case of Oracle, shared memory segments are used # by the System Global Area (SGA). The size of Oracle's SGA impacts the amount of shared memory pages and shared memory segments to be set within a system. By default, # Red Hat Enterprise Linux 7 provides a large amount of shared memory pages and segments. The appropriate allocation for a system depends on the size of the SGA within an # Oracle RAC database instance. # These values are based from the Deploying Oracle RAC 12c on RHEL 7 Tuning Guide: https://access.redhat.com/articles/1357883 (Section: 3.3.7) SHMALL=`cat "$CHK_LOC"/proc/sys/kernel/shmall` SHMMAX=`cat "$CHK_LOC"/proc/sys/kernel/shmmax` SHMMNI=`cat "$CHK_LOC"/proc/sys/kernel/shmmni` PAGESIZE=`getconf PAGE_SIZE` if [ "$SGA_MAX_SIZE" == "" ]; then SGA_MAX_SIZE_WARN="${YELLOW}There is no SGA_MAX_SIZE environment variable set - for safety we'll \nrecommend setting the SHMMAX value to 4398046511104 (4TB).\n\n" REC_SHMMAX=4398046511104 else SGA_MAX_SIZE_WARN="${RED}The SGA_MAX_SIZE is set to: $SGA_MAX_SIZE the shmmax value should be larger than this.\n\n" # Recommendation is to have SHMMAX greater than the value of SGA_MAX_SIZE - we'll calculate SHMMAX as SGA_MAX_SIZE + 100 PAGES SHMMAX_LEE=$((PAGESIZE * 100)) REC_SHMMAX=$((SHMMAX_LEE + SGA_MAX_SIZE)) fi if [ "$SHMMAX" > "$REC_SHMMAX" ]; then SHM_WARN="${GREEN}The maximum shared memory value is already greater than SGA_MAX_SIZE, and \ndoes not need increasing further.\n\n" SHMMAX_COL="${LIGHT_GREEN}" elif [ "$SHMMAX" > "$SGA_MAX_SIZE" ]; then SHM_WARN="${YELLOW}The maximum shared memory value is slightly greater than SGA_MAX_SIZE. This should be fine, although should be adjusted if SGA_MAX_SIZE changes.\n\n" SHMMAX_COL="${YELLOW}" else SHM_WARN="${RED}The current share memory value is $SHMMAX and the recommended value for shmmax is $REC_SHMMAX\n\n" SHMMAX_COL="${RED}" fi DEF_SHMALL=268435456 # To ensure an adequate amount of memory pages are allocated to a single Oracle SGA, it is recommended that the value of SHMALL be set to SHMMAX / PAGE_SIZE REC_SHMALL=$((REC_SHMMAX / PAGESIZE)) if [ "$SHMALL" > "$REC_SHMALL" ]; then SHMALL_WARN="${GREEN}The value of /proc/sys/kernel/shmall is currently set to $SHMALL and \ndoes not need adjusting.\n\n" SHMALL_COL="${LIGHT_GREEN}" else SHMALL_WARN="${RED}The recommended value for /proc/sys/kernel/shmall is $REC_SHMALL\n\n" SHMALL_COL="${RED}" fi DEF_SHMMNI=4096 # The default value of /proc/sys/kernel/shmmni is 4096 and based on the other settings this should not require further adjustment. if [ "$SHMMNI" = "$DEF_SHMMNI" ]; then SHMMNI_WARN="${GREEN}The value of /proc/sys/kernel/shmmni is set to $SHMMNI which is the default, \nand should not need any adjusting.\n\n" SHMMNI_COL="${LIGHT_GREEN}" else SHMMNI_WARN="${RED}The value of /proc/sys/kernel/shmmni is set to $SHMMNI which is not the default. You should check why this value has been changed and consider changing it back to $DEF_SHMMNI\n\n" SHMMNI_COL="${RED}" fi echo -e "${GREEN}#########################################################################" echo -e "# #" echo -e "# Shared Memory Settings #" echo -e "# #" echo -e "#########################################################################" echo -e "" echo -e "${GREEN}Value of /proc/sys/kernel/shmmax:" ${SHMMAX_COL}$SHMMAX echo -e "${GREEN}Value of /proc/sys/kernel/shmall:" ${SHMALL_COL}$SHMALL echo -e "${GREEN}Value of /proc/sys/kernel/shmmni:" ${SHMMNI_COL}$SHMMNI echo -e "" printf "$SGA_MAX_SIZE_WARN" printf "$SHM_WARN" printf "$SHMALL_WARN" printf "$SHMMNI_WARN" } function semaphore_check { # Semaphores # Semaphores are used for synchronisation of information between processes. There are four values defined in /proc/sys/kernel/sem # SEMMSL - maximum number of semaphores per sempahore set. Recommended: 250 # SEMMNS - total number of semaphores for the entire system (this is SEMMSL * SEMMNI). Recommended: 32000 # SEMOPM - total number of semaphore operations performed per semaphore system call. Recommended: 100 # SEMMNI - maximum number of semaphore sets for the entire system. Recommended: 128 # These values are based from the Deploying Oracle RAC 12c on RHEL 7 Tuning Guide: https://access.redhat.com/articles/1357883 (Section: 3.3.8) SEMMSL=`cat "$CHK_LOC"/proc/sys/kernel/sem | awk '{ print $1 }'` SEMMNS=`cat "$CHK_LOC"/proc/sys/kernel/sem | awk '{ print $2 }'` SEMOPM=`cat "$CHK_LOC"/proc/sys/kernel/sem | awk '{ print $3 }'` SEMMNI=`cat "$CHK_LOC"/proc/sys/kernel/sem | awk '{ print $4 }'` echo -e "${GREEN}#########################################################################" echo -e "# #" echo -e "# Semaphore Settings #" echo -e "# #" echo -e "#########################################################################" echo -e "" if [ "$SEMMSL" != "250" ]; then SEMMSL_WARN="\nThis server has a value of $SEMMSL as the maximum number of semaphores per \nsemaphore set. The recommended value is 250. You should consider setting \nthis value after determining why the current value is in place.\n" SEMMSL_COL="${RED}" else SEMMSL_WARN="" SEMMSL_COL="${LIGHT_GREEN}" fi if [ "$SEMMNS" != "32000" ]; then SEMMNS_WARN="\nThis server has a value of $SEMMNS as the total number of semaphores for \nthe entire system. The recommended value is 32000. You should consider \nsetting this value after determining why the current value is in place.\n" SEMMNS_COL="${RED}" else SEMMNS_WARN="" SEMMNS_COL="${LIGHT_GREEN}" fi if [ "$SEMOPM" != "100" ]; then SEMOPM_WARN="\nThis server has a value of $SEMOPM as the total number of semaphore operations \nperformed per semaphore system call. The recommended value is 100. You \nshould consider setting this value after determining why the current \nvalue is in place.\n" SEMOPM_COL="${RED}" else SEMOPM_WARN="" SEMOPM_COL="${LIGHT_GREEN}" fi if [ "$SEMMNI" != "128" ]; then SEMMNI_WARN="\nThis server has a value of $SEMMNI as the maximum number of semaphore sets for \nthe entire system. The recommended value is 128. You should consider \nsetting this value after determining why the current value is in place.\n" SEMMNI_COL="${RED}" else SEMMNI_WARN="" SEMMNI_COL="${LIGHT_GREEN}" fi echo -e "${GREEN}Value of /proc/sys/kernel/sem:" ${SEMMSL_COL}$SEMMSL ${SEMMNS_COL}$SEMMNS ${SEMOPM_COL}$SEMOPM ${SEMMNI_COL}$SEMMNI echo -e $SEMMSL_COL$SEMMSL_WARN $SEMMNS_COL$SEMMNS_WARN $SEMOPM_COL$SEMOPM_WARN $SEMMNI_COL$SEMMNI_WARN } function network_check { # Network Settings # Optimizing network settings - typically the read and write network buffers. Increasing from the default values. # This calculation is based from the Deploying Oracle RAC 12c on RHEL 7 Tuning Guide: https://access.redhat.com/articles/1357883 (Section: 3.3.10) RMEM_DEF=`cat "$CHK_LOC"/proc/sys/net/core/rmem_default` RMEM_MAX=`cat "$CHK_LOC"/proc/sys/net/core/rmem_max` WMEM_DEF=`cat "$CHK_LOC"/proc/sys/net/core/wmem_default` WMEM_MAX=`cat "$CHK_LOC"/proc/sys/net/core/wmem_max` echo -e "${GREEN}#########################################################################" echo -e "# #" echo -e "# Networking Settings #" echo -e "# #" echo -e "#########################################################################" echo -e "" if [ "$RMEM_DEF" -ge "262144" ]; then RMEM_DEF_WARN="The default receive buffer is set to $RMEM_DEF and is greater than or equal to the Oracle recommended value of 262144. No further tuning is necessary." RMEM_DEF_COL="${LIGHT_GREEN}" else RMEM_DEF_WARN="The default receive buffer value is currently: $RMEM_DEF Oracle recommend this value is set to 262144." RMEM_DEF_COL="${RED}" fi if [ "$RMEM_MAX" -ge "4194304" ]; then RMEM_MAX_WARN="The maximum receive buffer is set to $RMEM_MAX and is greater than or equal to the Oracle recommended value of 4194304. No further tuning is necessary." RMEM_MAX_COL="${LIGHT_GREEN}" else RMEM_MAX_WARN="The maximum receive buffer value is currently: $RMEM_MAX Oracle recommend this value is set to 4194304." RMEM_MAX_COL="${RED}" fi if [ "$WMEM_DEF" -ge "262144" ]; then WMEM_DEF_WARN="The default send buffer is set to $WMEM_DEF and is greater than or equal to the Oracle recommended value of 262144. No further tuning is necessary." WMEM_DEF_COL="${LIGHT_GREEN}" else WMEM_DEF_WARN="The default send buffer value is currently: $WMEM_DEF Oracle recommend this value is set to 262144." WMEM_DEF_COL="${RED}" fi if [ "$WMEM_MAX" -ge "1048576" ]; then WMEM_MAX_WARN="The maximum send buffer is set to $WMEM_MAX and is greater than or equal to the Oracle recommended value of 1048576. No further tuning is necessary." WMEM_MAX_COL="${LIGHT_GREEN}" else WMEM_MAX_WARN="The maximum send buffer value is currently: $WMEM_MAX Oracle recommend this value is set to 1048576." WMEM_MAX_COL="${RED}" fi echo -e "${GREEN}Value of /proc/sys/net/core/rmem_default: " ${RMEM_DEF_COL}$RMEM_DEF echo -e "${GREEN}Value of /proc/sys/net/core/rmem_max: " ${RMEM_MAX_COL}$RMEM_MAX echo -e "${GREEN}Value of /proc/sys/net/core/wmem_default: " ${WMEM_DEF_COL}$WMEM_DEF echo -e "${GREEN}Value of /proc/sys/net/core/wmem_max: " ${WMEM_MAX_COL}$WMEM_MAX # Reverse Path Filtering # RHEL 7 defaults to enabling reverse path filtering to mitigate against IP spoofing from DDoS attacks, this can have adverse # affect on the private interconnect of an Oracle RAC system. It is recommended to set the RP_FILTER to loose mode on the *private* interconnect interface(s). # This setting is based from the Deploying Oracle RAC 12c on RHEL 7 Tuning Guide: https://access.redhat.com/articles/1357883 (Section: 3.3.16) ### Need to determine which is the private interface - we'll call this $PRIV_INTERFACE for now - could be complicated if bonding/multiple NICs are used ... (perform via a loop?) for NIC in $PRIV_INTERFACE do if cat "$CHK_LOC"/proc/sys/net/ipv4/conf/$NIC/rp_filter > /dev/null 2>&1; then echo -e "${GREEN}User defined private interface $NIC: ${LIGHT_GREEN}Present" CURR_RP_FILTER=$(cat "$CHK_LOC"/proc/sys/net/ipv4/conf/$NIC/rp_filter 2>/dev/null) if [ "$CURR_RP_FILTER" = "2" ]; then echo "The reverse path filter value for" $NIC "is already set to 2 which is the recommended value for Oracle systems. No change is necessary." PRIV_INT_RP_COL="${LIGHT_GREEN}" elif [ "$CURR_RP_FILTER" = "1" ]; then PRIV_INT_RP_COL="${YELLOW}" else PRIV_INT_RP_COL="${RED}" echo "The reverse path filter value for" $NIC "is not set to 2 and should be altered. Changes should be made to /etc/sysctl.conf for Oracle installation and to /etc/sysctl.d/98-oracle.conf for future reference." fi echo -e "${GREEN}Value of /proc/sys/net/ipv4/conf/$NIC/rp_filter: " $PRIV_INT_RP_COL$CURR_RP_FILTER else printf "${GREEN}User defined private interface %-18s ${RED}Not Present\n" "$NIC:" fi done # Checking NOZEROCONF # Check for nozeroconf so that the 168.254.0.0/16 route is not added. # This setting is based from the Deploying Oracle RAC 12c on RHEL 7 Tuning Guide: https://access.redhat.com/articles/1357883 (Section: 3.3.11) if grep -ixq "NOZEROCONF=yes" "$CHK_LOC"/etc/sysconfig/network then echo -e "${GREEN}ZEROCONF disabled on this server: ${LIGHT_GREEN}Yes" else ZEROCONF_WARN="\n${YELLOW}You should disable ZEROCONF networking to prevent the route to the \nzeroconf network 169.254.0.0/16 being added to the routing table. You can \ndo this by adding NOZEROCONF=yes to the /etc/sysconfig/network file." echo -e "${GREEN}ZEROCONF disabled on this server: ${YELLOW}No" fi # Checking for (and disabling) the avahi services # Avahi is a service to facilitate service discovery on a local network. This can be useful for client PCs but can interfere with Oracle RAC multicast heartbeats. # It is enabled by default on RHEL, and should be disabled for Oracle servers. # This setting is based from the Deploying Oracle RAC 12c on RHEL 7 Tuning Guide: https://access.redhat.com/articles/1357883 (Section: 3.3.12) if service avahi-dnsconfd status > /dev/null 2>&1 ; then echo -e "${GREEN}Status of avahi-dnsconfd service: ${RED}running." else echo -e "${GREEN}Status of avahi-dnsconfd service: ${LIGHT_GREEN}Not running." fi if service avahi-daemon status > /dev/null 2>&1; then echo -e "${GREEN}Status of avahi-daemon service: ${RED}Running." else echo -e "${GREEN}Status of avahi-daemon service: ${LIGHT_GREEN}Not running." fi echo -e $ZEROCONF_WARN echo -e "" } function misc_kernel_check { # Increasing synchronous I/O requests # Oracle recommend increasing the maximum number of synchronous I/O requests the server is capable of handling. # This calculation is based from the Deploying Oracle RAC 12c on RHEL 7 Tuning Guide: https://access.redhat.com/articles/1357883 (Section: 3.3.13) echo -e "${GREEN}#########################################################################" echo -e "# #" echo -e "# Miscellaneous Kernel Settings #" echo -e "# #" echo -e "#########################################################################" echo -e "" MAX_IO=`cat "$CHK_LOC"/proc/sys/fs/aio-max-nr` if [ "$MAX_IO" -ge "1048576" ]; then MAX_IO_WARN="The maximum number of synchronous I/O requests has already been \nincreased to: $MAX_IO No further tuning is necessary.\n" MAX_IO_COL="${LIGHT_GREEN}" else MAX_IO_WARN="Oracle recommend the maximum synchronous I/O requests is increased to \n1048576 in /proc/sys/fs/aio-max-nr\n" MAX_IO_COL="${RED}" fi echo -e "${GREEN}Value of /proc/sys/fs/aio-max-nr: $MAX_IO_COL$MAX_IO" # File Handles # Oracle recommend that there are at least 512 file handles per SQL process on the server in addition to those required for the RHEL OS itself. # You must configure the SQL_PROCESSES parameter at the top of this script to accurately reflect the number of processes, otherwise the # value will be incorrectly calculated. A default value of 300 is used as that is the default number of processes Oracle configures. # This calculation is based from the Deploying Oracle RAC 12c on RHEL 7 Tuning Guide: https://access.redhat.com/articles/1357883 (Section: 3.3.14) CURR_FILE_MAX=`cat "$CHK_LOC"/proc/sys/fs/file-max` ADD_FILE_MAX=$(( SQL_PROCESSES * 512)) REC_FILE_MAX=$(( ADD_FILE_MAX + CURR_FILE_MAX )) if [ "$CURR_FILE_MAX" -lt "6815744" ]; then CURR_FILE_MAX_COL="${RED}" elif [ "$CURR_FILE_MAX" -eq "6815744" ]; then CURR_FILE_MAX_COL="${YELLOW}" else CURR_FILE_MAX_COL="${LIGHT_GREEN}" fi if [ "$REC_FILE_MAX" -lt "6815744" ]; then REC_FILE_MAX=6815744 MIN_FILE_MAX_WARN="\n${RED}Oracle recommend a minimum value of 6815744 for the maximum number of \nfile handles. The current calculated value for maximum file handles would \nbe less than than this value, so we recommend that /proc/sys/fs/file-max \nis set to 6815744\n" elif [ "$REC_FILE_MAX" -eq "6815744" ]; then MIN_FILE_MAX_WARN="\n${YELLOW}Oracle recommend a minimum value of 6815744 for the maximum number of \nfile handles. The current calculated value for maximum file handles would \nbe equal to this value.\n" else MIN_FILE_MAX_WARN="\n${GREEN}Oracle recommend a minimum value of 6815744 for the maximum number of \nfile handles. The current calculated value for maximum file handles is \ngreater than this recommended minimum.\n" fi if [ "$SQL_PROCESSES" = "0" ]; then MAX_FILE_HANDLES_WARN="\n${RED}You MUST configure the SQL_PROCESSES value at the top of this script. \nYou will see this warning if this value is left at 0.\n" MAX_FILE_HANDLES_COL="${RED}" else MAX_FILE_HANDLES_WARN="${YELLOW}Please note that repeatedly running and setting the maximum file handle \nrecommendation will result in the recommended maximum file handles \nconstantly increasing and therefore this value should not be repeatedly \nincreased.\n" MAX_FILE_HANDLES_COL="${LIGHT_GREEN}" fi echo -e "${GREEN}Current value for /proc/sys/fs/file-max: $CURR_FILE_MAX_COL$CURR_FILE_MAX" echo -e "${GREEN}Recommended value for /proc/sys/fs/file-max: $MAX_FILE_HANDLES_COL$REC_FILE_MAX" # Kernel panic on oops # Oracle installer checks for panic_on_oops being enabled in /etc/sysctl.conf even though it is enabled by default and that this file entry is not necessarily present. # This calculation is based from the Deploying Oracle RAC 12c on RHEL 7 Tuning Guide: https://access.redhat.com/articles/1357883 (Section: 3.3.15) PANIC_ON_OOPS=`cat "$CHK_LOC"/proc/sys/kernel/panic_on_oops` if [ "$PANIC_ON_OOPS" != "1" ]; then KRN_PNC_OOPS_WARN="\n${RED}The kernel is not configured to panic when an oops occurs - this is not recommended. Oracle installer also requires that this feature is enabled explicitly in the /etc/sysctl.conf file.\n" KRN_PNC_OOPS="${RED}No" else if grep -ixq "kernel.panic_on_oops=1" /etc/sysctl.conf then KRN_PNC_OOPS_WARN="\n${GREEN}The kernel is configured to panic when it encounters an OOPS event. This is the recommended (and default) setting. The Oracle installer also requires that this setting is explicitly enabled in the /etc/sysctl.conf file and this is present on this server.\n" KRN_PNC_OOPS="${LIGHT_GREEN}Yes" else KRN_PNC_OOPS_WARN="\n${YELLOW}The kernel is configured to panic when it encounters an OOPS event. This \nis the recommended (and default) setting. The Oracle installer requires \nthat this setting is explicitly enabled in the /etc/sysctl.conf file \nwhich is NOT currently the case on this server. This is not necessarily a \nproblem, but may prevent the Oracle installer from running.\n" KRN_PNC_OOPS="${YELLOW}Yes (below)" fi fi echo -e "${GREEN}Is the kernel configured to panic when an OOPS event occurs:" $KRN_PNC_OOPS echo -e "" echo -e "$MAX_IO_COL$MAX_IO_WARN" "$MIN_FILE_MAX_WARN" "\n$MAX_FILE_HANDLES_COL$MAX_FILE_HANDLES_WARN" "$KRN_PNC_OOPS_COL$KRN_PNC_OOPS_WARN" echo -e "" } function ntp_check { # Check that NTP (or chrony) is installed and running correctly # This is covered in the Deploying Oracle RAC 12c on RHEL 7 Tuning Guide: https://access.redhat.com/articles/1357883 (Section: 3.3.2) echo -e "${GREEN}#########################################################################" echo -e "# #" echo -e "# NTP Service #" echo -e "# #" echo -e "#########################################################################" echo -e "" if [ "$RHEL_RELEASE" == "7" ]; then if [ "$LOCALSYS" == "yes" ]; then if rpm -q chrony > /dev/null; then NTP_PKG=chrony else NTP_PKG=ntp fi else if grep -q "chrony-" "$CHK_LOC"/installed-rpms; then NTP_PKG=chrony else NTP_PKG=ntp fi fi fi echo -e "${GREEN}NTP package used is: ${LIGHT_GREEN}$NTP_PKG" if [ "$LOCALSYS" == "yes" ]; then if rpm -q $NTP_PKG > /dev/null; then echo -e "${GREEN}NTP package is installed: ${LIGHT_GREEN}Yes" NTP_INST=yes if service ntp status > /dev/null 2>&1; then echo -e "${GREEN}NTP daemon is running: ${LIGHT_GREEN}Yes" if ntpstat | grep unsynch > /dev/null 2>&1; then NTP_SYNC="${RED}No" elif ntpstat | grep "time correct" > /dev/null 2>&1; then NTP_SYNC="${LIGHT_GREEN}Yes" else NTP_SYNC="${YELLOW}Unknown" fi echo -e "${GREEN}Time is synchronised: $NTP_SYNC" else echo -e "${GREEN}NTP daemon is running: ${RED}No" fi else echo -e "${GREEN}NTP package is installed: ${RED}No" NTP_INST=no fi else if grep -q "$NTP_PKG-" "$CHK_LOC"/installed-rpms; then echo -e "${GREEN}NTP package is installed: ${LIGHT_GREEN}Yes" NTP_INST=yes if grep -q "ntpd" "$CHK_LOC"/ps; then echo -e "${GREEN}NTP daemon is running: ${LIGHT_GREEN}Yes" if grep -q "unsynch" "$CHK_LOC"/sos_commands/ntp/ntpstat; then NTP_SYNC="${RED}No" elif grep -q "time correct" "$CHK_LOC"/sos_commands/ntp/ntpstat; then NTP_SYNC="${LIGHT_GREEN}Yes" else NTP_SYNC="${YELLOW}Unknown" fi else echo -e "${GREEN}NTP daemon is running: ${RED}No" fi echo -e "${GREEN}Time is synchronised: $NTP_SYNC" else echo -e "${GREEN}NTP package is installed: ${RED}No" NTP_INST=no fi fi } function shell_limits { ## Shell Limits # Oracle recommend limiting the oracle and grid users from being able to exhaust system resources and potentially hang a server using ulimits on open file descriptors, number of processes, and size of the stack segment. # These values are based from the Deploying Oracle RAC 12c on RHEL 7 Tuning Guide: https://access.redhat.com/articles/1357883 (Section: 3.3.18) echo -e "" echo "NOTE TO SELF: You need to filter out the # comments - it's possible people may have oracle users commented out ... ugh!" echo -e "${GREEN}#########################################################################" echo -e "# #" echo -e "# Shell Limits Settings #" echo -e "# #" echo -e "#########################################################################" echo -e "" if grep -iq "^\b$ORACLE_USER\b" "$CHK_LOC"/etc/security/limits.conf; then echo -e "${YELLOW}There are shell limits defined for the oracle user in the \n/etc/security/limits.conf file. This is no longer the recommended \npractice - you should check the Red Hat article: What order are the limit \nfiles in the limits.d directory read in? for details.\n" ORACLE_LIMITS="yes" else ORACLE_LIMITS="no" fi if [ -f "$ORACLE_LIMITS_FILE" ]; then if grep -iq ^\b$ORACLE_USER\b "$ORACLE_LIMITS_FILE" then SHELL_LIMITS_FILE_WARN="${LIGHT_GREEN}The oracle user is present in the $ORACLE_LIMITS_FILE file. \nThis is correct. Checking the recommended values ...\n" ORACLE_LIMITS_D="1" else SHELL_LIMITS_FILE_WARN="${RED}The oracle user is not present in the $ORACLE_LIMITS_FILE \nfile. This is not correct and should be rectified.\n" ORACLE_LIMITS_D="0" fi else SHELL_LIMITS_FILE_WARN="${YELLOW}There is no Oracle specific shell limits file present or you have an \nerror in the configuration pointing to a shell limits file that doesn't \nexist. This should be corrected.\n" ORACLE_LIMITS_D="0" fi echo -e $SHELL_LIMITS_FILE_WARN if [ "$ORACLE_LIMITS_D" == "1" ]; then ORACLE_SOFT_NPROC=`grep ^\b$ORACLE_USER\b "$ORACLE_LIMITS_FILE" | awk '/soft/ && /nproc/ { print $4 }'` #echo "Here I am! $ORACLE_SOFT_NPROC" #echo "Here I am! $ORACLE_LIMITS_FILE" ORACLE_HARD_NPROC=`grep ^\b$ORACLE_USER\b "$ORACLE_LIMITS_FILE" | awk '/hard/ && /nproc/ { print $4 }'` ORACLE_SOFT_NOFILE=`grep ^\b$ORACLE_USER\b "$ORACLE_LIMITS_FILE" | awk '/soft/ && /nofile/ { print $4 }'` ORACLE_HARD_NOFILE=`grep ^\b$ORACLE_USER\b "$ORACLE_LIMITS_FILE" | awk '/hard/ && /nofile/ { print $4 }'` ORACLE_SOFT_STACK=`grep ^\b$ORACLE_USER\b "$ORACLE_LIMITS_FILE" | awk '/soft/ && /stack/ { print $4 }'` ORACLE_HARD_STACK=`grep ^\b$ORACLE_USER\b $ORACLE_LIMITS_FILE | awk '/hard/ && /stack/ { print $4 }'` if [ "$ORACLE_LIMITS" == "yes" ]; then SHELL_LIMITS_WARN="${YELLOW}You have shell limits for the oracle user defined in both \n/etc/security/limits.conf and $ORACLE_LIMITS_FILE - \nthis is not good practice. The settings from \n$ORACLE_LIMITS_FILE should take precedence over \nthose from /etc/security/limits.conf however this can be confusing and \nlead to unexpected results.\n" SHELL_LIMITS_PRES="${YELLOW}Yes" else SHELL_LIMITS_WARN="${LIGHT_GREEN}You correctly have shell limits for the oracle user defined only in $ORACLE_LIMITS_FILE as per recommended practices. Please check the shell limits values." SHELL_LIMITS_PRES="${LIGHT_GREEN}Yes" fi else if [ "$ORACLE_LIMITS" == "yes" ]; then SHELL_LIMITS_WARN="${YELLOW}You have shell limits for the oracle user defined in \n/etc/security/limits.conf only - this is not the recommended practice. \nThe shell limits for the oracle and grid users should be defined in a \nseparate /etc/security/limits.d/99-oracle.conf file.\n" SHELL_LIMITS_PRES="${YELLOW}Yes" ORACLE_SOFT_NPROC=`cat "$CHK_LOC"/etc/security/limits.conf | awk '/oracle/ && /soft/ && /nproc/ { print $4 }'` ORACLE_HARD_NPROC=`cat "$CHK_LOC"/etc/security/limits.conf | awk '/oracle/ && /hard/ && /nproc/ { print $4 }'` ORACLE_SOFT_NOFILE=`cat "$CHK_LOC"/etc/security/limits.conf | awk '/oracle/ && /soft/ && /nofile/ { print $4 }'` ORACLE_HARD_NOFILE=`cat "$CHK_LOC"/etc/security/limits.conf | awk '/oracle/ && /hard/ && /nofile/ { print $4 }'` ORACLE_SOFT_STACK=`cat "$CHK_LOC"/etc/security/limits.conf | awk '/oracle/ && /soft/ && /stack/ { print $4 }'` ORACLE_HARD_STACK=`cat "$CHK_LOC"/etc/security/limits.conf | awk '/oracle/ && /hard/ && /stack/ { print $4 }'` else SHELL_LIMITS_WARN="${RED}No shell limits for the oracle user have been found. This should be verified manually" SHELL_LIMITS_PRES="${RED}No" ORACLE_SOFT_NPROC=0 ORACLE_HARD_NPROC=0 ORACLE_SOFT_NOFILE=0 ORACLE_HARD_NOFILE=0 ORACLE_SOFT_STACK=0 ORACLE_HARD_STACK=0 fi fi echo -e $SHELL_LIMITS_WARN echo -e "${GREEN}Shell limts present for the oracle user:" $SHELL_LIMITS_PRES if grep -iq "grid" "$CHK_LOC"/etc/security/limits.conf then # echo "There are shell limits defined for the grid user in the /etc/security/limits.conf file. This is no longer the recommended practice - you should check the Red Hat article: What order are the limit files in the limits.d directory read in? for details" GRID_LIMITS=1 else GRID_LIMITS=0 fi if [ -f "$GRID_LIMITS_FILE" ]; then if grep -iq "grid" "$GRID_LIMITS_FILE" then #echo "The grid user is present in the" $GRID_LIMITS_FILE "file. This is correct. Checking the recommended values ..." GRID_LIMITS_D=1 else #echo "The grid user is not present in the" $GRID_LIMITS_FILE "file. This is not correct and should be rectified." GRID_LIMITS_D=0 fi else GRID_SHELL_LIMITS_FILE_WARN="${YELLOW}There is no Oracle Grid specific shell limits file present or you have an error in the configuration pointing to a shell limits file that doesn't exist. This should be corrected." GRID_LIMITS_D=0 fi if [ "$GRID_LIMITS_D" = "1" ]; then GRID_SOFT_NPROC=`cat "$GRID_LIMITS_FILE" | awk '/grid/ && /soft/ && /nproc/ { print $4 }'` GRID_HARD_NPROC=`cat "$GRID_LIMITS_FILE" | awk '/gird/ && /hard/ && /nproc/ { print $4 }'` GRID_SOFT_NOFILE=`cat "$GRID_LIMITS_FILE" | awk '/gird/ && /soft/ && /nofile/ { print $4 }'` GRID_HARD_NOFILE=`cat "$GRID_LIMITS_FILE" | awk '/gird/ && /hard/ && /nofile/ { print $4 }'` GRID_SOFT_STACK=`cat "$GRID_LIMITS_FILE" | awk '/grid/ && /soft/ && /stack/ { print $4 }'` GRID_HARD_STACK=`cat "$GRID_LIMITS_FILE" | awk '/grid/ && /hard/ && /stack/ { print $4 }'` if [ "$GRID_LIMITS" = "1" ]; then GRIDSHELL_LIMITS_WARN="${YELLOW}You have shell limits for the grid user defined in both /etc/security/limits.conf and $GRID_LIMITS_FILE - this is not good practice. The settings from $GRID_LIMITS_FILE should take precedence over those from /etc/security/limits.conf however this can be confusing and lead to unexpected results." GRID_SHELL_LIMITS_PRES="${YELLOW}Yes" else GRID_SHELL_LIMITS_WARN="${GREEN}You correctly have shell limits for the grid user defined only in $GRID_LIMITS_FILE as per recommended practices. Please check the shell limits values." GRID_SHELL_LIMITS_PRES="${LIGHT_GREEN}Yes" fi else if [ "$GRID_LIMITS" = "1" ]; then GRID_SHELL_LIMITS_WARN="${YELLOW}You have shell limits for the grid user defined in /etc/security/limits.conf only - this is not the recommended practice. The shell limits for the oracle and grid users should be defined in a separate /etc/security/limits.d/99-oracle.conf file." GRID_SHELL_LIMITS_PRES="${YELLOW}Yes" GRID_SOFT_NPROC=`cat "$CHK_LOC"/etc/security/limits.conf | awk '/grid/ && /soft/ && /nproc/ { print $4 }'` GRID_HARD_NPROC=`cat "$CHK_LOC"/etc/security/limits.conf | awk '/grid/ && /hard/ && /nproc/ { print $4 }'` GRID_SOFT_NOFILE=`cat "$CHK_LOC"/etc/security/limits.conf | awk '/grid/ && /soft/ && /nofile/ { print $4 }'` GRID_HARD_NOFILE=`cat "$CHK_LOC"/etc/security/limits.conf | awk '/grid/ && /hard/ && /nofile/ { print $4 }'` GRID_SOFT_STACK=`cat "$CHK_LOC"/etc/security/limits.conf | awk '/grid/ && /soft/ && /stack/ { print $4 }'` GRID_HARD_STACK=`cat "$CHK_LOC"/etc/security/limits.conf | awk '/grid/ && /hard/ && /stack/ { print $4 }'` else GRID_SHELL_LIMITS_WARN="${RED}No shell limits for the grid user have been found. This should be verified manually" GRID_SHELL_LIMITS_PRES="${RED}No" GRID_SOFT_NPROC=0 GRID_HARD_NPROC=0 GRID_SOFT_NOFILE=0 GRID_HARD_NOFILE=0 GRID_SOFT_STACK=0 GRID_HARD_STACK=0 fi fi echo -e "${GREEN}Shell limts present for the grid user:" $GRID_SHELL_LIMITS_PRES echo -e "" if [ "$ORACLE_SOFT_NPROC" != "0" ]; then if [ "$ORACLE_SOFT_NPROC" -ge "16384" ]; then OSN_COL="${LIGHT_GREEN}$ORACLE_SOFT_NPROC" else OSN_COL="${YELLOW}$ORACLE_SOFT_NPROC" fi else OSN_COL="${RED}$ORACLE_SOFT_NPROC" fi echo -e "${GREEN}Soft limit for the number of processes for the oracle user: " $OSN_COL if [ "$ORACLE_HARD_NPROC" != "0" ]; then if [ "$ORACLE_HARD_NPROC" -ge "16384" ]; then OHN_COL="${LIGHT_GREEN}$ORACLE_HARD_NPROC" else OHN_COL="${YELLOW}$ORACLE_HARD_NPROC" fi else OHN_COL="${RED}$ORACLE_HARD_NPROC" fi echo -e "${GREEN}Hard limit for the number of processes for the oracle user: " $OHN_COL if [ "$ORACLE_SOFT_NOFILE" != "0" ]; then if [ "$ORACLE_SOFT_NOFILE" -ge "1024" ]; then OSNF_COL="${LIGHT_GREEN}$ORACLE_SOFT_NOFILE" else OSNF_COL="${YELLOW}$ORACLE_SOFT_NOFILE" fi else OSNF_COL="${RED}$ORACLE_SOFT_NOFILE" fi echo -e "${GREEN}Soft limit for the number of open files for the oracle user:" $OSNF_COL if [ "$ORACLE_HARD_NOFILE" != "0" ]; then if [ "$ORACLE_HARD_NOFILE" -ge "65536" ]; then OHNF_COL="${LIGHT_GREEN}$ORACLE_HARD_NOFILE" else OHNF_COL="${YELLOW}$ORACLE_HARD_NOFILE" fi else OHNF_COL="${RED}$ORACLE_HARD_NOFILE" fi echo -e "${GREEN}Hard limit for the number of open files for the oracle user:" $OHNF_COL if [ "$ORACLE_SOFT_STACK" != "0" ]; then if [ "$ORACLE_SOFT_STACK" -ge "10240" ]; then OSS_COL="${LIGHT_GREEN}$ORACLE_SOFT_STACK" else OSS_COL="${YELLOW}$ORACLE_SOFT_STACK" fi else OSS_COL="${RED}$ORACLE_SOFT_STACK" fi echo -e "${GREEN}Soft limit for the stack segment size for the oracle user: " $OSS_COL if [ "$ORACLE_HARD_STACK" != "" ]; then if [ "$ORACLE_HARD_STACK" -ge "32768" ]; then OHS_COL="${LIGHT_GREEN}$ORACLE_HARD_STACK" else OHS_COL="${YELLOW}$ORACLE_HARD_STACK" fi else OHS_COL="${RED}Not Present" fi echo -e "${GREEN}Hard limit for the stack segment size for the oracle user: " $OHS_COL echo -e "" if [ "$GRID_SOFT_NPROC" != "0" ]; then if [ "$GRID_SOFT_NPROC" -ge "16384" ]; then GSN_COL="${LIGHT_GREEN}$GRID_SOFT_NPROC" else GSN_COL="${YELLOW}$GRID_SOFT_NPROC" fi else GSN_COL="${RED}$GRID_SOFT_NPROC" fi echo -e "${GREEN}Soft limit for the number of processes for the grid user: " $GSN_COL if [ "$GRID_HARD_NPROC" != "0" ]; then if [ "$GRID_HARD_NPROC" -ge "16384" ]; then GHN_COL="${LIGHT_GREEN}$GRID_HARD_NPROC" else GHN_COL="${YELLOW}$GRID_HARD_NPROC" fi else GHN_COL="${RED}$GRID_HARD_NPROC" fi echo -e "${GREEN}Hard limit for the number of processes for the grid user: " $GHN_COL if [ "$GRID_SOFT_NOFILE" != "0" ]; then if [ "$GRID_SOFT_NOFILE" -ge "1024" ]; then GSNF_COL="${LIGHT_GREEN}$GRID_SOFT_NOFILE" else GSNF_COL="${YELLOW}$GRID_SOFT_NOFILE" fi else GSNF_COL="${RED}$GRID_SOFT_NOFILE" fi echo -e "${GREEN}Soft limit for the number of open files for the grid user: " $GSNF_COL if [ "$GRID_HARD_NOFILE" != "0" ]; then if [ "$GRID_HARD_NOFILE" -ge "65536" ]; then GHNF_COL="${LIGHT_GREEN}$GRID_HARD_NOFILE" else GHNF_COL="${YELLOW}$GRID_HARD_NOFILE" fi else GHNF_COL="${RED}$GRID_HARD_NOFILE" fi echo -e "${GREEN}Hard limit for the number of open files for the grid user: " $GSNF_COL if [ "$GRID_SOFT_STACK" != "0" ]; then if [ "$GRID_SOFT_STACK" -ge "10240" ]; then GSS_COL="${LIGHT_GREEN}$GRID_SOFT_STACK" else GSS_COL="${YELLOW}$GRID_SOFT_STACK" fi else GSS_COL="${RED}$GRID_SOFT_STACK" fi echo -e "${GREEN}Soft limit for the stack segment size for the grid user: " $GSS_COL if [ "$GRID_HARD_STACK" != "0" ]; then if [ "$GRID_HARD_STACK" -ge "32768" ]; then GHS_COL="${LIGHT_GREEN}$GRID_HARD_STACK" else GHS_COL="${YELLOW}$GRID_HARD_STACK" fi else GHS_COL="${RED}$GRID_HARD_STACK" fi echo -e "${GREEN}Hard limit for the stack segment size for the grid user: " $GHS_COL echo -e "${GREEN}" } function misc_check { ## Tuned Section # The Red Hat tuning guide for Oracle 12 databases on RHEL 7 suggest creating a tuning profile based upon the throughput profile. We'll check if these parameters # are in place. echo -e "${GREEN}#########################################################################" echo -e "# #" echo -e "# Miscellaneous Tuning Settings #" echo -e "# #" echo -e "#########################################################################" echo -e "" if [ "$LOCALSYS" == "yes" ]; then if rpm -q tuned > /dev/null then TUNED_INST="${LIGHT_GREEN}Yes" else TUNED_INST="${RED}No" fi else if grep tuned "$CHK_LOC"/installed-rpms > /dev/null then TUNED_INST="${LIGHT_GREEN}Yes" else TUNED_INST="${RED}No" fi fi echo -e "${GREEN}Tuned package is installed: $TUNED_INST" if [ "$TUNED_INST" == "${LIGHT_GREEN}Yes" ]; then TUNED_PROFILE=`cat "$CHK_LOC"/etc/tuned/active_profile` echo -e "${GREEN}Active profile is: ${LIGHT_GREEN}$TUNED_PROFILE" fi if grep -q "\[never\]" "$CHK_LOC"/sys/kernel/mm/transparent_hugepage/enabled then echo -e "${GREEN}Status of Transparent hugepages in /sys filesystem: ${LIGHT_GREEN}Disabled" THP_STATUS_MSG="{LIGHT_GREEN}Transparent HugePages is currently disabled. This is correct." else echo -e "${GREEN}Status of Transparent hugepages in /sys filesystem: ${RED}Enabled" THP_STATUS_MSG="${RED}According to the Oracle knowledgebase document 'ALERT: Disable \nTransparent HugePages on SLES11,RHEL6,OEL6 and UEK2 Kernels \n(DOC ID: 1557478.1)' transparent hugepages (THP) should be disabled." fi # Disable Transparent Hugepages via grub boot option GRUB_LINUX=`cat "$CHK_LOC"/etc/default/grub | grep GRUB_CMDLINE_LINUX` if echo $GRUB_LINUX | grep -q "transparent_hugepage=never" ; then echo -e "${GREEN}Status of Transparent hugepages in the grub2 default settings: ${$LIGHT_GREEN}Disabled" # echo 'The GRUB_CMDLINE_LINUX section of /etc/default/grub should look like this:' `echo $GRUB_LINUX | sed 's/.$//'` 'hugepages='$CALC_NR_HUGEPAGES'"' THP_GRUB_DISABLED=1 THP_GRUB_STATUS_MSG="${LIGHT_GREEN}Transparent hugepages have been disabled in the grub configuration. This is correct." else echo -e "${GREEN}Status of Transparent hugepages in the grub2 default settings: ${RED}Enabled" THP_GRUB_DISABLED=0 THP_GRUB_STATUS_MSG="${RED}The /etc/default/grub file should be altered to contain the \nparameter 'transparent_hugepage=never' in the GRUB_LINUX section and the \ngrub configuration regenerated." fi echo "" echo -e $THP_STATUS_MSG echo "" echo -e $THP_GRUB_STATUS_MSG echo -e "${NC}" } case "$1" in check) request_settings curr_env confirm_settings swap_calc selinux_check vm_check shared_mem semaphore_check network_check misc_kernel_check ntp_check shell_limits misc_check ;; info) echo -e "This is where the information will end up" echo -e "This Oracle Database check script will check either the current server or an sosreport for settings optimised for Oracle Database workloads. The script will run on non-Oracle servers and return results, however you should be aware the settings being checked are those recommended for running Oracle Database. The optimised settings are taken from the Red Hat Reference Architecture: Deploying Oracle RAC Database 12c on Red Hat Enterprise Linux 7 Best Practices https://access.redhat.com/articles/1357883 " ;; *) echo -e "Usage: $0 runs with one of: info, check, or help" exit 2 esac ########################################################################################## ###### THESE COMMANDS/SETTINGS ARE PROABBLY TO BE REMOVED - FIRST DRAFT OF SCRIPT ######## ########################################################################################## ## Print out the hostname information to the user ## A unique hostname is required - we'll print out the hostname information, the SysAdmin should ensure the hostname is unique on the network #echo "Hostname and system information - please ensure the hostname is unique on your network!" #hostnamectl status ## Network Configuration Check ## This is currently left blank intentionally ... checking the network may (or may not) be something that can be added to the script. ## Given the variability of customer networks, this might not be something that is easily checked with a 'standard' utility. ## Oracle RAC specific # For Oracle RAC workloads it might be worth adding a check if there is a SCAN (Single Client Access Name) record (ask the user to provide the DNS name) and if it is reachable # Possibly also check the DNS entries for virtual IP (VIP) addresses of each node. For RAC it is recommended that clients connect via a SCAN record. #echo -e "Maybe add checks for a SCAN DNS record for Oracle RAC workloads only?" #echo -e "It won't be possible to check SCAN DNS records or VIP records from an sosreport. \nDubious value to having these checks - it would require the input of the correct \nvalues at the start." # Ephemeral Network Ports # Section here to check for available local ports - not urgent. #echo -e "We might want to add an ephemeral network port check here." # User and Group Accounts # Oracle recommend various groups are created for DB admin functions as well as grid, oinstall, and oracle user accounts. We should probably check for the existence of these here ... TO BE ADDED #echo "User and Group check here - TO BE ADDED" ## Device Mapper Section # This could be tricky - it would require a degree of user input/pre-configuration for information such as ASM details. It might not make # sense to include this as part of a checking script. Might be added later ... #echo "Device Mapper checks - TO BE ADDED LATER?" #############################################################