linux下oracle开机自启动以及关机自关闭数据库,并发送邮件通知

🔥 前言:做开发、测试或服务器运维的同学,是不是每天上班第一件事就是登录Linux服务器、启动Oracle数据库?关机时还要手动关闭数据库,生怕强制关机导致数据损坏、日志丢失!重复操作浪费时间,还容易遗漏步骤!今天分享核心技巧,实现Linux下Oracle开机自启动、关机自关闭,还能自动发送邮件通知状态,设置一次,长期生效,彻底解放双手,提升摸鱼(划掉)工作效率!

💡 适用场景:Oracle数据库运维、Linux服务器值守、开发/测试环境部署,支持CentOS 7/8、RHEL 7/8所有版本,兼容Oracle 11g/12c/19c主流版本,新手也能一步到位,全程复制命令即可完成!

一、先搞懂前提:环境准备(必做,避免后续踩坑)

操作前先确认2个核心前提,缺一不可,否则会导致自启/自关失败,新手必看!

  1. 确认Oracle环境正常:登录Linux服务器,切换到oracle用户(su - oracle),输入sqlplus / as sysdba,执行startup,能正常启动数据库;执行shutdown immediate,能正常关闭数据库,说明Oracle环境无问题。

  2. 确认邮件服务可用:本文采用Linux自带sendmail服务发送通知邮件,需提前安装并启动(后续会分步讲解,无需提前操作,跟着步骤来即可),支持发送到QQ邮箱、企业邮箱。

注意:本文所有操作均以「root用户」执行(除Oracle相关命令),Oracle安装路径默认「/opt/oracle/product/11.2.0/dbhome_1」,若你的安装路径不同,替换所有命令中的路径即可。

二、核心操作:Oracle开机自启动

开机自启动是基础,分「rc.local脚本(简单易操作,新手推荐)」和「systemd服务(稳定可靠,运维首选)」,根据自己的Linux版本选择,CentOS 7+优先方法2,CentOS 6优先方法1。

方法:rc.local脚本自启(简单直接,新手友好)

