srvctl add service 必须用 oracle 用户执行,否则报 PRCD-1288/PRKH-1014 错误;Failover type/method 需通过 srvctl modify service 显式设置;客户端 SERVICE_NAME 必须精确匹配服务名,不可带域名;TAF 生效需验证 v$session 中 failover_type、failover_method 和 failed_over 字段变化。

srvctl add service 必须用 oracle 用户执行,不能用 grid
直接用 grid 用户运行 srvctl add service 会报 PRCD-1288 和 PRKH-1014 错误,提示权限不足。这是因为服务元数据写入 OCR 时需以 Oracle Home 所有者身份操作。必须切换到 oracle 用户(不是 root 或 grid)再执行命令。
常见错误现象:命令看似成功返回,但后续 srvctl config service 查不到服务,或服务状态为 DISABLED。
- 确认当前用户:运行
id -un,输出必须是oracle - 检查 Oracle Home:
echo $ORACLE_HOME应指向数据库软件路径,而非 Grid Infrastructure 路径 - 若已用
grid执行过,需先用srvctl remove service清理残留,再重试
failover type 和 method 必须显式设置,不能依赖默认值
srvctl add service 默认创建的服务,Failover type 和 Failover method 都是 NONE,即使加了 -P BASIC 也不生效——这个参数只控制连接建立阶段行为,不开启 TAF 故障转移能力。
真正启用 TAF 的关键步骤是用 srvctl modify service 显式设置 -e 和 -m:
-
-e {SESSION|SELECT}:决定故障后是否重放查询结果。OLTP 系统通常选SESSION;报表类场景才考虑SELECT(开销大、需更多内存和 PGA) -
-m {BASIC|PRECONNECT}:影响连接建立时机。BASIC是主流选择;PRECONNECT会双倍消耗连接数和游标资源,仅在极低延迟要求下评估 -
-z 10 -w 5:建议设重试次数(-z)为 10,间隔(-w)为 5 秒,避免瞬时网络抖动误触发
示例命令:srvctl modify service -d woo -s server_taf -e SELECT -m BASIC -z 10 -w 5
客户端 tnsnames.ora 里 SERVICE_NAME 必须匹配服务名,且不能带域名
服务端创建的是 server_taf,客户端 tnsnames.ora 中的 SERVICE_NAME 就必须写成 server_taf,而不是 server_taf.db.example.com 或 server_taf.local。Oracle 名称解析对 SERVICE_NAME 是精确字符串匹配,尾部域名会导致连接使用默认服务(如 orcl),TAF 参数完全不生效。
典型错误配置:
TAFFAIL = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = scan-vip)(PORT = 1521)) (CONNECT_DATA = (SERVICE_NAME = server_taf.example.com)))
正确写法:
TAFFAIL = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = scan-vip)(PORT = 1521)) (CONNECT_DATA = (SERVICE_NAME = server_taf)))
- SCAN VIP 是推荐方式,不要硬编码单节点 VIP
-
FAILOVER=ON在现代 Oracle 版本中默认启用,可不显式写,但加上更明确 - JDBC Thin 驱动不支持 TAF,测试务必用 SQL*Plus 或 OCI 应用
验证 TAF 是否生效,得看 v$session 的 FAILOVER_TYPE 字段
光靠连接不中断不能说明 TAF 生效——可能是客户端重连或 SCAN 自动重路由。真正在后台发生透明切换的标志是会话级字段变化。
连接后立即查:SELECT sid, username, failover_type, failover_method, failed_over FROM v$session WHERE sid = SYS_CONTEXT('USERENV', 'SID');
-
failover_type应为SESSION或SELECT -
failover_method应为BASIC -
failed_over初始为NO;手动 kill 对应实例的 PMON 后,再次查该字段应变为YES,且sid不变
如果 failover_type 是 NULL 或空,说明服务端参数没生效,回退检查 srvctl modify service 是否执行成功、监听是否重载(srvctl stop/start listener 有时必要)。


















