ITPub博客

首页 > 数据库 > Oracle > Oracle RAC DB 层心跳误走 public 网络故障排查

Oracle RAC DB 层心跳误走 public 网络故障排查

原创 Oracle 作者:marui 时间:2026-09-08 15:58:52 0 删除 编辑

Oracle RAC DB 层心跳误走 public 网络故障排查

大家好,我是睿。

最近处理了一个 RAC 环境里比较典型、也比较容易被误判的问题:数据库实例突然出现大量 Oracle 进程异常终止, alert 日志里连续报出 ORA-27504 、 ORA-27301: No buffer space available 、 ORA-00603 等错误。

刚开始看,很多人第一反应可能是:

是不是主机网络 buffer 不够?

是不是 public 网卡有问题?

是不是 Data Guard 归档连接把 public 打满了?

是不是数据库 process 参数不够?

这些方向都可以查,但这次真正有价值的点不在这里。

这次问题的核心是:

Clusterware / OIFCFG / GPnP 里的 public/private 定义是正确的;

但是数据库实例启动时 GPnP 初始化失败;

DB 层 RAC interconnect 没有按配置走 private 网;

在 cluster_interconnects 未显式指定的情况下,数据库退回 OS dependent software 自动识别;

最终 DB 层 RAC IPC 错误走到了 public 网络。

所以这篇文章想重点讲一个点:

RAC 的网络配置不能只看 oifcfg 。

Clusterware 层配置正确,不代表 DB 层实际使用的一定正确。

本文中的客户名称、数据库名称、主机名、实例名、IP 、路径等均已换成模拟信息;进程号、 incident 编号、错误码、状态码等排查证据保留,方便大家看完整证据链。

为方便阅读,后文统一使用下面这组模拟环境:

数据库名      : payracdb

实例名        : paydb1 / paydb2

主机名        : payracdb01 / payracdb02

public 网络    : 10.66.4.0/24

private 网络   : 172.16.4.0/24

public 网卡    : bond0

private 网卡   : bond1

注意,这里说的 public 网络,是 RAC 里承载主机名、 VIP 、 SCAN 、业务访问、监控等流量的 public 侧网络,不是互联网意义上的公网。

一、故障现象

某客户 RAC 数据库在 2026-08-27 14:58 左右出现大量 Oracle 进程异常终止。

alert 日志中的关键错误如下:

Thu Aug 27 14:58:39 2026

skgxpvfynet: mtype: 61 process 87219 failed because of a resource problem in the OS.

The OS has most likely run out of buffers (rval: 4)

Errors in file /u01/app/oracle/diag/rdbms/payracdb/paydb1/trace/paydb1_ora_87219.trc (incident=176124):

ORA-00603: ORACLE server session terminated by fatal error

ORA-27504: IPC error creating OSD context

ORA-27300: OS system dependent operation:sendmsg failed with status: 105

ORA-27301: OS failure message: No buffer space available

ORA-27302: failure occurred at: sskgxpsnd2

这几条错误放在一起看,方向其实已经比较明确:

ORA-27504   指向 RAC IPC 创建 OSD 上下文失败。

ORA-27300   指向 OS 层系统调用失败,这里是 sendmsg 。

ORA-27301   给出 OS 层错误信息: No buffer space available 。

status 105 在这里对应网络发送相关的 buffer 不足。

也就是说,直接故障点不是普通 SQL 报错,而是数据库内部 RAC IPC 创建或发送失败。

这次分析也要先把边界说清楚:

这不是普通客户端连接问题。

这不是 Data Guard 归档连接本身的问题。

重点是数据库实例内部 RAC IPC / interconnect 通信异常。

二、先看 trace : IPC socket 绑定到了哪里?

alert 已经给出了 trace 文件,继续看这个 trace 。

关键内容如下:

SKGXPVFYNET: Socket self-test could not verify successful transmission of 32768 bytes (mtype 61).

The network is required to support UDP protocol sends of this size.

Socket is bound to 10.66.4.43.

 

ORA-27504: IPC error creating OSD context

ORA-27300: OS system dependent operation:sendmsg failed with status: 105

ORA-27301: OS failure message: No buffer space available

这里最关键的是这一句:

Socket is bound to 10.66.4.43.

SKGXPVFYNET 是 Oracle RAC IPC 网络自检。它在做 UDP 发送自检时,发现 32768 字节发送无法成功确认,随后报出 ORA-27504 和 No buffer space available 。

但比错误本身更关键的是:这个 IPC socket 绑定的地址是 10.66.4.43 。

