oracle在Linux上配置实例与监听的开机自启动的解决方案

问题:

Oracle 各版本在 Linux 上安装后默认都不会把实例与监听注册为开机自启动 :主机重启后实例未拉起、监听未启动(lsnrctl status 报 TNS-12541: TNS:no listener,连接报 Linux Error: 111: Connection refused)。各版本的核心机制相同(/etc/oratab 开关 + dbstart/dbshut 脚本),但注册到操作系统启动流程的方式随版本与安装方式不同:10g/11g/12c 走 SysV(rc.local 或 init.d 脚本),18c 起提供 RPM 自带的 init.d 服务脚本,19c 起推荐 systemd,RAC/ASM 环境则统一交给 CRS 管理。

方案:

〇、所有版本通用的两步前置操作(无论哪种注册方式都必须做)

第 1 步:修改 /etc/oratab 开关(核心开关,不改则 dbstart 不会启动任何实例)

格式为 $ORACLE_SID:$ORACLE_HOME:<Y|N>,把实例所在行的第三字段由 N 改为 Y:

bash 复制代码
cp -a /etc/oratab /etc/oratab.bak
# 通用写法(把 <SID> 换成实际实例名):
sed -i 's#^<SID>:\(.*\):N#<SID>:\1:Y#' /etc/oratab
grep '^<SID>' /etc/oratab        # 确认已变为 :Y

示例行:

复制代码
orcl:/u01/app/oracle/product/19.0.0/dbhome_1:Y

第 2 步:检查 dbstart/dbshut 中的监听变量(10g/11g/12c 尤其重要)

dbstart 中启动监听依赖变量 ORACLE_HOME_LISTNER(注意该变量在脚本中的原始拼写 就是 LISTNER)。其默认值为 $1(脚本第一个参数),当由 rc.local 等方式调用而未传参时,监听可能起不来,需硬编码为 $ORACLE_HOME:

bash 复制代码
sed -i 's/ORACLE_HOME_LISTNER=$1/ORACLE_HOME_LISTNER=$ORACLE_HOME/' $ORACLE_HOME/bin/dbstart
sed -i 's/ORACLE_HOME_LISTNER=$1/ORACLE_HOME_LISTNER=$ORACLE_HOME/' $ORACLE_HOME/bin/dbshut

提示:若你的调用方式始终显式传参(如 dbstart $ORACLE_HOME),部分场景无需修改此变量;若采用 rc.local 无参调用,则建议修改。两种实践都存在,以实际启动结果为准。


一、10g / 11g(SysV 系统,手工挂接)

适用于 RHEL/CentOS 5/6 等 SysV init 环境,两种方式二选一。

方式 A:/etc/rc.d/rc.local(最简单)

bash 复制代码
# 编辑 /etc/rc.d/rc.local,在末尾追加:
su - oracle -lc "$ORACLE_HOME/bin/lsnrctl start"
su - oracle -lc "$ORACLE_HOME/bin/dbstart $ORACLE_HOME"
# 如需 EM(11g):su - oracle -lc "export ORACLE_UNQNAME=orcl; $ORACLE_HOME/bin/emctl start dbconsole"

# CentOS 7 及以上需赋执行权限:
chmod +x /etc/rc.d/rc.local

方式 B:/etc/rc.d/init.d/oracle 服务脚本(可用 chkconfig 管理)

bash 复制代码
#!/bin/bash
# chkconfig: 345 99 10
# description: Oracle auto start-stop script.
ORA_OWNER=oracle
case "$1" in
  'start')
    su - $ORA_OWNER -lc "$ORACLE_HOME/bin/lsnrctl start"
    su - $ORA_OWNER -lc "$ORACLE_HOME/bin/dbstart $ORACLE_HOME"
    ;;
  'stop')
    su - $ORA_OWNER -lc "$ORACLE_HOME/bin/dbshut $ORACLE_HOME"
    su - $ORA_OWNER -lc "$ORACLE_HOME/bin/lsnrctl stop"
    ;;
  *)
    echo "Usage: $0 {start|stop}"
    exit 1
    ;;