适用:CentOS 6/7/8通用,无需复杂配置,编辑脚本、添加权限即可,适合新手快速上手。

  1. 编辑rc.local文件:执行命令(直接复制),打开自启配置文件: vi /etc/rc.d/rc.local

  2. 添加自启脚本:在文件末尾添加以下内容(替换Oracle安装路径和用户名,默认无需修改):

    bash 复制代码
    # 注意 start_oracle_mail.sh 脚本中的内容,如果是用root账户执行的 su - oracle -c "lsnrctl start" 则无需在rc.local中切换账号
    
    /bin/bash /home/oracle/start_oracle_mail.sh
    
    
    
    
    # 如果是oracle账户执行的命令,即 start_oracle_mail.sh 脚本中命令:lsnrctl start ,则在 rc.local 前需要加入账号切换
    
    su - oracle -lc "/bin/bash /home/oracle/start_oracle_mail.sh"
  3. 添加执行权限:执行以下命令,确保rc.local文件可执行(否则自启失效): chmod +x /etc/rc.d/rc.local

  4. startup_oracle_mail.sh 脚本内容如下:

    bash 复制代码
    #!/bin/bash
    
    ###########################################################
    # Oracle 自动启动脚本
    # 顺序:先启动监听 → 再启动数据库实例
    # 功能:判断是否已运行,未运行才启动 + 邮件通知
    ###########################################################
    
    # ====================== 请修改这里的配置 ======================
    ORACLE_HOME=/opt/oracle/product/11.2.0/dbhome_1
    ORACLE_SID=ORCL
    LOG_FILE=/home/oracle/oracle_start_log/`date "+%Y%m%d-%H%M%S"`_log_z.txt  ## 日志存放地址
    # ============================================================
    
    # 确保日志目录存在
    mkdir -p /home/oracle/oracle_start_log
    
    export ORACLE_HOME
    export ORACLE_SID
    export PATH=$ORACLE_HOME/bin:$PATH
    
    # 日志开头
    echo "=============================================" >> $LOG_FILE
    echo "检查时间:$(date +'%Y-%m-%d %H:%M:%S')" >> $LOG_FILE
    
    # 记录最终消息
    MSG=""
    
    ###########################################################################
    # 第一步:检查并启动监听(先启动监听)
    ###########################################################################
    LSNR_STATUS=$(ps -ef | grep tnslsnr | grep -v grep | wc -l)
    
    if [ $LSNR_STATUS -eq 0 ]; then
        echo "监听未运行 → 开始启动监听" >> $LOG_FILE
        su - oracle -c "lsnrctl start" >> $LOG_FILE 2>&1
    
        # 监听启动后短暂等待
        sleep 2
        LSNR_AFTER=$(ps -ef | grep tnslsnr | grep -v grep | wc -l)
        if [ $LSNR_AFTER -ge 1 ]; then
            MSG+="✅ 监听已成功启动\n"
        else
            MSG+="❌ 监听启动失败\n"
        fi
    else
        MSG+="ℹ️ 监听已在运行,无需启动\n"
    fi
    
    ###########################################################################
    # 第二步:检查并启动数据库实例(后启动实例)
    ###########################################################################
    # 优化:用oracle自带工具检查实例状态(比ps更可靠)
    check_db_status() {
        su - oracle -c "sqlplus -s / as sysdba << EOF
        set heading off;
        set feedback off;
        select 'RUNNING' from dual where instance_status = 'OPEN';
        exit;
    EOF" | grep -i "RUNNING" > /dev/null 2>&1
        return $?
    }
    
    # 先执行基础进程检查
    DB_STATUS=$(ps -ef | grep "ora_pmon_$ORACLE_SID" | grep -v grep | wc -l)
    
    if [ $DB_STATUS -eq 0 ]; then
        echo "实例未运行 → 开始启动实例" >> $LOG_FILE
        su - oracle -c "sqlplus / as sysdba << EOF
    startup;
    exit;
    EOF" >> $LOG_FILE 2>&1
    
        # 关键优化:实例启动后等待5秒(让进程完全生成)
        sleep 5
    
        # 双重验证:先查进程 → 再用sqlplus查实例状态
        DB_AFTER=$(ps -ef | grep "ora_pmon_$ORACLE_SID" | grep -v grep | wc -l)
        if [ $DB_AFTER -ge 1 ] || check_db_status; then
            MSG+="✅ Oracle 实例已成功启动\n"
            MSG+="oracle well startup\n"
        else
            MSG+="❌ Oracle 实例启动失败\n"
        fi
    else
        MSG+="ℹ️ Oracle 实例已在运行,无需启动\n"
        MSG+="oracle well startup\n"
    fi
    
    # 记录日志
    echo -e "$MSG" >> $LOG_FILE
    echo "=============================================" >> $LOG_FILE
    echo "" >> $LOG_FILE
    
    # 发送邮件通知
    MAIL_TO="你的邮箱地址"
    SMTP_USER="你的邮箱地址"
    SMTP_PASS="你的邮箱授权码,需要申请"
    SMTP_SERVER="smtp.163.com"
    
    NOW_TIME=$(date +"%Y-%m-%d %H:%M:%S")
    SUBJECT="Oracle Server Startup Success"
    
    # ========== 正确拼接邮件内容 ==========
    CONTENT="Server startup
    Time: $NOW_TIME
    DB: ORCL
    Status: Oracle Safe Startup Finish
    $MSG"
    
    # 发送邮件
    echo -e "\n[2/3] Sending mail..."
    # 修复:Python Here Document 结束标记EOF单独一行,无空格
    python - << EOF
    # -*- coding: utf-8 -*-
    import smtplib
    from email.mime.text import MIMEText
    
    msg = MIMEText('''$CONTENT''','plain','utf-8')
    msg['From'] = '$SMTP_USER'
    msg['To'] = '$MAIL_TO'
    msg['Subject'] = '$SUBJECT'
    
    try:
        server = smtplib.SMTP('$SMTP_SERVER', 25)
        server.login('$SMTP_USER', '$SMTP_PASS')
        server.sendmail('$SMTP_USER', ['$MAIL_TO'], msg.as_string())
        server.quit()
        print("Mail send OK")
    except Exception as e:
        print("Mail send FAIL")
        print(str(e))  # 打印具体错误,方便排查
    EOF
    
    echo -e "\n[3/3] Script finished"

三、关键步骤:Oracle关机自关闭

服务器关机时,必须先关闭Oracle数据库和监听,否则会导致数据损坏、日志错乱!以下方案和上面的开机自启方法对应,按需选择,步骤可直接复制。

