Oracle 19c ASMB 进程 PGA 内存泄漏排查实战 (Bug 38610635)

背景与现象

近期,在巡检 Oracle 19c RAC 环境时,发现数据库服务器的内存使用率异常偏高。通过操作系统层面排查,发现大量 ora_asmb 进程占用了极其夸张的内存(RSS)。

执行 ps aux 查看,结果触目惊心:

# ps aux | head -1; ps aux | grep -v PID | sort -rn -k +4 | head
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
oracle   75164  0.0  4.3 49154508 23104404 ?    Ss   2025 238:58 ora_asmb_xxxxx
oracle   46766  0.0  4.3 45430312 23099328 ?    Ss   2025 226:16 ora_asmb_xxxxx
oracle   46302  0.0  4.3 49139228 23099276 ?    Ss   2025 222:55 ora_asmb_xxxxx
oracle   18630  0.0  4.3 57527836 23099204 ?    Ss   2025 224:25 ora_asmb_xxxxx

可以看到,多个ASMB 进程 RSS 均高达 23GB 左右合计占用90GB以上,这是极不正常的。首先我们先来了解一下ASMB进程是什么。
ASMB(ASM Background Process)是 Oracle 自动存储管理(ASM)架构中的核心通信进程。它的核心职责是充当数据库实例ASM 实例之间的“信息桥梁”和“心跳通道”。

ASMB 进程的核心职责

ASMB 进程在数据库实例启动时便随之运行,它负责建立并维护一条到 ASM 实例的持久连接,确保数据库能持续访问存储在 ASM 磁盘组中的数据文件。具体来说,它主要承担以下工作:

  • 建立通信链路ASMB 进程首先会利用磁盘组名称,从集群同步服务(CSS)获取管理该磁盘组的 ASM 实例连接串,然后建立并维持这条连接。
  • 交换元数据信息:数据库实例需要从 ASM 实例获取区映射(Extent Map) 信息,以便知道数据具体存储在磁盘组的哪个位置。当磁盘组发生维护操作(如添加磁盘)导致区映射变化时,ASM 实例也通过 ASMB 进程将更新通知给数据库实例。
  • 传递 I/O 统计与心跳ASMB 进程会定期向 ASM 实例发送 I/O 统计数据,并传递“心跳”信号,让 ASM 实例知道数据库实例仍然存活且正常运行。
  • 处理物理文件变更:数据库层面涉及物理存储的操作,如创建、删除或重命名数据文件,都需要通过 ASMB 进程与 ASM 实例协调完成。

Grid 用户与 Oracle 用户下 ASMB 进程的区别

要理解这个区别,需要先了解 Oracle 典型的用户分离(User Separation) 安装模式。在这种模式下,不同软件由不同的操作系统用户所有和管理:

  • grid 用户:是 Oracle Grid Infrastructure(包含 ASM 和集群软件)的安装所有者。ASM 实例以 grid 用户身份运行。
  • oracle 用户:是 Oracle Database 软件的安装所有者。所有数据库实例(包括 CDB 和 PDB)都以 oracle 用户身份运行。

因此,你看到的 ora_asmb_* 进程,其操作系统属主直接反映了它服务于哪个实例:

  • 属主为 gridASMB 进程:属于 ASM 实例。它运行在 ASM 实例内部,负责与外部世界(如数据库实例、asmcmd 工具)进行通信。
  • 属主为 oracleASMB 进程:属于数据库实例。它运行在数据库实例内部,负责与为其提供存储的 ASM 实例进行通信。本次出现内存溢出的 ora_asmb_xxxxxx 等进程,正是属于各个 CDB 实例的 ASMB 进程,归属oracle用户。

虽然它们由不同用户运行、分属不同实例,但功能本质上是相同的:都是各自实例与 ASM 进行通信的代理。它们相互配合,oracle 用户的 ASMB 作为“客户端”发起连接和请求,grid 用户的 ASMB 作为“服务端”接收请求并返回存储信息,共同构成了数据库与 ASM 之间的完整通信链路。

🔍 深入排查与定位

Dump ASMB 进程堆内存 (Heap Dump)

为了弄清内存去向,最直接的方法就是使用 oradebug 对 ASMB 进程进行 PGA heap dump,找到内存的使用情况。在生成的 trace 文件中,发现了问题的关键点:

PRIVATE HEAP SUMMARY DUMP
22 GB total:
   22 GB commented, 750 KB permanent
  797 KB free ...
     22 GB,   1 heap:    "callheap       "

Summary of subheaps at depth 1
22 GB total:
   22 GB commented, 102 KB permanent
  745 KB free ...
     22 GB, 328043287 chunks:  "kffmiter                  " 701 KB free held

22GB 的内存中,有 3.28 亿个 kffmiter 内存块!

💥 根本原因 (Root Cause)

结合 Oracle MOS 文档(KB867774)和 Bug 列表,问题真相大白:

命中 Oracle 19c 已知 Bug:Bug 38610635 - PGA Memory Leak In kffmiter Chunks (KI54746)

触发条件:

在 Oracle 19c RAC 环境中,频繁地重复查询 v$asm_filex$kffil 视图(例如 select * from v$asm_file;select * from x$kffil;),会触发 ASMB 进程 PGA 中的 kffmiter chunk 泄漏。

泄漏机制:

ASMB 进程在响应这些查询时,会在 callheap 中分配大量 kffmiter 内存块。但由于 Bug 的存在,这些内存块在使用完毕后没有被正确释放(Freeable 为 0),导致内存持续累积,最终达到 22GB 甚至更高,随着时间的增长,会不断的累积增高。

经过与运维团队核实,确认某监控软件配置了每 1 分钟查询一次 v$asm_file 的监控语句,正是这个高频查询触发了该 Bug。

🛠️ 解决方案与规避措施

针对该问题,我们采取了以下措施:

1. 临时解决方法:调整监控频率(已验证有效)

找到触发问题的监控脚本或监控平台配置,降低对 v$asm_file 视图的查询频率,从 1 分钟改为 1 小时。
重启数据库后,ASMB的使用量恢复了正常,经过一段时间的跟踪,内存使用量增长降低很多。问题得到缓解。

2. 应用官方补丁(根本解决)

从 Oracle MOS 下载并应用补丁 Patch 38610635,或者在后续的 RU 补丁中集成该修复。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