esac
exit 0
bash 复制代码
chmod 755 /etc/rc.d/init.d/oracle
chkconfig --add oracle
chkconfig oracle on
service oracle start|stop|restart     # 验证

10g 特例 :10.2.0.1 必须修改 dbstart 中的 ORACLE_HOME_LISTNER(见通用第 2 步),否则监听不启动。


二、12c(SysV,机制与 11g 相同)

  1. 完成通用第 1、2 步。
  2. 注册方式同 11g 的方式 A 或方式 B。
  3. EM 变化 :12c 起 EMDE(Database Express)取代 EMDC,无需单独配置 EM 自启动 (11g 需要 emctl start dbconsole 的部分可省去)。
  4. 12c 多租户(CDB/PDB):dbstart 会启动 CDB 实例,PDB 随 CDB 自动 OPEN(若配置了 PDB 的 SAVE STATE,可保持 PDB 自动打开状态)。

三、18c(RPM 安装自带 init.d 服务脚本)

RPM 方式安装后,Oracle 会自动生成服务脚本,无需手工编写:

  1. 确认脚本与参数文件 :

    bash 复制代码
    ls -l /etc/init.d/oracledb_ORCLCDB-18c
    ls -l /etc/sysconfig/oracledb_ORCLCDB-18c.conf
  2. 修改参数文件 (决定 CDB/PDB 名称、端口等):

    bash 复制代码
    vi /etc/sysconfig/oracledb_ORCLCDB-18c.conf
    # ORACLE_SID / ORACLE_HOME / LISTENER_PORT 等
  3. 建库(如尚未建库) :

    bash 复制代码
    /etc/init.d/oracledb_ORCLCDB-18c configure
    # 自动创建 CDB=ORCLCDB、PDB=ORCLPDB1,并配置默认端口 1521 的监听
  4. 设为开机自启并启动 :

    bash 复制代码
    chkconfig --add oracledb_ORCLCDB-18c
    chkconfig oracledb_ORCLCDB-18c on
    service oracledb_ORCLCDB-18c start

四、19c(推荐 systemd,也可用 RPM 自带脚本)

方式 A:RPM 自带脚本(仅限 RPM 安装,最省事)

bash 复制代码
ls -l /etc/init.d/oracledb_ORCLCDB-19c /etc/sysconfig/oracledb_ORCLCDB-19c.conf
vi /etc/sysconfig/oracledb_ORCLCDB-19c.conf       # 配置 ORACLE_SID/ORACLE_HOME/LISTENER_PORT
/etc/init.d/oracledb_ORCLCDB-19c configure        # 如尚未建库
systemctl enable oracledb_ORCLCDB-19c
systemctl start  oracledb_ORCLCDB-19c

方式 B:手工创建 systemd 服务(通用,推荐用于二进制安装)

先完成通用第 1 步(改 /etc/oratab)。

/usr/lib/systemd/system/lsnrctl.service(监听):

ini 复制代码
[Unit]
Description=Oracle Net Listener
After=network.target

[Service]
Type=forking
User=oracle
Group=dba
Environment=ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1
Environment=ORACLE_SID=orcl
ExecStart=/u01/app/oracle/product/19.0.0/dbhome_1/bin/lsnrctl start
ExecStop=/u01/app/oracle/product/19.0.0/dbhome_1/bin/lsnrctl stop
ExecReload=/u01/app/oracle/product/19.0.0/dbhome_1/bin/lsnrctl reload

[Install]
WantedBy=multi-user.target

/usr/lib/systemd/system/oracledb.service(实例):

ini 复制代码
[Unit]
Description=Oracle Database Service
After=network.target lsnrctl.service
Requires=lsnrctl.service