方案:rc.local脚本对应------关机自关闭(简单直接)

  1. 创建关机脚本:执行命令,创建关机脚本文件: vi /home/oracle/shutdown_oracle_mail.sh

  2. 添加脚本内容

    bash 复制代码
    #!/bin/bash
    export ORACLE_SID=ORCL
    export ORACLE_HOME=/opt/oracle/product/11.2.0/dbhome_1
    export PATH=$ORACLE_HOME/bin:$PATH
    
    MAIL_TO="你的邮箱地址"
    SMTP_USER="你的邮箱地址"
    SMTP_PASS="你的邮箱授权码,需要申请"
    SMTP_SERVER="smtp.163.com"
    
    NOW_TIME=$(date +"%Y-%m-%d %H:%M:%S")
    SUBJECT="Oracle Server Will Shutdown"
    CONTENT="Server Shutdown
    Time: $NOW_TIME
    DB: ORCL
    Status: Oracle Safe Shutdown Finish"
    
    echo "============================================="
    echo "Oracle Safe Shutdown + Mail"
    echo "============================================="
    
    # 检查 Oracle 是否运行(通用版,不写死 ORCL)
    echo -e "\n[1/3] Check Oracle status..."
    ps -ef | grep ora_pmon | grep -v grep >/dev/null
    if [ $? -eq 0 ];then
      echo "Oracle is running, stopping..."
      su - oracle -c "
      sqlplus / as sysdba << EOF
      shutdown immediate;
      exit;
    EOF
      "
    
      # 等待完全关闭
      while true; do
        ps -ef | grep ora_pmon | grep -v grep >/dev/null
        if [ $? -ne 0 ];then
          echo "Oracle stopped successfully"
          break
        fi
        sleep 2
      done
    else
      echo "Oracle is already stopped"
    fi
    
    # 发送邮件
    echo -e "\n[2/3] Sending mail..."
    python - << EOF
    # -*- coding: utf-8 -*-
    import smtplib
    from email.mime.text import MIMEText
    
    msg = MIMEText('''$CONTENT''','plain','utf-8')
    msg['From'] = '$SMTP_USER'
    msg['To'] = '$MAIL_TO'
    msg['Subject'] = '$SUBJECT'
    
    try:
        server = smtplib.SMTP('$SMTP_SERVER', 25)
        server.login('$SMTP_USER', '$SMTP_PASS')
        server.sendmail('$SMTP_USER', ['$MAIL_TO'], msg.as_string())
        server.quit()
        print("Mail send OK")
    except Exception as e:
        print("Mail send FAIL")
    EOF
    
    # 关机
    echo -e "\n[3/3] System shutdown after 3 seconds..."
    sleep 3
    shutdown -h now
  3. 添加执行权限:执行命令,赋予脚本可执行权限: chmod +x /etc/init.d/shutdown_oracle_mail.sh

  4. 配置关机触发:通过定时任务关机,比如每天晚上22点关机,先关闭oracle,后半闭虚拟机:

    bash 复制代码
    crontab -e
    0 22 * * * /root/shutdown_mail.sh >/dev/null 2>&1

四、避坑指南:90%的人会踩的4个坑(必看!)

  • 坑1:开机自启失败,提示"ORA-01031: 权限不足":原因是脚本未以oracle用户执行,检查脚本中的「su - oracle -c」命令是否遗漏,或权限未设置正确(chmod +x)。

  • 坑2:关机自关闭失效,强制关机导致数据损坏:方案1需确保rc0.d、rc6.d目录下有脚本软链接;方案2需确认ExecStop命令路径正确,重启systemd服务配置。

  • 坑3:邮件发送失败,收不到通知:检查sendmail服务是否启动,邮箱授权码是否正确(QQ邮箱授权码需在"设置-账户-POP3/IMAP"中开启),服务器是否能ping通smtp.qq.com

  • 坑4:监听未启动,客户端无法连接:自启脚本中遗漏「lsnrctl start」命令,或dbstart配置文件中ORACLE_HOME_LISTNER路径错误,补充命令或修改路径即可。

五、总结:一步到位,运维省心又高效

整个流程分为3步:先准备环境,再设置Oracle开机自启+关机自关闭,最后配置邮件通知,设置一次,终身受益!

不管是开发、测试还是运维,都能节省每天重复操作的时间,避免因忘记关闭数据库导致的数据损坏,邮件通知更是让你随时随地掌握Oracle状态,无需频繁登录服务器。按照步骤操作,新手也能一次成功,有问题可在评论区留言,看到必回!

💬 评论区互动:你平时是手动启停Oracle还是自动启停?还有哪些Linux运维提升效率的小技巧,欢迎留言分享~

相关推荐
战族狼魂2 小时前
基于LibreOffice +python 实现一个小型销售管理系统的数据库原型教学实验
数据库·python
m0_640309302 小时前
PHP函数怎样适配高可靠性存储硬件_PHP在ZFS RAIDZ环境配置【技巧】
jvm·数据库·python
踏浪无痕2 小时前
用 AI 解决数据库性能问题的方法论
数据库
hnmpf3 小时前
linux系统离线环境安装mysql问题
linux·运维·mysql
2402_854808373 小时前
Django REST Framework 中实现用户资料更新的完整实践指南
jvm·数据库·python
m0_748839493 小时前
golang如何理解weak pointer弱引用_golang weak pointer弱引用总结
jvm·数据库·python
m0_738120723 小时前
渗透测试基础ctfshow——Web应用安全与防护(五)
前端·网络·数据库·windows·python·sql·安全
2401_865439633 小时前
mysql如何处理升级后的身份认证兼容性_mysql_native_password配置
jvm·数据库·python
lhbian3 小时前
PHP、C++和C语言对比:哪个更适合你?
android·数据库·spring boot·mysql·kafka