srvctl 不能设置服务运行优先级,其启动顺序由Clusterware资源依赖图决定;添加服务必须指定-r或-a参数,修改仅支持实例列表及高可用属性,不支持启动顺序调整。
srvctl 不能直接设置服务的“运行优先级”,它只负责启动、停止、添加、删除和 relocate 服务;服务本身的启动顺序与依赖关系由 oracle clusterware 内部资源依赖图(resource dependency graph)决定,而非 srvctl 的某个参数控制。
srvctl add service 添加新服务时必须指定 -r 或 -a 参数
Oracle RAC 中的服务(service)默认不自动启动,必须显式添加并启用。添加服务时,srvctl add service 要求至少指定一个运行实例列表:
-
-r:指定首选实例(preferred instances),即服务默认在哪些节点上启动 -
-a:指定可用实例(available instances),即故障转移目标节点
例如:
srvctl add service -d orcl -s report_svc -r "orcl1,orcl2" -a "orcl3"
这里 report_svc 会优先在 orcl1 和 orcl2 上运行;若两者都宕机,则 failover 到 orcl3。没指定 -r 会导致命令报错:PRKO-2002 : Invalid argument: -r option is required。
srvctl modify service 无法修改启动顺序或优先级权重
有人误以为用 srvctl modify service 可以调整“服务优先级”,但实际它只支持以下有限变更:
- 增删
-r/-a实例(即重新定义首选/可用节点) - 修改
-l(failover type)、-y(failover method)、-e(failover retries)等高可用行为 - 启用/禁用服务(
-e启用 /-d禁用)
它不接受类似 --priority、-weight 或 --start-order 这类参数。服务在 CRS 中的启动时机取决于其依赖的数据库资源(ora.<db>.db</db>)是否 online,而不是你先执行 srvctl start service 还是后执行。
真正影响服务“启动先后”的是资源依赖和状态检查
Oracle Clusterware 按照资源依赖图启动资源,服务资源(如 ora.orcl.report_svc.svc)默认依赖于对应数据库资源(ora.orcl.db)。这意味着:
- 数据库实例必须先
online,服务才可能启动 - 多个服务之间无显式依赖时,启动顺序不确定(由 CRS 内部调度器决定)
- 若需强制某服务晚于另一服务启动,必须手动添加依赖:
crsctl add resource+crsctl modify resource配置START_DEPENDENCIES,但这属于底层 CRS 操作,绕过了srvctl抽象层,且极易破坏集群稳定性
典型错误现象:srvctl start service -d orcl -s report_svc 返回成功,但 srvctl status service -d orcl -s report_svc 显示 is not running —— 很可能因为依赖的数据库实例尚未完全 open,或该服务被配置为 MANUAL_START=1(需手工启动)。
扩容服务本质是添加服务+分配实例+启动,不是“调优优先级”
所谓“扩容服务”,在 RAC 场景下通常指让服务覆盖更多节点以分担负载或增强容错能力。实操步骤只有三步:
- 确认目标实例已运行:
srvctl status instance -d orcl -i orcl3 - 将新实例加入服务的
-a列表(或提升为-r):srvctl modify service -d orcl -s report_svc -i orcl3 -a - 手动启动(如果服务当前未运行):
srvctl start service -d orcl -s report_svc
注意:srvctl start service 不会自动把服务拉到所有 -a 实例上,它只启动在 -r 列表中的实例;-a 实例仅在 failover 时被动接管。要让服务在新节点上主动运行,必须把该节点加进 -r 并执行 start。
真正容易被忽略的是:服务资源的状态(online/offline)和实例上的实际进程(PMON 是否注册了该 service name)是两回事。即使 srvctl status service 显示 running,也要用 sqlplus / as sysdba 查 SELECT NAME, FAILOVER_TYPE FROM GV$ACTIVE_SERVICES; 确认服务已在对应实例中 active —— 这才是客户端连接能真正路由过去的前提。











