缍米 发表于 2025-10-6 12:23:04

oracle_19c_ru_ojvm_upgrade.sh一键升级脚本分享

oracle_19c_ru_ojvm_upgrade.sh脚本的初始版本来源于IT邦德的分享,使用原脚本时发现有一些bug,在我的环境中脚本根本跑不通,于是个人在这个脚本的基础上进行了大量的改进与优化,到当前版本可以说算是完全重构了。我用这个脚本进行了大量的测试验证(测试环境和UAT环境Oracle 19c数据库实例打补丁),对于Oracle 19c来说基本上是没有什么问题. 使用此脚本打补丁相当丝滑与惬意。也确实让工作效率飞升,可以腾出很多时间做其他事情。脚本的一些思路与想法,阅读下面代码即可略知一二,如果有不足的地方,也敬请指教。当然,这个脚本暂时没有在其他数据库版本经过测试验证。难免会一些Bug,个人后续也会不断地完善、扩充这个脚本。关于这个脚本的一些基本注意事项,详情请见下面:
注意事项:


[*]此脚本只在Linux(REHL)平台上测试了Oracle 19c数据库, 虽然经过大量验证,不保证其它平台环境也能运行,可能存在Bug,使用前请进行测试验证,作者不保证脚本没有任何bug
[*]使用前,根据实际情况修改相关变量.
[*]REQUIRED_OPATCH_VERSION变量需要指定的opatch版本根据官方文档资料指定
[*]脚本目前还只适用于单实例
[*]Oracle 19c早期版本需要先回滚OJVM补丁,然后安装新的补丁,从Oracle Database 19.17.0开始,官方发布了 RU + OJVM Combination Patch(组合补丁)。在该组合补丁中,OJVM 补丁已被整合进 RU 安装映像,不再需要先回滚旧的 OJVM 补丁. 脚本里面没有考虑早期版本升级需要先回滚OJVM补丁情况. 如有需要,请自行完善.
[*]多实例环境,又分相同数据库版本和不同数据库版本,这里脚本暂未实现这个功能, 属实太复杂的场景会让脚本变得无比复杂,代码量继续飙增.这个脚本代码行数破千了。如果是相同数据库版本的多实例,只保留一个实例和监听服务,其它关闭,然后跑完脚本,最后在启动其它实例,只需跑datapatch脚本
[*]脚本的函数prepare_run_sql只是特殊环境需要授权,应该很多人的数据库环境根本不需要这样的授权,可以注释删除这个函数。
#!/bin/bash##########################################################################################                                                                                       ## Oracle 19c RU + OJVM 一键升级脚本,此脚本初始版本来源于IT邦德,使用原脚本时发现有一些bug## 于是个人在其基础上进行了大量的调整与改进,这个脚本基本上可以算是完全重构了。          ###########################################################################################                                                                                       ## ScriptName            :    oracle_19c_ru_ojvm_upgrade.sh                              ## Author                :    潇湘隐者                                                   ## CerateDate            :    2025-08-21                                                 ## Email               :    kerry2008code@qq.com                                       ##***************************************************************************************## 变量配置                                                                              ##---------------------------------------------------------------------------------------## CONNECT_INFO      连接数据库的方式,默认为系统认证模式(如需适用账号密码访问,调整即可 ## ORACLE_SID          ORACLE_SID                                                      ## ORACLE_HOME         ORACLE主目录                                                      ## PATCH_DIR         Oracle的补丁文件存放路径                                          ## OPATCH_PATCH      Oracle的opatch补丁文件名                                          ## REQUIRED_OPATCH_VERSION 要求的最低opatch版本                                          ## RU_PATCH            RU补丁文件名                                                      ## OJVM_PATCH          OJVM补丁名                                                      ##---------------------------------------------------------------------------------------## 参数说明                                                                              ##---------------------------------------------------------------------------------------##   此脚本无须使用参数                                                                ##---------------------------------------------------------------------------------------##Usage:                                                                               ##          sh oracle_19c_ru_ojvm_upgrade.sh                                             ##      或./oracle_19c_ru_ojvm_upgrade.sh                                              ##***************************************************************************************## 注意事项:                                                                           ##    1. 此脚本只在Linux(REHL)平台上测试了Oracle 19c数据库, 虽然经过大量验证,不保证其它##       平台环境也能运行,可能存在Bug,使用前请进行测试验证,作者不保证脚本没有任何bug   ##    2. 使用前,根据实际情况修改相关变量.                                                ##    3. REQUIRED_OPATCH_VERSION变量需要指定的opatch版本根据官方文档资料指定             ##    4. 脚本目前还只适用于单实例                                                      ##    5. Oracle 19c早期版本需要先回滚OJVM补丁,然后安装新的补丁,从Oracle Database 19.17.0 ##       开始,官方发布了 RU + OJVM Combination Patch(组合补丁)。在该组合补丁中,OJVM 补丁##       已被整合进 RU 安装映像,不再需要先回滚旧的 OJVM 补丁. 脚本里面没有考虑早期版本升##       级需要先回滚OJVM补丁情况. 如有需要,请自行完善.                                  ##    6. 多实例环境,又分相同数据库版本和不同数据库版本,这里脚本暂未实现这个功能,         ##       属实太复杂的场景会让脚本变得无比复杂,代码量继续飙增.这个脚本代码行数破千了      ##       如果是相同数据库版本的多实例,只保留一个实例和监听服务,其它关闭,然后跑完脚本,最后##       在启动其它实例,只需跑datapatch脚本                                              ##***************************************************************************************## Version      Modified Date            Description                                 ##***************************************************************************************## V.0.0          2025-08-19            IT邦德的原始脚本                               ## V.1.0          2025-08-21            修改/创建此脚本                              ## V.1.1          2025-08-25            增加逻辑判断,fix掉几个bug                      ## V.1.2          2025-08-29            关闭/启动数据库实例,关闭/启动监听功能封装成函数##                                        独立出来,方便简单调用                        ## V.1.3          2025-09-01            打补丁前检查各个PDB失效对象信息,打完补丁后执行 ##                                        重编译无效对象                                 ## V.1.4          2025-09-02            打完补丁,检查补丁安装信息                      ## V.1.5          2025-09-03            完善部分功能与(19c非租户环境)执行检查无      ##                                        效对象出错的Bug                              ########################################################################################### =============== 安全控制 ===============# 严格错误处理#set -euo pipefail#trap "echo 'ERROR: 脚本异常退出,请检查日志!'; exit 1" ERR# =============== 配置区(根据实际修改)===============# ORACLE_SIDexport ORACLE_SID="gsp"# ORACLE_HOME目录export ORACLE_HOME="/opt/oracle19c/product/19.3.0/db_1"# 数据库的连接方式,请根据实际情况调整readonly CONNECT_INFO="conn / as sysdba"# 数据库补丁存放的路径readonly PATCH_DIR="/data/soft"# OPATCH补丁文件名readonly OPATCH_PATCH="p6880880_190000_Linux-x86-64.zip"# 要求的最低opatch版本readonly REQUIRED_OPATCH_VERSION="12.2.0.1.46"# RU补丁文件名readonly RU_PATCH="p37960098_190000_Linux-x86-64.zip"# OJVM补丁文件名readonly OJVM_PATCH="p37847857_190000_Linux-x86-64.zip"# 下面变量基本无须修改ROLLBACK_FILE="${PATCH_DIR}/rollback_${ORACLE_SID}_$(date +%Y%m%d).sql"LOG_DATE=$(date +%Y%m%d%H%M)readonly SUCCESS=0readonly FAILURE=1LOG_FILE="${PATCH_DIR}/patch_${ORACLE_SID}_${LOG_DATE}.log"# Log输出方式:log或cmd或allLOG_OUT_TYPE=allLSNR_NAME=""DB_VERSION="19"IS_MULTI_DB=""OS_TYPE=""PDB_LIST=""# 记录脚本的日志信息输出log_info(){    #判断参数个数    if [ $# -eq 1 ];then      local log_msg=$1      case $LOG_OUT_TYPE in            cmd)                echo -e ": $(date '+%Y%m%d %H:%M:%S')> ${log_msg}"                ;;            log)                echo -e ": $(date '+%Y%m%d %H:%M:%S')> ${log_msg}" >> "$LOG_FILE"                ;;            all)                # log_info暂时不会发送邮件                echo -e ": $(date '+%Y%m%d %H:%M:%S')> ${log_msg}"                echo -e ": $(date '+%Y%m%d %H:%M:%S')> ${log_msg}" >> "$LOG_FILE"                ;;            *)      esac    elif [ $# -eq 2 ];then      local log_msg=$1      case $2 in            cmd)                echo -e ": $(date '+%Y%m%d %H:%M:%S')> ${log_msg}"                ;;            log)                echo -e ": $(date '+%Y%m%d %H:%M:%S')> ${log_msg}" >> "$LOG_FILE"                ;;             all)                echo -e ": $(date '+%Y%m%d %H:%M:%S')> ${log_msg}"                echo -e ": $(date '+%Y%m%d %H:%M:%S')> ${log_msg}" >> "$LOG_FILE"                ;;            *)      esac    else      echo -e ": $(date '+%Y%m%d %H:%M:%S')> the number of parameters is incorrect!"    fi}# 记录脚本的错误信息输出log_error(){    #判断参数个数    if [ $# -eq 1 ];then      local log_msg=$1      case $LOG_OUT_TYPE in            cmd)               echo-e":$(date '+%Y%m%d %H:%M:%S')> ${log_msg}"               ;;            log)               echo-e":$(date '+%Y%m%d %H:%M:%S')> ${log_msg}" >> "$LOG_FILE"               ;;            all)               echo -e ":$(date '+%Y%m%d %H:%M:%S')> ${log_msg}"               echo -e ":$(date '+%Y%m%d %H:%M:%S')> ${log_msg}" >> "$LOG_FILE"               ;;            *)      esac    elif [ $# -eq 2 ];then      local log_msg=$1      case $2 in            cmd)               echo-e":$(date '+%Y%m%d %H:%M:%S')> ${log_msg}"               ;;            log)               echo-e":$(date '+%Y%m%d %H:%M:%S')> ${log_msg}" >> "$LOG_FILE"               ;;            all)               echo -e ":$(date '+%Y%m%d %H:%M:%S')> ${log_msg}"               echo -e ":$(date '+%Y%m%d %H:%M:%S')> ${log_msg}" >> "$LOG_FILE"               ;;            *)      esac    else      echo -e ": $(date '+%Y%m%d %H:%M:%S')> the number of parameters is incorrect!"    fi}precheck() {    log_info "precheck开始预检..."      # 1. 检查操作系统    OS_TYPE=$(uname -a | awk ' { print $1} ')    log_info "当前操作系统为: "${OS_TYPE}" "       if [ "$OS_TYPE" == "Linux" ];    then         log_info "当前操作系统为 ${OS_TYPE},检查通过"    else      log_info "当前脚本没有在Linux之外平台测试过,请谨慎使用!"    fi         # 2. 运行脚本的当前用户检查/确认    if [ "$(whoami)" != "oracle" ];   then      log_error "必须使用oracle用户执行此脚本!"      exit ${FAILURE}    else      log_info "账号检查正常,当前账号为$(whoami)"    fi      # 3. Oracle补丁文件检查是否齐全    if [[ ! -f ${PATCH_DIR}/${RU_PATCH} || ! -f ${PATCH_DIR}/${OJVM_PATCH} || ! -f ${PATCH_DIR}/${OPATCH_PATCH} ]];   then      log_error "Oracle相关补丁文件缺失!,请检查补丁包文件是否齐全"      exit ${FAILURE}    else      log_info "Oracle安装升级的补丁文件齐全,如下所示:"      ls -lrt ${PATCH_DIR}/${RU_PATCH}      ls -lrt ${PATCH_DIR}/${OJVM_PATCH}      ls -lrt ${PATCH_DIR}/${OPATCH_PATCH}    fi      # 4. 数据库监听服务检查确认    local curr_lsn_num    curr_lsn_num=$(ps -e -o args | grep tnslsnr | grep -v grep |wc -l)    if [ "${curr_lsn_num}" -eq 0 ];    then      log_info "当前环境不存在监听服务或监听服务已经关闭了"      read -r-p "请输入正确的监听服务名"listener_name      LSNR_NAME=$(listener_name)   elif [ "${curr_lsn_num}" -eq 1 ]    then       LSNR_NAME=$(ps -e -o args | grep tnslsnr | grep -v grep | awk '{print $2}' | tr "[:upper:]" "[:lower:]")       log_info "当前监听名称为: ${LSNR_NAME}"    elif [ "${curr_lsn_num}" -gt 1 ];    then       log_info "当前环境有多个监听服务,请指定监听服务名: "       read -r-p "请输入正确的监听服务名: "listener_name       LSNR_NAME=$(listener_name)   fi         # 5. 数据库实例的状态检查确认    local curr_db_status    curr_db_status=$(check_db_status)            if [ "$curr_db_status" != "OPEN" ];   then      log_error "数据库已处于关闭状态,数据库必须处于OPEN状态"      exit${FAILURE}    else      IS_MULTI_DB=$(check_db_multitenant)      log_info "数据库状态为: ${curr_db_status} "    fi    # 5. OPatch版本检查    log_info "Opatch的版本信息如下所示:"    $ORACLE_HOME/OPatch/opatch version   # 6. 数据库版本信息    log_info "数据库的版本信息如下所示:"    sqlplus -S /nolog
页: [1]
查看完整版本: oracle_19c_ru_ojvm_upgrade.sh一键升级脚本分享