srvctl add service 必须指定 -preferred(-r)或 -available(-a),否则报 PRKO-2002;-r 参数为必需,用于声明首选实例,如 -r "CDB11,CDB12",漏写即失败。
srvctl add service 必须指定 -preferred 或 -available,否则报 PRKO-2002
在 oracle 21c rac 中为 pdb 添加服务时,srvctl add service 命令不接受“无实例绑定”的配置。漏掉 -preferred(首选实例)或 -available(可用实例),会直接失败并抛出 prko-2002 : invalid argument: -r option is required——注意这里提示的是 -r,因为 -preferred 在底层对应参数名就是 -r。
常见错误写法:srvctl add service -db CDB1 -pdb SALES_PDB -s sales_svc -pdb SALES_PDB(只写了 -pdb,没写 -preferred)
- 必须显式声明该服务跑在哪几个节点上:
-preferred "CDB11,CDB12"表示默认只在这两个实例运行 - 若需故障转移能力,额外加
-available "CDB13",当首选全宕时才切过去 -
-pdb参数从 12.2 起才支持,21c 可用;但若省略,服务会注册到 CDB 层,无法被 PDB 感知 - 命令执行用户必须是
oracle,且当前 shell 已正确设置 ORACLE_HOME / GRID_HOME
为什么 srvctl start service 显示成功,但 lsnrctl status 看不到服务?
最常见原因是:数据库实例还没完全 open,或者服务依赖的 PDB 没打开。srvctl 启动服务只是向 Clusterware 提交请求,不保证监听器立刻注册成功。
检查顺序要严格按层级来:
- 先确认数据库资源状态:
srvctl status database -d CDB1,输出应为Instance CDB11 is running on node host1 - 再查 PDB 是否在所有实例 open:
SELECT inst_id, name, open_mode FROM gv$pdbs WHERE name = 'SALES_PDB',任意inst_id行为MOUNTED都不行 - 确保已执行:
ALTER PLUGGABLE DATABASE SALES_PDB OPEN INSTANCES=ALL(缺INSTANCES=ALL是高频遗漏点) - 最后验证监听器注册:
lsnrctl status | grep -A 3 SALES_PDB,看到Service "SALES_PDB" has 2 instance(s)才算真正就绪
修改服务运行节点:srvctl modify service 只能调实例列表,不能调优先级
srvctl modify service 不支持调整“启动顺序”“权重”或“优先级”,它只允许变更服务与实例的绑定关系和高可用行为。
比如要把服务从 CDB11 迁移到 CDB12 作为首选:
- 执行:
srvctl modify service -d CDB1 -s SALES_PDB -preferred "CDB12" -available "CDB11" - 然后 reload:
srvctl stop service -d CDB1 -s SALES_PDB && srvctl start service -d CDB1 -s SALES_PDB - 不能用
-weight、--priority等不存在的参数,Oracle 不识别,会报PRKO-2002或SRVCTL-1001 - 如果想让服务“晚一点启动”,得改 CRS 依赖图(用
crsctl modify resource),但这属于绕过 srvctl 的底层操作,生产环境慎用
tnsnames.ora 里连不上 PDB?重点核对 network_name 和大小写
PDB 服务连接必须走 SERVICE_NAME,不能用 SID;而客户端能否连上,取决于 tnsnames.ora 中写的 SERVICE_NAME 是否和数据库内 V$SERVICES.NAME 完全一致——包括大小写、域名后缀。
典型错误链:
- 你执行了
srvctl add service -s sales_pdb,但忘了查network_name - 执行
SELECT name, network_name FROM dba_services WHERE name = 'sales_pdb',发现network_name实际是SALES_PDB(全大写) - tnsnames.ora 写成
SERVICE_NAME = sales_pdb→ 连接时返回ORA-12514: TNS:listener does not currently know of service requested - 正确写法:
SERVICE_NAME = SALES_PDB,且确保 SCAN 地址指向集群 DNS 解析正确的 SCAN VIP
这个大小写问题在 Linux + Oracle 组合下极隐蔽,因为文件系统不敏感,但监听器和服务注册是严格区分大小写的。











