ITPub博客

首页 > 数据库 > Oracle > OGG Extract 异常停止排查:最后根因落在 RAC 私网分片重组失败

OGG Extract 异常停止排查:最后根因落在 RAC 私网分片重组失败

原创 Oracle 作者:marui 时间:2026-08-17 21:04:23 0 删除 编辑

OGG Extract 异常停止排查:最后根因落在 RAC 私网分片重组失败

Oracle GoldenGate 故障处理案例

大家好,我是睿。

今天处理了一个比较有意思的 Oracle GoldenGate 问题:某生产库的 OGG Extract 进程突然异常停止。

刚开始看现象,很容易把方向放在 OGG 自身,比如参数、trail 文件、归档日志、抽取表 DDL、Redo 读取等。但这次一路排下来,最后发现真正的问题并不在 GoldenGate 本身,而是在 RAC 私网通信链路上。

更具体一点:

OGG 元数据线程查询 GV$INSTANCE

=> RAC 节点间发生跨实例 IPC 通信

=> Oracle IPC 包大于当前私网 MTU ,需要 IP 分片和重组

=> 接收端出现大量 IP 分片重组失败

=> 发送端持续重传,接收端持续 Deferred NAK

=> OGG 内部线程长时间无响应

=> Extract 进程 ABEND

这类问题的迷惑性在于:最终挂掉的是 OGG,但根因不一定在 OGG。DBA 排查时如果只盯着 GoldenGate 日志,很容易停在“重启后恢复”这一层,后面真正的风险点就漏掉了。

一、故障现象

某客户业务系统反馈:Oracle GoldenGate 抽取进程 EXT02 异常停止。

故障发生时,GoldenGate 错误日志中先出现内部线程状态切换超时,随后 Redo 线程对 Stop 命令无响应,最后进程 ABEND。

脱敏后的关键日志如下:

ERROR   OGG-01028  Oracle GoldenGate Capture for Oracle, ext02.prm:

Thread: +++consumer_1 has timed out after waiting for: 600000 seconds,

for other threads to respond to message: SUSPEND,

while changing state from: RUNNING to: SUSPENDED.

 

WARNING OGG-15429  Oracle GoldenGate Capture for Oracle, ext02.prm:

Thread Redo_Thread_2 not responding to command Stop in timely manner.

 

ERROR   OGG-01668  Oracle GoldenGate Capture for Oracle, ext02.prm:

PROCESS ABENDING.

看到这几条日志,基本可以确认一件事:

这个 Extract 不是正常停止,而是内部线程长时间没有响应,最终异常终止。

二、先确认 Extract 运行方式

先看参数文件,确认这个 Extract 到底怎么抽取、抽哪些对象。

参数大概如下:

extract ext02

setenv (ORACLE_SID=<INSTANCE_NAME>)

USERID <OGG_USER>, PASSWORD ****

checkpointsecs 1

tranlogoptions dblogreader

EXTTRAIL ./dirdat/02

ddl include mapped

ddloptions report

table APP_OWNER.BIZ_SYNC_TABLE;

这里有几个信息比较重要:

1. 这是经典抽取模式。

2. 参数中使用了 TRANLOGOPTIONS DBLOGREADER ,也就是通过数据库接口读取 redo。

3. 本进程只同步一张脱敏后的业务表 APP_OWNER.BIZ_SYNC_TABLE 。

4. 开启了 mapped 范围内的 DDL 捕获。

为什么要先看参数?

因为后面排查日志时,需要知道哪些 DDL、哪些对象、哪些数据库会话可能和这个 Extract 相关。否则看到一点异常就往上套,很容易误判。

三、排除同步清单外 DDL 干扰

故障时间段里,GoldenGate 日志中确实出现过一些 DDL。

比如类似下面的统计信息收集语句:

DDL found, operation [ANALYZE TABLE APP_OWNER.LOG_TABLE_1 COMPUTE STATISTICS]

DDL operation excluded [not included by any filter]

 

DDL found, operation [ANALYZE TABLE APP_OWNER.LOG_TABLE_2 COMPUTE STATISTICS]

DDL operation excluded [not included by any filter]

这里要看后半句:

DDL operation excluded [not included by any filter]

意思是这些 DDL 不在当前 Extract 的同步过滤范围内,GoldenGate 已经排除了。

