nohup dgmgrl 启动后 observer 一断开就退出,因其在 START OBSERVER 模式下本质是交互式会话,非守护进程;nohup 仅屏蔽 SIGHUP,无法阻止 TTY EOF 导致 read() 返回 0 而终止。
为什么 nohup dgmgrl 启动后 observer 一断开就退出
因为 dgmgrl 在 observer 模式下(start observer)本质上是交互式会话,不是守护进程;nohup 只能屏蔽 sighup,但无法阻止终端关闭时 tty 的 eof 触发 dgmgrl 主动退出。你看到的“后台运行”只是假象——进程实际卡在等待输入状态,一旦父 shell 退出或 ssh 断连,它很快被 sigpipe 或 read() 返回 0 而终止。
正确启动 observer 并保持长期在线的三步法
必须绕过交互式入口,用脚本封装 + 真实守护机制:
- 写一个最小化启动脚本
start_observer.sh,内容为:#!/bin/bash export ORACLE_HOME=/u01/app/oracle/product/19c/dbhome_1 export PATH=$ORACLE_HOME/bin:$PATH echo "START OBSERVER" | dgmgrl /
- 用
nohup+&运行该脚本,并重定向所有流:nohup ./start_observer.sh > /tmp/observer.log 2>&1
- 加一层保险:用
systemd或supervisord管理(推荐 systemd),避免依赖用户 session。例如/etc/systemd/system/dg-observer.service中设置Type=simple、Restart=always、RestartSec=10
START OBSERVER 命令本身不支持后台参数
Oracle 官方明确未提供 -background 或 --daemon 类选项。dgmgrl 的 observer 模式设计就是“启动即驻留”,但它把驻留逻辑耦合在了交互式 stdin 处理上——所以直接 echo "START OBSERVER" | dgmgrl / 是唯一可行的免交互路径。别尝试 setsid 或 screen -dmS,它们治标不治本:一旦底层 read() 遇到 EOF,observer 仍会干净退出,且不会自动重连。
验证 observer 是否真正在线的两个关键检查点
不能只看进程是否存在:
- 查
ps -ef | grep dgmgrl输出中是否含START OBSERVER字样(而非仅是dgmgrl /) - 登录到主库或备库,执行
dgmgrl /→SHOW CONFIGURATION,确认输出里Observer状态为ONLINE,且State列显示VALID(不是UNKNOWN或空白) - 注意:
tail -f /tmp/observer.log若持续滚动 “Observer started” 日志,说明脚本没卡住;若日志停在某一行不动,大概率 stdin 被截断,需检查是否遗漏
observer 的心跳和故障响应完全依赖后台持续运行的 dgmgrl 实例,任何中断都会导致 DGMGRL 无法触发自动切换。最常被忽略的是脚本中未设置 ORACLE_HOME 和 PATH,导致 dgmgrl 找不到 Oracle 网络配置而静默失败。