如果 10.66.4.43 是 public 地址,那问题就不只是 “OS buffer 不够 ” 这么简单了,而是 DB 层 RAC IPC 很可能走错了网络。

同一时间段,多个 trace 都出现了相同现象:

paydb1_ora_87219.trc  2026-08-27 14:58:39  Socket is bound to 10.66.4.43

paydb1_ora_87241.trc  2026-08-27 14:58:43  Socket is bound to 10.66.4.43

paydb1_ora_87227.trc  2026-08-27 14:58:46  Socket is bound to 10.66.4.43

paydb1_ora_87149.trc  2026-08-27 14:58:47  Socket is bound to 10.66.4.43

paydb1_ora_87328.trc  2026-08-27 14:58:59  Socket is bound to 10.66.4.43

对采集到的 trace 做统计:

Socket is bound to 10.66.4.43   : 206 处

Socket is bound to 172.16.4.43  : 未发现

Socket is bound to 172.16.4.44  : 未发现

这个证据很直接:

故障时失败的 DB 层 RAC IPC socket ,绑定在 public 地址上,而不是 private interconnect 地址上。

三、确认 10.66.4.43 是 public 地址

接下来要确认 10.66.4.43 到底是什么网段。

主机解析关系如下:

10.66.4.43   payracdb01

10.66.4.44   payracdb02

10.66.4.45   payracdb01-vip

10.66.4.46   payracdb02-vip

 

172.16.4.43  payracdb01-priv

172.16.4.44  payracdb02-priv

网卡信息如下:

bond0: 10.66.4.43/24

bond1: 172.16.4.43/24

bond 组成关系如下:

bond0:

  Currently Active Slave: ens10f0

  Slave Interface: ens10f0

  Slave Interface: ens11f0

 

bond1:

  Currently Active Slave: ens10f1

  Slave Interface: ens10f1

  Slave Interface: ens11f1

由此可以确认:

10.66.4.43    属于 bond0 public 网络

172.16.4.43   属于 bond1 private interconnect 网络

所以,trace 里出现的 Socket is bound to 10.66.4.43 ,说明 DB 层 RAC IPC 确实绑定到了 public 地址。

四、Clusterware 配置是不是写错了?

既然 DB 层 IPC 走到了 public ,下一步自然要看 Clusterware 网络配置是不是错了。

先看 oifcfg getif :

bond0  10.66.4.0   global  public

bond1  172.16.4.0  global  cluster_interconnect

再看 GPnP profile :

IP="10.66.4.0"   Adapter="bond0" Use="public"

IP="172.16.4.0"  Adapter="bond1" Use="cluster_interconnect"

这两个结果说明:

Clusterware / OIFCFG / GPnP 静态配置里, public/private 定义是正确的。

正确的 private interconnect 应该使用 bond1 / 172.16.4.0 网段。

这一步很容易让人困惑:

既然 oifcfg 里 bond1 已经是 cluster_interconnect ,

为什么数据库实际还会走 bond0 public ?

原因是,RAC 网络要分层看。

oifcfg 看到的是 Clusterware 层网络定义;但数据库实例启动后, DB 层实际使用哪个 interconnect ,还要看数据库进程是否正常取得并采用了这些信息。

所以不能只看 oifcfg getif 就下结论。

五、DB 层实际 interconnect 已经走到 bond0

继续在数据库里查 gv$cluster_interconnects :

select inst_id,

       name,

       ip_address,

       is_public,

       source

from gv$cluster_interconnects

order by inst_id, name;

实际结果如下:

INST_ID  NAME   IP_ADDRESS  SOURCE

-------  -----  ----------  ---------------------

1        bond0  10.66.4.43  OS dependent software

2        bond0  10.66.4.44  OS dependent software

这里有两个关键点。

第一,两个实例 DB 层 interconnect 都显示为 bond0 / 10.66.4.x 。

第二, source = OS dependent software 。

这个结果说明:

当前 DB 层 RAC interconnect 地址,不是从正常的 Clusterware / GPnP private interconnect 配置中采用过来的;

而是由数据库退回 OS dependent software 自动识别出来的。

而 OS 自动识别的结果,恰好选到了 public 地址。

所以到这里,问题已经比较明确:

Clusterware 层配置没错;

DB 层实际选择错了;

两个实例的 DB 层 RAC IPC 实际使用了 bond0 public 网络。

六、为什么 DB 层没有采用 private interconnect ?

关键证据来自实例启动日志。

故障后实例启动时,alert 日志出现如下信息:

Thu Aug 27 15:34:28 2026

