#!/bin/bash ## Usage: db_change_oh.sh , where: ## -d|--database ## -o|--oraclehome # Global variables #----------------- typeset ABS_PATH_THIS_SHELL typeset ABS_PATH_EXECUTION_LOG_FILE typeset EXEC_ID typeset ROOTDIR="/dbfs_tools/TOOLS/admin/sh" typeset UPLEVEL_SCRIPT_PATH typeset NEW_ORACLE_HOME typeset THIS_HOST typeset DBNODE1 typeset DBNODE2 typeset DBINST1 typeset DBINST2 typeset EXECUTION_TYPE typeset EXECUTION_HOST typeset EXECUTION_INSTANCE typeset EXECUTION_HOST_BIS typeset EXECUTION_INSTANCE_BIS typeset THIS_SHELL typeset DB_UNIQUE_NAME typeset OHOME typeset OVERSION typeset GHOME typeset SQLPLUS typeset DB_SRVCTL typeset GRID_SRVCTL typeset -i LAST_RETURN_CODE typeset AUX_STRING typeset DATABASE_ROLE # Procedures #----------- usage() { [ "$*" ] && echo "$0: $*" sed -n '/^##/,/^$/s/^## \{0,1\}//p' "$0" exit 2 } 2>/dev/null get_database_info (){ # Get the last 3 letters of database unique name parameter AUX_STRING=$(echo ${DB_UNIQUE_NAME} | rev | cut -c 1-3 | rev) if [[ "${AUX_STRING}" != "EXA" ]] ; then echo " ERROR: Invalid database name: ${DB_UNIQUE_NAME} [FAILED]" | tee -a ${UPLEVEL_SCRIPT_PATH}/logs/${THIS_SHELl}_${EXEC_ID}.log exit 1 fi # Get GID_HOME GHOME=$(cat /etc/oratab | grep -v '^#' | grep "+ASM" | cut -d":" -f2 | sed 's/ //g') GRID_SRVCTL=${GHOME}/bin/srvctl ${GRID_SRVCTL} config database -v | grep ${DB_UNIQUE_NAME} | awk '{ print $1 }'> ${UPLEVEL_SCRIPT_PATH}/workdir/${EXEC_ID}.tmp typeset -i DBCOUNT=$(cat ${UPLEVEL_SCRIPT_PATH}/workdir/${EXEC_ID}.tmp | wc -l) if [[ ( ${DBCOUNT} > 1 ) || ( ${DBCOUNT} = 0 ) ]] ; then echo " ERROR: ${DBCOUNT} databases founded for the database name: ${DB_UNIQUE_NAME} [FAILED]" | tee -a ${UPLEVEL_SCRIPT_PATH}/logs/${THIS_SHELl}_${EXEC_ID}.log exit 1 else OHOME=$(${GRID_SRVCTL} config database -v | grep ${DB_UNIQUE_NAME} | awk '{ print $2 }') export ORACLE_HOME=${OHOME} OVERSION=$(${GRID_SRVCTL} config database -v | grep ${DB_UNIQUE_NAME} | awk '{ print $3 }') SQLPLUS="${OHOME}/bin/sqlplus -s / as sysdba" DB_SRVCTL=${OHOME}/bin/srvctl echo "DB_UNIQUE_NAME=${DB_UNIQUE_NAME}, ORACLE_HOME=${OHOME}, VERSION=${OVERSION}" fi # Identify database instances THIS_HOST=$(hostname -s) THIS_HOST_NUMBER=$(echo ${THIS_HOST} | rev | cut -c 1-1 | rev) THIS_HOST_BASE=${THIS_HOST:0:10} DB_UNIQUE_NAME_BASE=${DB_UNIQUE_NAME:0:${#DB_UNIQUE_NAME}-3} STR1=$(${DB_SRVCTL} config database -db ${DB_UNIQUE_NAME} | grep "Configured nodes") STR2=${STR1#"Configured nodes: "} DBNODE1=$(echo ${STR2} | awk -F"," '{ print $1}') DBNODE2=$(echo ${STR2} | awk -F"," '{ print $2}') STR1=$(${DB_SRVCTL} config database -db ${DB_UNIQUE_NAME} | grep "Database instances") STR2=${STR1#"Database instances: "} DBINST1=$(echo ${STR2} | awk -F"," '{ print $1}') DBINST2=$(echo ${STR2} | awk -F"," '{ print $2}') echo "Database instances: ${DBINST1}@${DBNODE1}, ${DBINST2}@${DBNODE2}" } continue_if_ok () { RETURN_CODE=$1 if [[ ( ${RETURN_CODE} != 0 ) ]] ; then echo "ERROR, please check the logfile: ${ABS_PATH_EXECUTION_LOG_FILE}" exit 1 fi } restart_database (){ ${DB_SRVCTL} stop database -db ${DB_UNIQUE_NAME} > ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 continue_if_ok $? ${DB_SRVCTL} start database -db ${DB_UNIQUE_NAME} > ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 continue_if_ok $? } copy_init_and_passwordfile (){ cp -p ${OHOME}/dbs/init${EXECUTION_INSTANCE}.ora ${NEW_ORACLE_HOME}/dbs/init${EXECUTION_INSTANCE}.ora >> ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 cp -p ${OHOME}/dbs/orapw${EXECUTION_INSTANCE} ${NEW_ORACLE_HOME}/dbs/orapw${EXECUTION_INSTANCE} >> ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 scp -p ${OHOME}/dbs/init${EXECUTION_INSTANCE}.ora ${EXECUTION_HOST_BIS}:${NEW_ORACLE_HOME}/dbs/init${EXECUTION_INSTANCE_BIS}.ora >> ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 scp -p ${OHOME}/dbs/orapw${EXECUTION_INSTANCE} ${EXECUTION_HOST_BIS}:${NEW_ORACLE_HOME}/dbs/orapw${EXECUTION_INSTANCE_BIS} >> ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 } disable_cluster (){ export ORACLE_HOME=${OHOME} export ORACLE_SID=${EXECUTION_INSTANCE} ${ORACLE_HOME}/bin/sqlplus / as sysdba<> ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 whenever oserror exit failure whenever sqlerror exit sql.sqlcode alter system set cluster_database=false scope=spfile sid='*'; EOF! continue_if_ok $? } stop_db (){ ${DB_SRVCTL} stop database -db ${DB_UNIQUE_NAME} >> ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 continue_if_ok $? } update_oratab (){ cp /etc/oratab ${UPLEVEL_SCRIPT_PATH}/logs/oratab_${DB_UNIQUE_NAME}_${EXECUTION_HOST}_${EXEC_ID}.bak scp ${EXECUTION_HOST_BIS}:/etc/oratab ${UPLEVEL_SCRIPT_PATH}/logs/oratab_${DB_UNIQUE_NAME}_${EXECUTION_HOST_BIS}_${EXEC_ID}.bak >> ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 sed '/'${DB_UNIQUE_NAME}':/d' /etc/oratab > ${UPLEVEL_SCRIPT_PATH}/workdir/oratab_${DB_UNIQUE_NAME}_{EXEC_ID}.tmp echo "${DB_UNIQUE_NAME}:${NEW_ORACLE_HOME}:N" >> ${UPLEVEL_SCRIPT_PATH}/workdir/oratab_${DB_UNIQUE_NAME}_{EXEC_ID}.tmp cp ${UPLEVEL_SCRIPT_PATH}/workdir/oratab_${DB_UNIQUE_NAME}_{EXEC_ID}.tmp /etc/oratab sed '/'${DB_UNIQUE_NAME}':/d' ${UPLEVEL_SCRIPT_PATH}/logs/oratab_${DB_UNIQUE_NAME}_${EXECUTION_HOST_BIS}_${EXEC_ID}.bak > ${UPLEVEL_SCRIPT_PATH}/workdir/oratab_${DB_UNIQUE_NAME}_{EXEC_ID}.tmp echo "${DB_UNIQUE_NAME}:${NEW_ORACLE_HOME}:N" >> ${UPLEVEL_SCRIPT_PATH}/workdir/oratab_${DB_UNIQUE_NAME}_{EXEC_ID}.tmp scp ${UPLEVEL_SCRIPT_PATH}/workdir/oratab_${DB_UNIQUE_NAME}_{EXEC_ID}.tmp ${EXECUTION_HOST_BIS}:/etc/oratab >> ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 } execute_datapatch (){ # Switch to new ORACLE_HOME export ORACLE_HOME=${NEW_ORACLE_HOME} echo " Start instance ${EXECUTION_INSTANCE}@${EXECUTION_HOST} in UPGRADE mode" ${ORACLE_HOME}/bin/sqlplus / as sysdba<> ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 whenever oserror exit failure whenever sqlerror exit sql.sqlcode startup upgrade; EOF! continue_if_ok $? # Asked by Michael :) ${ORACLE_HOME}/bin/sqlplus / as sysdba<> ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 whenever oserror exit failure whenever sqlerror exit sql.sqlcode begin FOR dummy IN (SELECT index_name from dba_indexes where owner='SYS' and index_name='[FK_RES]') LOOP execute immediate 'drop index SYS."[FK_RES]"'; END LOOP; end; / EOF! continue_if_ok $? echo " Executing DATAPATCH" ${ORACLE_HOME}/OPatch/datapatch >> ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 continue_if_ok $? } enable_cluster (){ echo " Set cluster_database=true and shutdown ${DB_UNIQUE_NAME} database" ${ORACLE_HOME}/bin/sqlplus / as sysdba<> ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 whenever oserror exit failure whenever sqlerror exit sql.sqlcode alter system set cluster_database=true scope=spfile sid='*'; shutdown immediate; EOF! continue_if_ok $? } update_CRS (){ ${DB_SRVCTL} modify database -db ${DB_UNIQUE_NAME} -oraclehome ${NEW_ORACLE_HOME} >> ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 continue_if_ok $? } start_db (){ ${DB_SRVCTL} start database -db ${DB_UNIQUE_NAME} >> ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 continue_if_ok $? ${DB_SRVCTL} status database -db ${DB_UNIQUE_NAME} -v >> ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log 2>&1 } get_database_role (){ export ORACLE_HOME=${OHOME} export ORACLE_SID=${EXECUTION_INSTANCE} DATABASE_ROLE=$(${ORACLE_HOME}/bin/sqlplus -s / as sysdba< oratab. echo " Update ${DB_UNIQUE_NAME} in oratab with the new ORACLE_HOME" update_oratab if [ "${DATABASE_ROLE}" == "PRIMARY" ]; then execute_datapatch enable_cluster fi echo " Update ${DB_UNIQUE_NAME} in CRS with new ORACLE_HOME" update_CRS if [ "${DATABASE_ROLE}" == "PRIMARY" ]; then echo " Start ${DB_UNIQUE_NAME} database" start_db else echo " Restart ${DB_UNIQUE_NAME} database" stop_db start_db fi } # -------- # M a i n #--------- THIS_SHELL=$(basename "$0") EXEC_ID="$(date +"%Y%m%d%H%M%S")$$" # Parse the input parameters while [ "$1" != "" ]; do case $1 in -d | --database ) shift # Uppercase the database name AUX_STRING=$1 DB_UNIQUE_NAME=${AUX_STRING^^} ;; -o | --oraclehome ) shift NEW_ORACLE_HOME=$1 ;; -h | --help ) usage exit ;; * ) usage exit 1 esac shift done # Check for parameter consistance #-------------------------------- if [ -z "${DB_UNIQUE_NAME}" ]; then usage; exit 1; fi if [ -z "${NEW_ORACLE_HOME}" ]; then usage; exit 1; fi ABS_PATH_THIS_SHELL=$(readlink -f ${THIS_SHELL}) UPLEVEL_SCRIPT_PATH=$(dirname "${ROOTDIR}") ABS_PATH_EXECUTION_LOG_FILE=$(readlink -f ${UPLEVEL_SCRIPT_PATH}/logs/${DB_UNIQUE_NAME}_${EXEC_ID}.log) get_database_info echo "I like to move it, move it!" if [ "${THIS_HOST}" == "${DBNODE1}" ]; then EXECUTION_HOST=${THIS_HOST} EXECUTION_INSTANCE=${DBINST1} EXECUTION_HOST_BIS=${DBNODE2} EXECUTION_INSTANCE_BIS=${DBINST2} echo "BEGIN ORACLE HOME MOVE for ${DB_UNIQUE_NAME} database" local_execution echo "END ORACLE HOME MOVE for ${DB_UNIQUE_NAME} database" RETURN_CODE=0 elif [ "${THIS_HOST}" == "${DBNODE2}" ]; then EXECUTION_HOST=${THIS_HOST} EXECUTION_INSTANCE=${DBINST2} EXECUTION_HOST_BIS=${DBNODE1} EXECUTION_INSTANCE_BIS=${DBINST1} echo "BEGIN DATAPATCH for ${DB_UNIQUE_NAME} database" local_execution echo "END DATAPATCH for ${DB_UNIQUE_NAME} database" RETURN_CODE=0 else echo "ERROR: please execute this shell on ${DBNODE1} or ${DBNODE2}" RETURN_CODE=1 fi exit ${RETURN_CODE}