所以这一步先排除一个方向:

故障时间段出现过同步清单外 DDL ,但这些 DDL 不是本次 Extract 异常停止的直接原因。

这一点很关键。生产故障分析里,不是同一时间出现的东西都叫根因。要看它有没有进入当前链路。

四、从 ASH 找到 OGG 卡在哪里

GoldenGate 日志只能告诉我们 Extract 内部线程卡住了,但卡在数据库哪里,还要回到数据库侧看。

我先查故障时间段内的 ASH,重点看非 Idle 等待:

select inst_id,

       qc_instance_id,

       qc_session_id,

       module,

       program,

       sql_id,

       event,

       count(*) cnt

from gv$active_session_history

where sample_time between timestamp '2026-08-17 11:20:00'

                      and timestamp '2026-08-17 12:40:00'

  and inst_id = 2

  and wait_class <> 'Idle'

group by inst_id,

         qc_instance_id,

         qc_session_id,

         module,

         program,

         sql_id,

         event

order by cnt desc;

结果里有一类等待非常突出:

INST_ID        : 2

QC_INSTANCE_ID : 1

QC_SESSION_ID  : 3996

MODULE         : OGG-OCI_META_THREAD

PROGRAM        : oracle@dbnode2 (PPA7)

EVENT          : IPC send completion sync

CNT            : 3664

这里有几个关键点:

5. MODULE 是 OGG-OCI_META_THREAD ,说明它和 GoldenGate 元数据线程有关。

6. PROGRAM 是 oracle@dbnode2 (PPA7),说明节点二上出现了并行从进程。

7. 等待事件是 IPC send completion sync ,这是 RAC 节点间 IPC 通信相关等待。

8. QC_INSTANCE_ID = 1,QC_SESSION_ID = 3996,说明这个节点二的 PPA7 进程,是节点一会话 3996 拉起来的。

这里不要只凭 PPA 进程名去猜它属于谁。真正把它和 OGG 关联起来的,是 ASH 里的 MODULE=OGG-OCI_META_THREAD 以及 QC_SESSION_ID 。

继续看这个等待持续了多久:

select min(sample_time) first_time,

       max(sample_time) last_time,

       count(*) cnt

from gv$active_session_history

where inst_id = 2

  and sample_time between timestamp '2026-08-17 11:20:00'

                      and timestamp '2026-08-17 12:40:00'

  and module = 'OGG-OCI_META_THREAD'

  and program like '%PPA7%'

  and event = 'IPC send completion sync';

结果:

FIRST_TIME : 2026-08-17 11:38:49.271

LAST_TIME  : 2026-08-17 12:39:59.420

CNT        : 3664

也就是说,Extract 真正异常停止之前,数据库侧已经有一段时间在持续等待 RAC IPC 发送完成。

五、节点一和节点二的关系怎么确认?

上一步看到节点二有 PPA 进程等待,接下来要确认节点一的 QC 会话。

根据 ASH 里的 QC_INSTANCE_ID=1、QC_SESSION_ID=3996,查节点一对应会话:

select sample_time,

       inst_id,

       session_id,

       session_serial#,

       module,

       program,

       sql_id,

       top_level_sql_id,

       event,

       wait_class

from gv$active_session_history

where inst_id = 1

  and session_id = 3996

  and sample_time between timestamp '2026-08-17 11:20:00'

                      and timestamp '2026-08-17 12:40:00'

order by sample_time;

关键结果如下:

INST_ID    : 1

SESSION_ID : 3996

SESSION_SERIAL#   : 58011

MODULE     : OGG-OCI_META_THREAD

PROGRAM    : extract@dbnode1 (TNS V1-V3)

EVENT      : PX Deq: Slave Session Stats

这一步把链路串起来了:

节点一 Extract 会话

=> 发起 OGG 元数据查询

=> 节点二 PPA 并行从进程参与查询

=> 节点二向节点一发送 IPC 数据

=> 节点一等待节点二返回状态

所以,此时问题已经不只是 GoldenGate 进程日志里的一个 ABEND,而是 RAC 跨实例通信链路上的等待。

六、这个 OGG 元数据线程到底查了什么?

继续看 ASH 里的上层 SQL_ID,现场值是 50h8yp28ravcx。

查询 SQL 文本:

select sql_text

