crsctl stop crs 是最贴近真实故障的单节点宕机模拟方式,它逐层停止Oracle Clusterware(含OHAS、CRS、CSS、EVM),触发CSS心跳超时、reboot仲裁和资源自动拉起等完整高可用流程,避免kill -9或强制断电导致的验证缺失。
如何用 crsctl stop crs 安全触发单节点宕机
直接在目标节点执行 crsctl stop crs 是最贴近真实故障的模拟方式,它会逐层停止 oracle clusterware(包括 ohas、crs、css、evm 等),相当于整机断电前的软件级“软崩溃”。注意不要用 shutdown -h now 或强制断电——那会跳过集群心跳检测逻辑,无法验证 css 心跳超时、reboot 仲裁、资源重新拉起等关键路径。
实操建议:
- 确保应用连接使用的是 SCAN 地址 + TNS 中配置
FAILOVER=ON和RETRY_COUNT=3,否则客户端可能卡在旧节点连接上不重试 - 执行前用
crsctl check cluster -all确认集群健康,用srvctl status database -d <db_name>确认数据库当前运行节点 - 在另一节点上提前运行
tail -f $ORACLE_BASE/diag/rdbms/<db_name>/<inst_name>/trace/alert_<inst_name>.log,观察实例是否被自动 relocate 或 shutdown abort 后重启 - 别在主库归档模式下同时停两个节点——可能触发
ORA-00600 [kcrr_arch_dest_unavailable]类错误,干扰判断
为什么不能只靠 kill -9 数据库进程来测试?
kill -9 ora_pmon_<inst> 或 ora_lmon_<inst> 看似快,但绕过了 CRS 的资源生命周期管理。此时 CRS 仍认为实例“活着”,不会触发 failover;只有当 CSS 心跳超时(默认 60 秒)后才判定节点死亡,再启动 relocate 流程——这中间有明显延迟,且日志里会出现大量 CRS-2415: The resource 'ora.<db_name>.db' failed due to an internal error,掩盖真实高可用行为。
更关键的是:这种操作无法验证 RAC 的 instance recovery 能力。真实节点 crash 后,存活实例必须完成对宕机实例 buffer cache 的前滚/回滚,而 kill -9 可能导致 redo 未刷盘或 SCN 不一致,引发 ORA-00600 [kcrfw_post_wait] 等内部错误。
应用端怎么确认切换成功?重点看这三个信号
别只盯着 SELECT INSTANCE_NAME, STATUS FROM V$INSTANCE——那是数据库视角。应用高可用是否生效,得从客户端链路验证:
- 连接池日志中出现
IO Error: Connection reset或TNS-12535: TNS:operation timed out后,3–5 秒内重建新连接并返回结果,说明 JDBC 的oracle.jdbc.replay.enabled=true或 UCP 的FAN通知已生效 - 执行
SELECT SYS_CONTEXT('USERENV', 'INSTANCE') FROM DUAL,切换前后返回值应从原节点名(如rac1)变为新节点名(如rac2) - 检查应用事务连续性:如果测试中插入了一条带
SYSTIMESTAMP的记录,切换后查该记录是否存在、时间戳是否连续(无重复提交或丢失),可暴露 FAN 事件丢失或 replay 未开启的问题
最容易被忽略的配置点:sqlnet.ora 中的 SQLNET.OUTBOUND_CONNECT_TIMEOUT
很多团队测出来“切换慢”或“连接卡住”,根源不在 RAC,而在客户端网络超时设置。默认 SQLNET.OUTBOUND_CONNECT_TIMEOUT=60,意味着应用尝试连原节点失败后,要等满 60 秒才转向下一个地址。实际应设为 5 或 10,配合 TNS 中 CONNECT_TIMEOUT=5 和 TRANSPORT_CONNECT_TIMEOUT=3,才能压测出真实 failover 延迟。
这个值一旦设大,在 RAC 节点反复启停测试中,你会看到应用线程长时间 BLOCK 在 socket connect 阶段,误判为集群响应慢。改完记得重启应用进程——JDBC 驱动只在初始化时读一次 sqlnet.ora。

