Starting ORACLE instance (normal)

 

2026-08-27 15:34:32.326:

[USER(30548)]CRS-2316:Fatal error: cannot initialize GPnP, CLSGPNP_ERR (Generic GPnP error).

kggpnpInit: failed to init gpnp

WARNING: No cluster interconnect has been specified. Depending on

the communication driver configured Oracle cluster traffic

may be directed to the public interface of this machine.

 

Cluster communication is configured to use the following interface(s) for this instance

  10.66.4.43

cluster interconnect IPC version:Oracle UDP/IP (generic)

对应 trace 里也能看到:

2026-08-27 15:34:32.237: failed to initialize skgp context

2026-08-27 15:34:32.299: Cannot set primary certkey for id=1

2026-08-27 15:34:32.299: Cannot set certkey for id=1

2026-08-27 15:34:32.299: Error getting certkeys.

2026-08-27 15:34:32.299: clsgpnp_Init init failed. Error: CLSGPNP_ERR

2026-08-27 15:34:32.326: Fatal error: cannot initialize GPnP

kggpnpInit: failed to init gpnp

另外,另一个实例历史启动日志中也出现过同类信息:

2023-05-21 19:13:12.803:

[USER(24005)]CRS-2316:Fatal error: cannot initialize GPnP, CLSGPNP_ERR (Generic GPnP error).

kggpnpInit: failed to init gpnp

WARNING: No cluster interconnect has been specified.

...

may be directed to the public interface of this machine.

这几行日志非常关键。

要特别注意,不要把问题简单归结为:

cluster_interconnects 参数为空,所以出问题。

这个说法不准确。

cluster_interconnects 参数默认可以为空。在正常情况下,数据库实例可以从 Clusterware / GPnP 中取得 interconnect 信息,并使用 private 网络。

真正异常的地方是:

数据库实例启动阶段 GPnP 初始化失败;

DB 层没有正常取得或采用 Clusterware / GPnP 中的 private interconnect 信息;

在 cluster_interconnects 未显式指定的情况下, DB 层退回 OS dependent software 自动识别;

自动识别结果选到了 public 地址 10.66.4.x 。

这就是这次 DB 层心跳和 RAC IPC 走 public 的根本原因。

七、故障链路还原

把前面的证据串起来,链路大概是这样:

Clusterware / OIFCFG 中 private interconnect 配置为 bond1 / 172.16.4.0

  ->

数据库实例启动阶段出现 GPnP 初始化失败

CRS-2316 / kggpnpInit failed to init gpnp

  ->

DB 层没有正常采用 Clusterware / GPnP 中的 private interconnect 配置

  ->

cluster_interconnects 未显式指定时, DB 层由 OS dependent software 自动识别 interconnect

  ->

OS 自动识别结果选择到 public 地址 10.66.4.43 / 10.66.4.44

  ->

两个实例 DB 层 RAC IPC 实际使用 bond0 public 网络

  ->

2026-08-27 14:58 左右, Oracle 进程创建 RAC IPC OSD 上下文

  ->

SKGXPVFYNET 在 10.66.4.43 上执行 UDP 32768 字节发送自检

  ->

OS sendmsg 返回 105 / No buffer space available

  ->

Oracle 报 ORA-27504 、 ORA-27301 、 ORA-00603 ,多个进程异常

这条链路里,最容易被忽略的是中间这段:

oifcfg 配置正确

不等于

DB 层 gv$cluster_interconnects 使用正确

生产排查 RAC 网络问题时,我一般会把这两个都查一遍。

八、这算 public 网卡故障吗?

这里要谨慎。

本次故障和 DB 层 RAC IPC 错误使用 public 网络有直接关系,依据是:

1. 故障 trace 明确显示出错 IPC socket 绑定在 10.66.4.43 。

2. 10.66.4.43 是 bond0 public 地址。

3. 两个实例 DB 层 interconnect 都是 bond0 / 10.66.4.x 。

4. public 网络同时承载主机 public 、 VIP 、 SCAN 、 Data Guard 归档连接、监控、日志采集等流量,本来就不应该作为 RAC DB IPC interconnect 使用。

但当前证据没有显示 bond0 存在物理层故障,比如:

CRC

drop

网卡 down

链路中断

所以更准确的表述应该是:

DB 层 RAC IPC 错误使用 public 网络,并在该 public-bound IPC socket 上发生 OS buffer 资源不足,导致 IPC 创建失败。

九、怎么处理?

这次 oifcfg 和 GPnP profile 中 public/private 定义本身是正确的,所以不建议优先改 Clusterware 网络定义。