[Service]
Type=forking
User=oracle
Group=dba
Environment=ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1
Environment=ORACLE_BASE=/u01/app/oracle
Environment=ORACLE_SID=orcl
ExecStart=/u01/app/oracle/product/19.0.0/dbhome_1/bin/dbstart /u01/app/oracle/product/19.0.0/dbhome_1
ExecStop=/u01/app/oracle/product/19.0.0/dbhome_1/bin/dbshut /u01/app/oracle/product/19.0.0/dbhome_1

[Install]
WantedBy=multi-user.target

若 systemctl status oracledb 显示服务已退出/失败(因为 dbstart 执行完即返回、不常驻),将 Type=forking 改为 Type=oneshot 并追加 RemainAfterExit=yes。

赋权、重载、设为自启、验证:

bash 复制代码
chown root:root /usr/lib/systemd/system/lsnrctl.service /usr/lib/systemd/system/oracledb.service
chmod 644       /usr/lib/systemd/system/lsnrctl.service /usr/lib/systemd/system/oracledb.service
systemctl daemon-reload
systemctl enable lsnrctl oracledb
systemctl start  lsnrctl oracledb
systemctl status lsnrctl oracledb
lsnrctl status

五、21c(RPM + systemd)

  1. RPM 安装后,使用初始化脚本建库并配置监听:

    bash 复制代码
    /etc/init.d/oracledb_ORCLCDB-21c configure
    # 自动创建 CDB=ORCLCDB,执行复制文件、启动实例、创建 PDB 等各阶段
  2. 设为开机自启:

    bash 复制代码
    systemctl enable oracledb_ORCLCDB-21c
    systemctl start  oracledb_ORCLCDB-21c
  3. 若为二进制安装,仍按 19c 方式 B 手工编写 systemd 服务。


六、23ai / 26ai(systemd)

  • 23ai/26ai 完全基于 systemd 管理,安装程序会提供服务脚本(如 Oracle AI Database Free 的 /etc/init.d/oracle-free-26ai),支持 start/stop/status:

    bash 复制代码
    systemctl enable oracle-free-26ai
    systemctl start  oracle-free-26ai
    systemctl status oracle-free-26ai
  • 核心机制仍是 /etc/oratab + dbstart/dbshut,只是在 systemd 下由服务单元调用。


七、RAC / ASM 环境(所有版本统一,不走上表方式)

RAC 与 ASM 由 Grid Infrastructure 的 CRS 统一管理,不要使用 rc.local/init.d/systemd 手工挂接,应把数据库资源注册到 CRS:

bash 复制代码
# 以 root 执行,<dbname> 替换为实际数据库名
crsctl modify resource "ora.<dbname>.db" -attr "AUTO_START=always" -unsupported

AUTO_START=always 表示集群启动时自动启动该实例;-unsupported 允许修改非官方支持属性;修改后重启主机验证。


附一:各版本配置方式速查

版本 安装方式 注册方式 关键文件
10g / 11g 二进制 rc.local 或 init.d/oracle 脚本 /etc/oratab、$ORACLE_HOME/bin/dbstart、/etc/rc.d/rc.local
12c 二进制 同 11g(EMDE 免配 EM) 同上
18c RPM init.d 自带脚本 /etc/init.d/oracledb_ORCLCDB-18c、/etc/sysconfig/oracledb_ORCLCDB-18c.conf
19c RPM init.d 自带脚本或 systemd /etc/init.d/oracledb_ORCLCDB-19c、/usr/lib/systemd/system/{lsnrctl,oracledb}.service
21c RPM systemd /etc/init.d/oracledb_ORCLCDB-21c、systemd unit
23ai / 26ai RPM/二进制 systemd /etc/init.d/oracle-free-26ai、systemd unit
RAC / ASM(全部) --- CRS 管理 crsctl modify resource ... AUTO_START=always

附二:配置文件清单

