OceanBase中observer进程被自动拉起的原因与触发条件
本文中的 OCP 版本不低于 4.4.0 ,OceanBase 版本不低于 4.2.5 。更早期的版本,这里就不专门花时间来研究了。
模拟 OB 进程被杀场景
首先从一个简单的场景入手。如果服务器没有宕机,只把 OB 进程杀掉,OB 进程是否会自动拉起?又是谁拉起的?
OB 进程名叫 observer ,这里直接杀进程。
kill -9 $(pidof observer)
过了差不多 1 分钟后, OB 进程又自动起来了。

OB 进程宕机和恢复
这个 OB 进程自动拉起,是 OCP 的“预案管理”行为。当 OCP 发现 OB 进程不可用发出告警的时候,就会自动执行预案。

OB 进程宕机预案
OCP 里会有个预案执行历史。

OB 进程宕机预案执行历史
点击“查看任务”,可以看执行细节,就是告警信息。

OB 进程宕机告警
这里注意预案执行结果是“成功”。如果不成功,则必定有其他原因导致 OB 进程拉起失败。这个分析不是本文重点。
如果没有预案执行历史,则说明 OCP 没有拉起 OB 进程。为了确认这点,再看一下 OCP Agent 日志。
cd /home/admin/ocp_agent/log
grep "/home/admin/oceanbase/bin/observer" *.log |grep -v POST
[root@server61 log]# grep "/home/admin/oceanbase/bin/observer" *.log |grep -v POST
......
mgragent.log:2026-06-06T16:17:06.12835+08:00 INFO [1574,ad36bf661044e2de] caller=shell/exec.go:125:execute: execute shell command start, command=Command{user=admin, program=/bin/bash, outputType=combined, cmd=cd /home/admin/oceanbase; ulimit -s 10240 -u 655350 -n 655350 -c unlimited; LD_LIBRARY_PATH=/home/admin/oceanbase/lib:$LD_LIBRARY_PATH LD_PRELOAD='' /home/admin/oceanbase/bin/observer, timeout=10s} fields:, duration="114.89µs"
mgragent.log:2026-06-06T16:17:06.2824+08:00 INFO [1574,ad36bf661044e2de] caller=shell/exec.go:180:execute: execute shell command end, command=Command{user=admin, program=/bin/bash, outputType=combined, cmd=cd /home/admin/oceanbase; ulimit -s 10240 -u 655350 -n 655350 -c unlimited; LD_LIBRARY_PATH=/home/admin/oceanbase/lib:$LD_LIBRARY_PATH LD_PRELOAD='' /home/admin/oceanbase/bin/observer, timeout=10s} fields: duration=154.167428ms
mgragent.log:2026-06-06T16:17:06.44681+08:00 INFO [1574,fa36076a39e5ade7] caller=mgragent/system_handler.go:24:getProcessInfoHandler: get process info done fields:, name=observer, skipPorts=false, processes="[ProcessInfo{pid: 20259, name: observer, cmdLine: /home/admin/oceanbase/bin/observer, username: admin, createTime: 2026-06-06 16:17:05 +0800 CST, elapsedTime: 1378}]"
mgragent.log:2026-06-06T16:17:11.59114+08:00 INFO [1574,7829498d81131605] caller=mgragent/system_handler.go:24:getProcessInfoHandler: get process info done fields:, name=observer, skipPorts=false, processes="[ProcessInfo{pid: 20259, name: observer, cmdLine: /home/admin/oceanbase/bin/observer, username: admin, createTime: 2026-06-06 16:17:05 +0800 CST, elapsedTime: 6509}]"
[root@server61 log]#
如果预案自动拉起失败,手动拉起方法如下:
su - admin
export LD_LIBRARY_PATH=/home/admin/oceanbase/lib:$LD_LIBRARY_PATH LD_PRELOAD=''
cd /home/admin/oceanbase && bin/observer
推荐用相对路径启动,这样可以确保你是在正确的目录下启动。
服务器宕机重启场景
模拟服务器节点宕机重启的命令:reboot 。
通常重启后会自动加载一系列服务。OB 的进程自动拉起就在这些服务里。
早期版本写在 rc-local 服务里。
rc-local 服务
当主机重启后,首先确认一下主机启动的准确时间。
uptime -s
[root@server61 ~]# uptime -s
2026-06-06 16:30:19
查看 rc-local 服务内容。
[root@server61 ~]# systemctl cat rc-local | grep . |grep -v '^#'
[Unit]
Description=/etc/rc.d/rc.local Compatibility
ConditionFileIsExecutable=/etc/rc.d/rc.local
After=network.target
[Service]
Type=forking
ExecStart=/etc/rc.d/rc.local start
TimeoutSec=0
RemainAfterExit=yes
服务执行脚本在文件 /etc/rc.d/rc.local 文件中。
[root@server61 ~]# ls -lrth /etc/rc.local
lrwxrwxrwx. 1 root root 13 Jan 8 20:07 /etc/rc.local -> rc.d/rc.local
[root@server61 ~]# ls -lrth /etc/rc.d/rc.local
-rwxr-xr-x 1 root root 1.2K Mar 26 15:09 /etc/rc.d/rc.local
[root@server61 ~]#
[root@server61 ~]# cat /etc/rc.local | grep . |grep -v '^#'
touch /var/lock/subsys/local
/usr/local/bin/set_deadline.sh
echo never > /sys/kernel/mm/transparent_hugepage/enabled
/usr/local/sbin/set_nic_irq_ob.sh start
/usr/local/bin/auto_start_ob.sh >> /var/log/ob.autostart.log 2>&1 &
/usr/local/bin/set_cpufreq.sh
sysctl -e -p || sysctl -p
echo tsc > /sys/devices/system/clocksource/clocksource0/current_clocksource
[[ -f /home/admin/ens192-speed.mock ]] || echo 10000 > /home/admin/ens192-speed.mock
for ((i=0;i<60;i++)); do [[ -f /sys/class/net/ens192/speed ]] && { mount --bind /home/admin/ens192-speed.mock /sys/class/net/ens192/speed && break; } || sleep 5; done; [[ $i -eq 60 ]] && echo 'set nic speed timeout: nic not ready after 5 minutes.'
[root@server61 ~]#
操作系统默认在这个文件里不会写这么多内容,这里大部分内容都是 OB 产品(OAT 或者 OCP ) “塞”进去的。塞进去的理由有:设置 SSD 调度策略为 deadline 、禁用透明大页、设置网卡中断、自动启动 OB、CPU 频率设置、内核参数设置、时钟源设置、网卡速率模拟等。
可以通过日志观察 rc-local 服务是否正常执行。
grep "rc.local" /var/log/messages
Jun 6 16:30:24 server61 systemd: rc-local.service: control process exited, code=exited status=1
Jun 6 16:30:24 server61 systemd: Failed to start /etc/rc.d/rc.local Compatibility.
Jun 6 16:30:24 server61 systemd: Unit rc-local.service entered failed state.
Jun 6 16:30:24 server61 systemd: rc-local.service failed.

