要确认服务实际运行节点,需依次执行srvctl config service查配置、srvctl status service看状态、DBA_SERVICES视图查preferred/available实例及failover_method,并验证监听器注册、实例状态、资源余量和连接分布。

怎么看服务当前运行在哪些节点上
先确认服务实际分布,别只信 srvctl status service 的简略输出。它可能显示服务“online”,但没告诉你具体跑在哪几个实例上,尤其当服务配置了 preferred 和 available 列表时,负载不均或故障转移后状态容易误判。
执行:srvctl config service -d <db_name> -s <service_name> 查配置;再用 srvctl status service -d <db_name> -s <service_name> 看当前状态;最后必须查 SELECT name, preferred_instances, available_instances, failover_method FROM dba_services WHERE name = '<service_name>' —— 注意 preferred_instances 是字符串字段,不是列表,得用 REGEXP_SUBSTR 或手动拆分。
- 如果查询结果里
preferred_instances是rac1,rac2,但srvctl status显示只在rac1运行,说明服务没按预期启动,可能因资源不足、实例未注册或服务依赖失败 - 若
available_instances为空,服务无法 failover,哪怕节点宕机也无法迁移,这种配置等于裸奔 -
failover_method为NONE时,客户端连接断开后不会自动重连,不是“不需要重分配”,而是“根本不会重分配”
查服务连接数和响应延迟是否严重倾斜
服务物理分布在哪不重要,真正影响用户体验的是连接数和响应时间是否集中在单节点。RAC 不会自动把新连接导到空闲节点,全靠客户端连接池或 SCAN listener 负载策略。
在每个节点分别执行:SELECT inst_id, COUNT(*) AS conn_count FROM gv$session WHERE username IS NOT NULL AND service_name = '<service_name>' GROUP BY inst_id;
- 如果某节点
conn_count是其他节点的 3 倍以上,且该节点DB CPU或gc buffer busy acquire等待事件明显升高,就是重分配的明确信号 - 单纯看连接数不够,还得比延迟:查
gv$servicemetric中response_time和service_time,单位是毫秒,注意取 5 分钟滚动窗口(metric_unit = 'Per Second'的是速率,别混) - SCAN listener 默认用轮询(round-robin),但如果客户端用了 TNS connect descriptor 里硬编码了
(INSTANCE_NAME=rac1),那永远连不到 rac2,重分配前得先改应用连接串
检查服务是否绑定到异常实例或已下线节点
有时服务看似“在线”,实则绑在已 shutdown 实例或 CRS 未完全启动的节点上,导致新连接失败或超时。
先确认所有实例状态:crsctl stat res -t | grep ora.<db_name>;再查服务注册情况:lsnrctl services 在每个节点执行,看输出里是否有该服务名及对应实例名;最后查 gv$instance 确认各节点 status 为 OPEN 且 database_status 为 ACTIVE。
- 如果某节点
lsnrctl services输出里没有该服务,但srvctl status service却说它 running,说明监听器没收到服务注册,常见于监听器重启后未触发服务重注册,需手工ALTER SYSTEM REGISTER -
gv$instance中某节点startup_time比其他节点晚几小时,可能是刚恢复,但服务还没自动拉起——RAC 不保证服务随实例自动启动,得看srvctl config service里的management policy是否为AUTO - 服务名在
dba_services里enabled为NO,但srvctl status仍显示 online,这是元数据不一致,必须用srvctl disable service+enable同步
重分配前必须验证节点资源余量
盲目迁移服务到“空闲”节点,可能触发 ORA-00090 或 ORA-4030。所谓空闲,只是 top 看着内存低,不代表 Oracle 实际能再扛一个服务的 PGA/SGA 开销。
重点查三件事:该节点 V$PGASTAT.total PGA allocated 峰值是否接近 _pga_aggregate_limit;gv$memory_dynamic_components 中 DEFAULT buffer cache 当前大小是否已达 db_cache_size 配置上限;以及 free -h 显示的可用内存是否 ≥ 该服务历史峰值 PGA + 1.5GB 安全余量。
- 如果目标节点
total PGA allocated已达_pga_aggregate_limit的 85%,迁入新服务大概率触发ORA-04036,得先调高 limit 或 kill 掉非核心会话 -
db_cache_size设了 8G,但current_size只有 4G,说明 AMM 正在压缩缓存腾空间,此时加服务会让 shared_pool 更紧,引发硬解析风暴 - 别信
free -h的 available 字段——Linux 内核 4.5+ 的这个值包含可回收的 pagecache,Oracle SGA 不吃这部分,得看MemAvailable和Buffers+Cached的差值
srvctl relocate service -d <db_name> -s <service_name> -i <source_inst> -t <target_inst>。但上面四步漏掉任何一环,就不是优化,是制造故障。最常被跳过的,是查 lsnrctl services 和验证目标节点 PGA 余量——这两步花不了两分钟,却能避开 70% 的 relocation 失败。


