更合适的处理思路是:

在数据库 SPFILE 中按实例显式设置 cluster_interconnects ,

固定 DB 层 RAC IPC 使用 private interconnect 地址,

避免继续依赖 OS dependent software 自动识别。

修改前先备份参数:

create pfile='/home/oracle/init_payracdb_before_interconnect_fix.ora' from spfile;

先确认实例名和主机名:

select inst_id,

       instance_name,

       host_name

from gv$instance

order by inst_id;

按实例设置 cluster_interconnects :

alter system set cluster_interconnects='172.16.4.43' scope=spfile sid='paydb1';

alter system set cluster_interconnects='172.16.4.44' scope=spfile sid='paydb2';

这里一定要注意:

不要使用 sid='*' 。

因为两个实例对应的 private IP 不同,如果写成 sid='*' ,反而可能把两个实例都指到同一个地址。

另外, cluster_interconnects 不是动态参数,需要重启实例后生效。

重启方式按现场维护窗口和高可用要求处理,可以滚动重启,也可以按变更窗口统一重启。示例命令如下:

shutdown immediate

startup

十、修改后怎么验证?

修改后第一件事,还是回到 DB 层看实际结果,而不是只看参数有没有写进去。

检查 gv$cluster_interconnects :

set linesize 200

col name for a20

col ip_address for a20

col source for a40

 

select inst_id,

       name,

       ip_address,

       is_public,

       source

from gv$cluster_interconnects

order by inst_id, name;

期望结果:

INST_ID  NAME   IP_ADDRESS

-------  -----  -----------

1        bond1  172.16.4.43

2        bond1  172.16.4.44

第二,看两个实例启动 alert 日志:

Cluster communication is configured to use the following interface(s) for this instance

期望显示:

paydb1 -> 172.16.4.43

paydb2 -> 172.16.4.44

同时确认不再出现下面这些信息:

CRS-2316: Fatal error: cannot initialize GPnP

kggpnpInit: failed to init gpnp

WARNING: No cluster interconnect has been specified

may be directed to the public interface of this machine

第三,继续观察故障类错误是否消失:

ORA-27504: IPC error creating OSD context

ORA-27301: OS failure message: No buffer space available

SKGXPVFYNET: Socket self-test could not verify successful transmission

Socket is bound to 10.66.4.43

Socket is bound to 10.66.4.44

如果后续 trace 里不再出现 public 地址绑定,同时 DB 层 interconnect 已稳定显示 private 地址,这个问题才算真正闭环。

十一、这次排查的几个提醒

最后总结几个我觉得值得记下来的点。

第一, cluster_interconnects 为空不一定是问题。

很多 RAC 环境这个参数默认就是空的。正常情况下,数据库可以通过 Clusterware / GPnP 获取 private interconnect 信息。真正要查的是: DB 层实际用了什么地址。

第二, oifcfg getif 正确,不代表 DB 层一定正确。

这次 oifcfg 和 GPnP profile 里配置都对,但是 gv$cluster_interconnects 已经显示 DB 层实际使用了 bond0 public 地址。所以 RAC 网络排查不能只停在 Clusterware 层。

第三,看到 No buffer space available 不要只从 OS buffer 参数入手。

OS 层报 buffer 不足是结果之一,但如果 socket 本身就绑定到了不该使用的 public 网络,那优先要纠正 RAC IPC 走错网络的问题。

第四,public 网络不是不能通,而是不应该承载 DB 层 RAC IPC 。

public 网络通常还承载业务访问、 VIP 、 SCAN 、 Data Guard 、监控、日志采集等流量。 RAC interconnect 对延迟、稳定性和隔离性更敏感,应该固定走 private interconnect 。

第五,生产处理前一定要先备份 SPFILE 参数。

尤其是按实例设置 cluster_interconnects 这类参数,一定要保留修改前 pfile 。万一写错地址或维护窗口内需要回退,手里要有原始配置。

这次问题表面上看是 Oracle 进程异常退出, alert 里报 ORA-27504 和 No buffer space available ;但真正把链路串起来后,核心其实是 DB 层 RAC IPC 没有走 private interconnect ,而是误走了 public 网络。

很多 RAC 故障就是这样:第一眼看到的是数据库报错,第二眼看到的是 OS 报错,真正的答案可能藏在 “ 数据库实际选择了哪块网卡 ” 这里。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70047128/viewspace-3181856/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
要得到你想要的某样东西,最可靠的办法是让你自己配得上它。

注册时间:2025-07-21

  • 博文量
    30
  • 访问量
    31693