rc.local 服务
通过这个日志,我们可以间接推测 rc.local 服务脚本里的执行情况。我们主要目的是推测那个 /usr/local/bin/auto_start_ob.sh 脚本到底有没有跑。它不会有日志记录,但是从前后的脚本记录可以推测。
脚本 auto_start_ob.sh
这个脚本从 OCP 早期版本就有。不同版本的 OCP 其脚本内容可能有些变化。这里展示的是 4.4.0 以后版本的内容。内容太长,我们只看最后 20 行。
[root@server61 ~]# tail -n 20 /usr/local/bin/auto_start_ob.sh
if systemctl list-units -t service | grep -qw ocp_agent; then
# from ocp 420, ocp_agent handles all auto start logic, and service file may not in normal dir
ts_echo "ocp_agent is managed by systemd, skip auto start step"
exit
fi
# 兼容ocp4.2.0、4.2.1找不到service的bug
current_version=$(rpm -q --queryformat '%{VERSION}\n' ocp-agent 2>/dev/null)
if [[ $current_version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && [[ "$(echo -e "$current_version\n4.2.0" | sort -V | head -n1)" == "4.2.0" ]]; then
echo"ocp_agent is managed by systemd, skip auto start step"
exit
fi
wait_until_startup_finished
autostart_obproxy
autostart_ob
autostart_ocp_agent
autostart_obagent
[root@server61 ~]#
脚本大概意思:
- 如果存在服务 ocp_agent ,就退出脚本,不执行后面的逻辑。这是 OCP 4.2.0 后的变化。OCP 自 4.2.0 后通过 ocp_agent 去自动拉起 OB 进程。
- 如果是 OCP 4.2.0/4.2.1 版本,生成的 ocp_agent 服务文件可能在某些系统上通过 systemd 认不到。这里直接看 ocp_agent 软件版本,命中 BUG 也会自动退出。
- 自动拉起 ODP 进程/ OB 进程 / OCP AGENT 进程 / OB AGENT 进程。
如果要判断是不是这个脚本拉起的 OB 进程,可以看脚本的日志文件时间和内容。
[root@server61 ~]# ls -lrth /var/log/ob.autostart.log
-rw-r--r-- 1 root root 172 Jun 6 15:33 /var/log/ob.autostart.log
[root@server61 ~]#
[root@server61 ~]# tail -n 5 /var/log/ob.autostart.log
[2026-01-15 18:36:43.270169] [ocp_agent is managed by systemd, skip auto start step]
[2026-06-06 15:33:18.793270] [ocp_agent is managed by systemd, skip auto start step]
[root@server61 ~]#
[root@server61 ~]# uptime -s
2026-06-06 16:30:19
我这个测试环境还算符合预期,这个日志文件能看到内容和最后修改时间跟重启后的时间比较符合。
如果文件没有内容,排除掉人为清除掉内容外,可以判断为这个脚本没有执行,说明前面执行就报错了。
[root@server61 ~]# uptime -s
2026-06-06 16:30:19
[root@server61 ~]# ps -p `pidof observer` -o pid,user,lstart,etime,cmd
PID USER STARTED ELAPSED CMD
1716 admin Sat Jun 6 16:30:27 2026 30:01 /home/admin/oceanbase/bin/observer
[root@server61 ~]#
OB 进程确实启动了,也确认不是脚本 auto_start_ob.sh 启动的。 我这里测试环境比较顺利,脚本日志里提到了关键字 ocp_agent 。所以,接着看这个服务。
服务 ocp_agent
大概从 OCP 4.2.0 版本开始,OCP 将 ocp_agent 的启动做成了 systemd 服务。
[root@server61 ~]# systemctl list-units -t service |grep ocp_agent
ocp_agent.service loaded active running start ocp_agent
查看一下服务文件内容。
[root@server61 ~]# systemctl cat ocp_agent.service
# /usr/lib/systemd/system/ocp_agent.service
[Unit]
Description=start ocp_agent
After=network.target syslog.target rc-local.target
[Service]
Type=forking
ExecStart=/home/admin/ocp_agent/bin/ocp_agentctl start
ExecStop=/home/admin/ocp_agent/bin/ocp_agentctl stop
ExecReload=/home/admin/ocp_agent/bin/ocp_agentctl restart
RemainAfterExit=yes
KillMode=none
[Install]
WantedBy=multi-user.target
首先这个是一个 systemd 服务文件,不是 target 文件。其次这个服务定义了 ocp_agent 的启动顺序在 network.target syslog.target rc-local.target 之后。
刚开始我还认为 rc-local.target 就是 rc-local.service 。顿时陷入疑惑。 rc.local 脚本逻辑里有判断 ocp_agent 服务。
判断方法如下:
[root@server61 ~]# systemctl list-units -t service |grep -qw ocp_agent
[root@server61 ~]# systemctl list-units -t service |grep -w ocp_agent
ocp_agent.service loaded active running start ocp_agent
如果 rc.local 发现没有 ocp_agent 服务,就会走 auto_start_ob 后面的自动拉起逻辑。这里又说 ocp_agent 服务会在 rc-local 后启动。 这逻辑明显有矛盾。
后来发现 rc-local.target 不等于 rc-local.service 。实际上,根本不存在所谓 rc-local.target 。
[root@server61 ~]# systemctl list-units |grep rc-local
● rc-local.service loaded failed failed /etc/rc.d/rc.local Compatibility
操作系统只有 rc-local.service 。
[root@server61 ~]# systemctl cat rc-local.service | grep . |grep -v '^#'
[Unit]
Description=/etc/rc.d/rc.local Compatibility
ConditionFileIsExecutable=/etc/rc.d/rc.local
After=network.target
[Service]
Type=forking
ExecStart=/etc/rc.d/rc.local start
TimeoutSec=0
RemainAfterExit=yes
在这个服务文件里也提到一个 network.target 。这个可是确实存在的。
[root@server61 ~]# systemctl list-units |grep -w network
network.service loaded active exited LSB: Bring up/down networking
rhel-domainname.service loaded active exited Read and set NIS domainname from /etc/sysconfig/network
rhel-import-state.service loaded active exited Import network configuration from initramfs
network-online.target loaded active active Network is Online
network.target loaded active active Network
所以,服务 ocp_agent 的启动顺序跟 rc-local 服务,没有定义先后关系。那么实际启动顺序就是扫描 units 文件的顺序了。
虽然 ocp_agent 字母排名在前,systemd 启动各个服务并不一定要等待每个服务文件,这取决于 systemd 各个服务文件的具体定义。我们可以通过操作系统日志 /var/log/messages 去确认它们的启动顺序。
grep -Hn "ocp_agent" /var/log/messages |egrep -i "starting|started|failed"
grep -Hn "rc.local" /var/log/messages |egrep -i "starting|started|failed"
这里会查出我多次重启的记录,正好看看顺序。

systemd 服务启动顺序

添加图片注释,不超过 140 字(可选)
这里有 2 次重启主机记录,根据时间不一定能严格看到 2 个服务启动顺序,可以从日志在文件里记录号判断顺序。 服务 ocp_agent 比 rc-local 服务几乎是同时启动,但是确实晚一步。不过,可以确定在 rc.local 执行到 auto_start_ob.sh 脚本的时候, ocp_agent 服务肯定是启动中或已经启动。
再查看 ocp-agent 进程的运行日志。
cd /home/admin/ocp_agent/log
grep "/home/admin/oceanbase/bin/observer" *.log |grep -v POST

ocp_agent 日志
从这个图能看到 2 次重启服务器后 ocp_agent 拉起 OB 进程的日志,时间点跟重启时间都能对上。
所以,结论是服务器重启后 ocp_agent 进程会拉起一次 OB 进程。这个在 OCP 页面里不会看到记录,只能在 mgragent.log 里看到。
如果服务器重启没能自动拉起 OB 进程,大概率是 OB 进程拉起后失败退出了。这个在测似环境也经常见,总有一些外部环境变化导致 OB 进程重启后拉不起来。比如说内存不足、或日志空间满了 或 OB 文件目录权限被改了等等。
问题到此基本得到解释了,查看服务状态,为 “running start” 。
[root@server61 log]# systemctl list-units -t service |grep ocp_agent
ocp_agent.service loaded active running start ocp_agent
此后,如果你在 OCP 里重启主机的 Agent 后,这个 ocp_agent 服务的状态就会有一点变化。

添加图片注释,不超过 140 字(可选)
再次查看服务状态,变成 “active exited” 了。
[root@server61 log]# systemctl list-units -t service |grep ocp_agent
ocp_agent.service loaded active exited start ocp_agent
这个设计的问题在于用主机 SYSTEMD 和 OCP 同时去管理 ocp_agent 进程带来了冲突。
结论
在早期的版本里, OB 服务器重启是需要 DBA 手动拉起 OB 进程的。
估计后来有客户提需求,OCP 才做了自动拉起的逻辑。
先用脚本 auto_start_ob.sh 拉起 OB/ODP/OCPAGENT/OBAGENT 相关进程。
后来又改为通过 ocp_agent 进程去做这个。
其实方案有多种。个人认为更好的方法是将 OB 进程做成 systemd 服务,自动启动更好,这样就不依赖 OCP 产品了。当然,如果把 OB 进程启动做成 systemd 服务,也会面临一样如果跟 OCP 管理冲突了,状态也会有不对。
再往深处说一些,如果把 OB/ODP/OCP AGENT 进程都做成 systemd 服务并且还做成如果服务退出自动拉起,那就不依赖 OCP 了。现有的设计,如果手动将 OCP AGENT 相关进程都 KILL 掉(模拟 AGENT 包括守护进程自己出问题退出),那么这个进程就彻底歇菜了。OCP 的性能采集和 OB 进程自动拉起机制就会彻底失效。当然,还是有解决办法的。

添加图片注释,不超过 140 字(可选)

添加图片注释,不超过 140 字(可选)

添加图片注释,不超过 140 字(可选)
解决办法,就是重启一下(restart 而不是 start) ocp_agent 服务。

添加图片注释,不超过 140 字(可选)

添加图片注释,不超过 140 字(可选)
立即试用 OceanBase 企业版,体验国产数据库能力
更多推荐




所有评论(0)