from v$sql

where sql_id = '50h8yp28ravcx';

得到的 SQL 很简单:

SELECT TO_CHAR(startup_time, 'YYYY-MM-DD HH24:MI:SS')

FROM gv$instance

WHERE inst_id = :1;

再看绑定变量:

select inst_id,

       sql_id,

       name,

       value_string,

       last_captured

from gv$sql_bind_capture

where sql_id = '50h8yp28ravcx';

绑定变量大概是:

NAME  : :1

VALUE : 1

这个 SQL 本身没有复杂业务逻辑,也不是一条大 SQL。

但是它查的是 GV$INSTANCE 。

在 RAC 环境里, GV$ 视图有可能触发跨实例通信。平时这个动作很快,基本没存在感;但如果节点间私网通信异常,一个很简单的元数据查询也可能被卡住。

这就是这次问题里比较容易被忽略的地方:

不是 SQL 复杂导致 OGG 卡住,而是这个简单的 GV$ 查询触发了 RAC 跨实例通信,而通信链路本身出现异常。

七、trace 里看到发送端一直重传

节点二 alert 日志里,在故障前出现了 ORA-10388 ,并指向 PPA 进程 trace 文件。

脱敏后的日志如下:

Errors in file /path/to/diag/rdbms/<db>/<inst2>/trace/<inst2>_ppa7_2319774.trc:

ORA-10388: parallel query server interrupt (failure)

这里的 PPA7 进程和 ASH 中看到的 oracle@dbnode2 (PPA7) 能对上。

继续看这个 PPA trace,里面有几类信息很关键:

Local Address  : <node2_private_ip>:10645

Remote Address : <node1_private_ip>:38735

Peer           : FG: 2949857.KSX.2949857

 

Pending Sends  : Yes

Unacked Sends  : Yes

Pldsz          : 16376

 

RETRANS DMP request sent to peer: <node1_private_ip>:38735

同时,同一消息的重传次数在不断增加:

# XMits: 127360

# XMits: 131008

这里可以得到一个很明确的判断:

节点二 PPA7 进程向节点一发送 IPC 数据包后,长时间收不到正常确认。

Oracle IPCLW 层持续进行重传。

Pending Sends 、 Unacked Sends 、 RETRANS 这几个词放在一起看,方向已经很清楚了:发送端不是没有发,而是发出去后一直没有等到对端正常确认。

八、接收端也能对上 Deferred NAK

只看发送端还不够,最好能在接收端找到对应证据。

节点二 PPA trace 里显示对端进程是:

Peer           : FG: 2949857.KSX.2949857

Remote Address : <node1_private_ip>:38735

其中 2949857 是节点一侧对端 Oracle 进程号。

在节点一查这个进程:

select inst_id,

       addr,

       pid,

       spid,

       program,

       tracefile

from gv$process

where spid = '2949857';

结果可以定位到节点一对端 trace:

INST_ID   : 1

SPID      : 2949857

PROGRAM   : oracle@dbnode1 (TNS V1-V3)

TRACEFILE : /path/to/diag/rdbms/<db>/<inst1>/trace/<inst1>_ora_2949857.trc

检查节点一对端 trace,能看到同一类 IPC 消息的异常确认:

ERRCH K PKT(17262591.1433052174)

 

peer=PPA7.KSXP_ksipc

ospid=2319774

msn=17262591

seq=1433052173

 

Deferred NAK

 

UDP://<node2_private_ip>:10645 -> UDP://<node1_private_ip>:38735

 

Total errch k 138048

Total errch k 140000

PT DMP_REQ at seq 1433052173 from peer <node2_private_ip>:10645

这里发送端和接收端可以互相印证:

节点二 PPA7 端显示 Unacked Sends / RETRANS 。

节点一对端显示 ERRCH K / Deferred NAK 。

问题发生在节点二到节点一的 RAC 私网 IPC 通信确认环节。

这一步很重要。它让问题从 “OGG 好像卡住了”,进一步收敛成了“RAC 私网 IPC 通信确认异常”。

九、为什么会和 MTU、IP 分片有关?

继续看 RAC 私网配置。

检查集群 interconnect:

select inst_id,

       name,

       ip_address,

       is_public,

       source

from gv$cluster_interconnects

order by inst_id, name;

脱敏后的结果:

