今天有一个客户反馈OGG不可用,并且数据库间隔性无法连接,环境db oracle 11g, ogg 11, on AIX 。在 Oracle 到 Oracle(或其他支持的目标库)的同步链路中,因为extract某中原因长时间stop, 再下次起动时,在 Oracle GoldenGate 集成模式(Integrated Extract)下,因为 lag 很大 时,依赖 LogMiner 的挖掘进程会不断积压未处理的 redo,导致:
- 内存(Streams Pool / PGA)持续增长
- LogMiner session 持有大量未消费的变更
- 最终可能内存耗尽和数据库实例crash
这个问题本质上不能“直接限制缓存大小”彻底解决,但可以通过多种手段“控制和缓解”。下面给你实战可行方案👇
Integrated Extract 机制:
- Extract 不直接读日志文件
- 而是通过 LogMiner server(数据库内部)
- 未处理完的事务会被缓存(在内存中)
👉 lag 越大 → 未消费 redo 越多 → 内存线性甚至指数增长.
数据库日志
ORA-27301: OS failure message: Not enough space
ORA-27302: failure occurred at: skgpspawn3
Process J000 died, see its trace file
kkjcre1p: unable to spawn jobq slave process
Errors in file /ora/app/oracle/diag/rdbms/anbob/anbob1/trace/anbob1_cjq0_33751804.trc:
Process startup failed, error stack:
Errors in file /ora/app/oracle/diag/rdbms/anbob/anbob1/trace/anbob1_psp0_42991656.trc:
ORA-27300: OS system dependent operation:fork failed with status: 12
ORA-27301: OS failure message: Not enough space
ORA-27302: failure occurred at: skgpspawn3
查看trace
*** 2026-04-02 10:58:55.225
loadavg : 8.46 12.14 10.87
swap info: free_mem = 127.82M rsv = 256.00M
alloc = 15258.36M avail = 65536.00M swap_free = 50277.64M
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
240001 A oracle 12125102 1 0 60 20 edd166590 212040 Aug 25 - 644:41 ora_lmd0_anbob1
*** 2026-04-02 10:58:56.444
Short stack dump:
ksedsts()+240<-ksdxfstk()+44<-ksdxcb()+3432<-sspuser()+116<-__sighandler()<-nrecvmsg()+664<-ssskgxp_rcvmsg()+160<-sskgxp_rcvmsg()+1940<-skgxpfragrcv()+152
<-skgxp_recv_next_fragment()+296<-skgxprusr()+584<-skgxpiwait()+3308<-skgxpwaiti()+2340<-skgxpwait()+164<-ksxpwait()+2348<-ksliwat()+10552<-kslwaitctx()+1
80<-kslwait()+112<-ksxprcv_int()+5116<-ksxprcvimd()+68<-kjctr_rksxp()+312<-kjctrcv()+408<-kjcsrmg()+112<-kjmdm()+8100<-ksbrdp()+2216<-opirip()+1620<-opidr
v()+608<-sou2o()+136<-opimai_real()+188<-ssthrdmain()+276<-main()+204<-__start()+112
检查ogg
GGSCI (yzanbob1) 13> info ext_hx, showch
EXTRACT EXT_HX Last Started 2026-04-02 12:42 Status ABENDED
Checkpoint Lag 12:38:09 (updated 00:28:30 ago)
Log Read Checkpoint Oracle Integrated Redo Logs
2026-04-02 00:19:17
SCN 3251.74759066 (13963013438362)
Current Checkpoint Detail:
Read Checkpoint #1
Oracle Integrated Redo Log
Startup Checkpoint (starting position in the data source):
Timestamp:
SCN: 3237.282384814 (13903091521966)
Recovery Checkpoint (position of oldest unprocessed transaction in the data source):
Timestamp: 2026-04-01 22:06:06.000000
SCN: 3251.47355401 (13962986034697)
Current Checkpoint (position of last record read in the data source):
Timestamp: 2026-04-02 00:19:17.000000
SCN: 3251.74759066 (13963013438362)
Write Checkpoint #1
GGS Log Trail
Current Checkpoint (current write position):
Sequence #: 419932
RBA: 1059
Timestamp: 2026-04-02 12:57:26.288231
Extract Trail: ./dirdat/hx
Trail Type: EXTTRAIL
在 Oracle GoldenGate (OGG) 中,限制 Bounded Recovery (BR) 的内存使用,核心在于调整 CACHEMGR 参数。BR 机制本身是为了防止长事务无限制地占用内存,它会周期性地将未提交事务的状态写入磁盘,而 CACHEMGR 则负责管理这些操作所使用的内存。
使用view report extrace可以查看默认参数
Bounded Recovery Parameter:
BRINTERVAL = 4HOURS
BRDIR = /ogg
CACHEMGR virtual memory values (may have been adjusted)
CACHESIZE: 64G
CACHEPAGEOUTSIZE (normal): 8M
PROCESS VM AVAIL FROM OS (min): 128G
CACHESIZEMAX (strict force to disk): 96G
这段日志表明 OGG 进程被允许占用高达 64GB 的初始内存,并且在极端情况下(长事务堆积)可能膨胀到 96GB 甚至更多。如果系统物理内存不足,这将直接导致操作系统开始使用交换分区(Swap),进而引发系统卡顿甚至 OGG 进程崩溃(OOM),或数据库CRASH。
| 参数 | 当前值 | 含义与风险 |
|---|---|---|
| CACHESIZE | 64G | 初始缓存大小。OGG 启动时就会尝试预留或分配这么多内存来缓存未提交的事务数据。这是导致你内存占用高的直接原因。 |
| PROCESS VM AVAIL FROM OS | 128G | 进程可用虚拟内存。OGG 认为操作系统最多能给它提供 128G 的虚拟内存。 |
| CACHESIZEMAX | 96G | 最大缓存阈值。当未提交数据超过 96G 时,OGG 才会强制将数据写入磁盘(Pageout)。在此之前,它会尽量吃光内存。 |
结论:如果不加干预,只要出现几个长事务,这个进程就会毫不客气地占用几十 GB 的内存。
配置样例
-- 限制 OGG 进程自身的缓存大小(单位 MB),超过则写入磁盘 dirtmp
CACHEMGR CACHESIZE 2GB, CACHESIZEMAX 4GB
配置 CACHEMGR 参数
CACHEMGR 是控制 OGG 进程(如 Extract)内存使用的关键参数。通过设置 CACHESIZE,你可以直接限制 OGG 进程为缓存事务所能使用的最大内存量。
-- 在 Extract 进程的参数文件中配置
CACHEMGR CACHESIZE 1GB
这个配置将 Extract 进程的总缓存大小限制为 1GB。当未提交的事务数据超过此限制时,OGG 会开始将数据交换到磁盘上的临时目录(dirtmp),从而防止内存溢出。
一个典型的包含 BR 和内存限制的 Extract 进程参数文件可能如下所示:
EXTRACT ext1
-- 启用 Bounded Recovery,每30分钟检查并处理一次长事务
TRANLOGOPTIONS BR INTERVAL 30M
-- 限制Extract进程的总缓存大小为512MB
CACHEMGR CACHESIZE 512MB
-- 设置长事务告警,超过1小时的事务会记录在报告文件中
WARNLONGTRANS 1H, CHECKINTERVAL 10M
但是注意,后增加参数,它仅限配置后未来的BR事务,而之前处理in recovery 状态的extract 不生效。
- 如果你使用的是集成模式(Integrated Capture):
- 内存主要由数据库的
STREAMS_POOL_SIZE和MAX_SGA_SIZE控制(如上一轮对话所述)。 CACHEMGR主要用于处理Extract 进程自身无法放入 SGA 的未提交事务数据。- 建议:在集成模式下,
CACHEMGR的限制依然有效且必要,用于防止长事务溢出,但主要的内存控制阀门还是MAX_SGA_SIZE。
- 内存主要由数据库的
- 如果你使用的是经典模式(Classic Capture):
CACHEMGR是最主要的内存控制手段。- 上述日志显示的配置(64G)在经典模式下是非常危险的,必须立即通过
CACHEMGR CACHESIZE进行限制。
配置后发现操作系统内存依旧增长,后面考虑关掉BR, 使用normal recover。
当前环境是AIX,查看使用内存最多的进程
-- 查看内存占用率最高的前 10 个进程:
ps aux | head -1 ; ps aux | sort -rn +4 | head -10
-- 查看物理内存(RSS)占用最大的前 10 个进程:
ps vx | head -1 ; ps vx | grep -v PID | sort -rn +6 | head -10
-- 查看内存使用最多的进程列表:
svmon -P -t 10
关闭BR
-- 在 Extract 进程的参数文件中配置--
BR BROFF
重启ext查看
anon alloc: mmap(MAP_ANON) anon free: munmap
file alloc: mmap(MAP_SHARED) file free: munmap
target directories:
/ogg/BR/EXT_HX.
Bounded Recovery Parameter:
Options = BROFF
BRINTERVAL = 4HOURS
BRDIR = /ogg
关闭BR同样会出现随着恢复时间长,内存使用逐渐增涨,直到耗尽。
限制集成模式的EXTRACT 内存
在 Oracle GoldenGate (OGG) 的集成模式(Integrated Capture)下,限制其因处理大量日志而占用过大内存,核心在于配置数据库的 STREAMS_POOL_SIZE 参数和 OGG 抽取进程的 MAX_SGA_SIZE 参数。
你需要进行两步配置:首先在数据库层面设定一个总的内存池大小,然后在 OGG 进程层面设定其可以从该池中使用的最大内存。
- 配置数据库的 STREAMS_POOL_SIZE
这是 Oracle 数据库 SGA(系统全局区)的一个组件,为集成模式的 OGG 进程提供共享内存。你需要为它设置一个合理的上限。
-- 在数据库中执行,将流池大小设置为 4GB
ALTER SYSTEM SET STREAMS_POOL_SIZE = 4G SCOPE = BOTH;
这个值是所有集成抽取进程共享的总内存池。
- 配置 OGG 抽取进程的 MAX_SGA_SIZE
这是 OGG 抽取进程自身可以使用的最大内存量。它必须小于或等于 STREAMS_POOL_SIZE。MAX_SGA_SIZE 参数的单位是 MB (兆字节)。
-- 在 Extract 进程的参数文件中配置
TRANLOGOPTIONS INTEGRATEDPARAMS (MAX_SGA_SIZE 2048, PARALLELISM 2)
此配置将该抽取进程的最大内存使用量限制为 2048MB(即 2GB),并设置并行度为 2。
重要注意事项
内存分配规则:MAX_SGA_SIZE 的值不能超过 STREAMS_POOL_SIZE。如果未显式设置 STREAMS_POOL_SIZE,OGG 可能会尝试使用共享池(Shared Pool)的 10%(最大 1GB),这可能导致 ORA-04031 内存分配错误。
限制内存使用可以防止 OGG 耗尽系统资源,但如果设置的值过小,可能会在处理大量日志时导致性能下降或进程延迟(Lag)增加。
截止当前把数据库和ogg的内存配置都已配置, 但是抽取近160g日志(集成模式ogg 使用logminer ,在db alert log中可以看到),但是内存使用率依旧增加。
默认情况下,LogMiner 可能会尝试加载所有可用的归档日志。如果 Lag 导致有 1000 个归档日志需要处理时,OGG如果有机制中以配置参数,让LogMiner 分批处理(例如每次 50 个),处理完一批后释放内存,再加载下一批,应该会好一些。
AIX 内存参数
| 参数 | 推荐值 | 说明 |
|---|---|---|
| maxperm% | 90 | 允许文件系统缓存最大占用 90% 内存(受 lru_file_repage 保护)。 |
| minperm% | 5 (或 3) | 内存紧张时,文件缓存最少保留的百分比。设低一点以便释放更多内存给应用。 |
| lru_file_repage | 0 | 最关键参数。确保只置换文件页,保护 Oracle SGA 不被换出。 |
| strict_maxclient | 1 | 确保 maxclient% 限制生效。 |
| maxclient% | 90 | 限制客户端文件缓存的上限。 |
以前建议maxperm% 配置低于20%是为了防止 AIX 的文件系统缓存(File Cache)占用太多内存,导致 Oracle 的 SGA(系统全局区)内存不足。现代 AIX 版本(5.2 ML04+ / 5.3 ML01+ / 6.1+ / 7.x)引入了 lru_file_repage 参数。当将其设置为 0 时,它告诉 AIX 内核:“当内存不足时,只回收文件缓存页面,不要触碰计算页面(即 Oracle SGA),如果设置过低(如 20%),大量的物理内存既没有被 Oracle 使用,也不被文件系统缓存允许使用,造成了极大的资源浪费,所以后来建议把maxperm% 保留90.
但是这个环境已经触发了内存使用率高,而且是文件cache(ogg占用), 那就可以配置低值,限制内存使用。
vmo -a | grep -E "maxperm%|minperm%|lru_file_repage|maxclient%"
vmo -p -o maxclient%=90
vmo -p -o maxperm%=90
注 :maxperm不能低于maxclient
在配置操作系统内存限制后,操作系统的使用率稳定在了75%.没再内存耗尽。
OGG-02077 error (108, no space on directories: error: 108: obj_id: )
限制了内存使用大小,extract跑了几个小时再次crash, 查看日志是这次又把磁盘耗尽了,上面我们有提示如果限制cachemgr 的cachesize,会导致 生成数据到dirtmp, 后我们分析数据库归档,发现问题时间点的归档量比之前增加了几十倍,加上长时间的停止,现在产生的中间数据非常大。错误日志如下

提示ogg-02077 error 108 no space on directories
OGG 所在的文件系统预留的硬盘空间不足,基本上是产生的*.cm 文件占用。 解决方法,把临时文件指定到另一个更大的文件系统。
CACHEMGR CACHEDIRECTORY /opt/dirtmp 10G.
小结:
简单总结就是突然客户的某个操作产生了几十倍的日志量,但是ogg extract 已经crash,并且lag 超过了11小时,启动extrace时,ogg把内存耗尽,数据库实例crash,然后ogg进程再次crash,需要读更多的日志。后面深度限制内存,对于集成模式配置streams pool和max_sga_size(非db参数), 同时建议配置CACHEMGR CACHESIZE, 超过内存限制会写磁盘,同时配置了AIX maxperm 小于20%,才间接限制了内存使用,但是产生的temp又把OGG原规划的文件系统耗尽,后指定ogg cache目录到其他文件系统解决。