文件 作用
/etc/oratab 记录 `ORACLE_SID:ORACLE_HOME:<Y
$ORACLE_HOME/bin/dbstart、dbshut Oracle 自带启停脚本,读 oratab 启停实例并连带启停监听(含 ORACLE_HOME_LISTNER 变量)
/etc/rc.d/rc.local SysV 启动流程最后执行(10g/11g/12c;CentOS7+ 需 chmod +x)
/etc/rc.d/init.d/oracle SysV 自定义服务脚本(10g/11g/12c,配 chkconfig)
/etc/init.d/oracledb_<SID>-<版本>、/etc/sysconfig/oracledb_<SID>-<版本>.conf 18c/19c/21c RPM 自带服务脚本与参数文件
/etc/init.d/oracle-free-26ai 23ai/26ai(Free)服务控制脚本
/usr/lib/systemd/system/lsnrctl.service、oracledb.service 19c+ 手工 systemd 服务单元
$ORACLE_HOME/network/admin/listener.ora 监听器配置(监听启动依赖,非自启动开关)
$ORACLE_HOME/startup.log、shutdown.log 启动/关闭日志,用于验证

附三:原理说明

  1. 为什么 Linux 下都要手工配? Windows 安装 Oracle 会自动注册 OracleService<SID> 与监听服务,把启动类型设为"自动"即可;Linux 无此机制,安装程序不写系统服务,必须手工挂接。
  2. 系统启动流程差异 :SysV(RHEL/CentOS 5/6)由 init 按运行级别执行 /etc/rc.d/rcN.d/ 下的脚本,最后执行 rc.local;systemd(RHEL/CentOS 7+)由 multi-user.target 拉起各 unit,systemctl enable 的本质是在 /etc/systemd/system/multi-user.target.wants/ 下创建软链,daemon-reload 让 systemd 重新扫描 unit 文件。这就是"老版本用 rc.local/init.d、新版本用 systemd"的根本原因。
  3. dbstart 的工作机制 :逐行读 /etc/oratab,解析 SID:ORACLE_HOME:Y|N,只对标志为 Y 的实例执行 startup ------这正是"不改 oratab,重启后实例不启动"的根因;脚本内部同时调用 lsnrctl 启动监听,监听路径由 ORACLE_HOME_LISTNER 决定。
  4. 启动/关闭顺序 :启动时先启监听、再启实例 ;关闭时相反,先 dbshut 关实例、再 lsnrctl stop 关监听 。systemd 中用 After=/Requires= 声明该依赖。
  5. Type=forking 与 Type=oneshot :lsnrctl 启动后父进程退出、子进程常驻,用 forking;dbstart 执行完即返回,用 oneshot + RemainAfterExit=yes 更准确,否则会被 systemd 误判为服务失败。
  6. 多实例与边界 :/etc/oratab 中所有 Y 的实例会被一并自动启停,多实例环境需注意;ASM/RAC 必须交给 CRS(AUTO_START=always),不用上述方式;无 EM 时可省略 ORACLE_UNQNAME 与 emctl 相关行。

参考资料:

  • Oracle 官方文档:Oracle Database Administrator's Guide --- Starting and Stopping the Database Instances Automatically(dbstart/dbshut 与 /etc/oratab 机制)。
  • Oracle 官方文档:Oracle Database Net Services Administrator's Guide --- 监听器启动与 listener.ora 配置。
  • Oracle 官方文档:Oracle Database Installation Guide for Linux(各版本)--- 服务脚本与 systemd 集成。
  • 知识条目:Oracle DB/监听/OEM 开机自启动配置(Linux/Unix);Oracle 数据库、监听及 EM 开机自启动配置方法;Oracle 19c systemd 监听与数据库服务文件;systemd 服务配置后的激活步骤;oratab 标志控制数据库自启动;dbstart、dbshut、lsnrctl 命令用途;dbstart 监听器变量 ORACLE_HOME_LISTNER 修正;oracledb_ORCLCDB-18c.conf 配置文件;/etc/init.d/oracledb_ORCLCDB-18c configure 建库脚本;crsctl 配置 RAC 数据库实例开机自启动。