INST_ID  NAME   IP_ADDRESS           IS_PUBLIC

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

1        bond1  <node1_private_ip>   NO

2        bond1  <node2_private_ip>   NO

两边 RAC 私网都走 bond1 ,当前 MTU 为 1500:

bond1        mtu 1500

slave_nic_1  mtu 1500

slave_nic_2  mtu 1500

而前面 PPA trace 里看到:

Pldsz 16376

这里就有一个关键点:

Oracle IPC 报文载荷约 16KB ,大于当前私网 MTU 1500 。

因此这类通信需要依赖 IP 分片和接收端重组。

正常情况下,分片和重组对上层来说是透明的。但如果网络链路、交换机、驱动、内核参数或瞬时拥塞等因素导致分片丢失、乱序、重组超时,上层看到的就可能是 IPC 包迟迟无法确认。

这也解释了为什么 OGG 日志里看起来是线程不响应,但底层 trace 却是 Unacked Sends 、 RETRANS 、 Deferred NAK 。

十、OSWatcher 证明确实有分片重组失败

接下来检查节点一 OSWatcher 的 netstat 历史数据。

脱敏后的检查思路如下:

for f in dbnode1_netstat_26.08.17.{0900,1000,1100,1200,1300,1400}.dat.gz; do

  zcat "$f" | awk '

    /^IpReasmFails/ {

      if (n==0) first=$2;

      last=$2;

      n++;

    }

    END {

      printf "%s first=%s last=%s delta=%s samples=%s\n",

             FILENAME, first, last, last-first, n;

    }'

done

关键结果如下:

09:00  IpReasmFails delta≈0

10:00  IpReasmFails delta≈0

11:00  IpReasmFails delta=15662

12:00  IpReasmFails delta=35664

13:00  IpReasmFails delta=36831

14:00  IpReasmFails delta=36688

故障前 09:00、10:00 基本没有明显分片重组失败;11:00 开始明显增长,和 ASH 中 OGG 元数据线程开始出现 IPC send completion sync 等待的时间窗口基本吻合。

再看更细的指标:

IpReasmReqds       delta=1129228

IpReasmOKs         delta=134758

IpReasmFails       delta=15662

IpFragOKs          delta=129171

IpFragFails        delta=0

UdpInErrors        delta=0

UdpRcvbufErrors    delta=0

UdpSndbufErrors    delta=0

IpInHdrErrors      delta=0

IpInDiscards       delta=0

下一小时仍然类似:

IpReasmReqds       delta=1296230

IpReasmOKs         delta=126839

IpReasmFails       delta=35664

IpFragOKs          delta=142023

IpFragFails        delta=0

UdpInErrors        delta=0

UdpRcvbufErrors    delta=0

UdpSndbufErrors    delta=0

IpInHdrErrors      delta=0

IpInDiscards       delta=0

这里有个判断点:

不是 UDP 缓冲区错误。

不是 IP 头错误。

不是普通 IP 丢弃。

不是本机发送分片失败。

问题集中体现在接收端 IP 分片重组失败。

也就是说,节点一私网接收方向在故障时间段确实存在大量 IP 分片重组失败。这和前面看到的 RAC IPC 发送端重传、接收端 Deferred NAK 是能对上的。

十一、同步排除几个容易误判的方向

为了避免结论过早,还同步排查了几个常见方向。

1. 归档日志是否异常?

检查故障时间段 Thread 2 的归档日志:

select thread#,

       sequence#,

       first_time,

       next_time,

       name,

       archived,

       status,

       deleted

from v$archived_log

where thread# = 2

  and sequence# between 11208 and 11214

order by sequence#;

结果显示:

Thread 2 sequence 11208 - 11213 均存在

ARCHIVED = YES

STATUS   = A

DELETED  = NO

alert 日志中 Thread 2 在 11211、11212、11213 等 sequence 上 redo 切换和归档也正常。

所以本次不是因为归档日志缺失、删除或归档失败导致 Extract 异常。

2. 主机资源是否打满?

故障时间段两台主机 CPU、I/O、swap、运行队列都比较正常。

脱敏后的统计大概如下:

节点一:

CPU idle 约 99%

iowait 约 0%

swap in/out 0

blocked 0

 

节点二:

CPU idle 约 99%

iowait 约 0%

swap in/out 0

blocked 0

所以也不是主机 CPU、内存、I/O、swap 资源瓶颈。

3. 网卡硬错误或带宽打满?

节点一 RAC 私网网卡在故障时间段检查结果大概如下:

rxerr/s   = 0

txerr/s   = 0

rxdrop/s  = 0

txdrop/s  = 0

rxfifo/s  = 0

txfifo/s  = 0

%ifutil   = 0.04 - 0.07

这说明网卡层没有直接记录硬错误或明显丢包,链路带宽也没有打满。

但是这里要注意:

网卡层没有 rxdrop ,不代表 IP 层没有分片重组失败。

这次真正有价值的证据,是 OSWatcher netstat 里 IpReasmFails 在故障窗口明显增长。

十二、故障时间线

把关键时间点串起来,链路会更清楚。

T1

节点二 PPA7 进程开始在 ASH 中持续出现 IPC send completion sync 等待。

 

T2

Extract 日志出现 OGG-01028 ,内部 consumer 线程状态切换超时。

 

T3

Extract 日志出现 OGG-15429 , Redo_Thread_2 对 Stop 命令无响应。

 

T4

Extract 日志出现 OGG-01668 ,进程异常终止。

 

T5

人工重新启动 Extract ,进程恢复运行。

时间线里最重要的是 T1。

OGG 真正 ABEND 是后面的结果,前面数据库侧的 RAC IPC 等待已经持续了一段时间。

十三、最终结论

先说结论:

本次 OGG Extract 异常停止,根因不是业务表 DDL 、归档缺失、主机资源打满,也不是 GoldenGate 参数本身异常。

 

根因定位为 RAC 私网通信异常,具体表现为节点一私网接收方向存在大量 IP 分片重组失败。

完整链路如下:

OGG Extract 元数据线程查询 GV$INSTANCE

=> RAC 节点间触发跨实例通信

=> 节点二 PPA7 进程向节点一发送 Oracle IPC 包

=> IPC 报文载荷约 16KB ,大于 MTU 1500 ,需要 IP 分片和重组

=> 节点一接收方向出现大量 IpReasmFails

=> 节点二发送端持续 Unacked Sends / RETRANS

=> 节点一对端持续 ERRCH K / Deferred NAK

=> OGG 元数据线程长时间阻塞

=> Extract 内部线程状态切换超时

=> Redo_Thread_2 无响应

=> Extract ABEND

这次比较有代表性的一点是:触发等待的 SQL 本身非常简单,只是查了 GV$INSTANCE 。

但在 RAC 环境里,简单 SQL 只要涉及 GV$ 跨实例访问,就可能触发节点间通信。如果底层私网链路存在分片重组异常,上层就可能表现成 GoldenGate 元数据线程卡住。

十四、后续建议

这类问题如果后续还要继续排查,我建议重点放在 RAC 私网接收方向,而不是只盯着 OGG 进程本身。

建议检查:

9. 节点一 RAC 私网 bond1 当前 active slave 对应交换机端口的 discard、drop、pause frame、CRC、microburst 记录。

10. 节点二到节点一私网链路中间交换设备,是否存在瞬时拥塞、分片丢弃或重组超时。

11. 两节点网卡驱动、固件版本以及系统日志,是否存在网卡 reset、link flap、driver warning。

12. 当前 MTU 为 1500,而 Oracle IPC 大包通信依赖 IP 分片,建议评估 RAC 私网全链路启用 jumbo frame 的可行性。

13. 如果再次发生,建议两节点同时在私网网卡上抓包,确认是否存在分片丢失、分片乱序或重组超时。

另外可以同步关注内核 IP 分片重组相关参数:

sysctl net.ipv4.ipfrag_high_thresh

sysctl net.ipv4.ipfrag_low_thresh

sysctl net.ipv4.ipfrag_time

sysctl net.ipv4.ipfrag_max_dist

这些参数不要看到就直接改。生产环境里,内核参数、MTU、交换机配置、网卡 offload、RAC 私网要求都要一起评估,尤其是 jumbo frame,必须保证全链路一致,否则问题可能更隐蔽。

—— 睿 | Oracle性能优化老司机

专注硬核干货,欢迎一起卷技术!

 


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

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

注册时间:2025-07-21

  • 博文量
    30
  • 访问量
    31696