KingbaseES V8 集群主库 OOM 故障排查

在 KingbaseES 集群运维中,主库 OOM(内存溢出)是严重故障,不仅会导致数据库服务中断,还可能因核心文件(core)生成增加恢复复杂度。本文基于 KingbaseES V8R3 集群真实案例,从故障现象入手,通过 “数据库日志分析→系统状态验证→根因定位” 的流程,拆解 OOM 故障的排查逻辑,并总结通用的内存故障处理方法论,帮助运维人员快速解决类似问题。

一、故障背景与核心现象

明确故障发生的环境与关键表现,是后续分析的基础。本次案例的核心信息如下:
 
  • 集群环境:KingbaseES V8R3 主从集群,主库部署在华为云虚拟机,配置 64GB 物理内存,无 swap 分区(内存不足时无法通过 swap 临时缓解)。
  • 故障现象:主库突发 OOM 故障,生成 core 文件,数据库服务中断;重启数据库时,出现动态库加载失败(如 libss1.so.1.0.0 无法映射内存),无法正常启动。
  • 初步疑问:是数据库自身内存配置过高(如 shared_buffers 超限),还是系统级内存被其他进程占用导致?

二、故障分析:从数据库到系统的分层排查

OOM 故障不能只关注数据库本身,需按 “数据库日志→系统日志→资源占用” 的顺序分层验证,避免遗漏系统级根因。

1. 第一步:数据库日志分析(排除自身配置问题)

首先查看数据库相关日志,判断是否因参数配置或内部内存泄漏导致 OOM。

(1)sys_log 内存分配日志

sys_log 记录了数据库内部内存上下文(MemoryContext)的使用情况,核心关注 “已使用内存” 是否异常:
 
CacheMemoryContext: 516096 total in 6 blocks; 159416 free (0 chunks); 356680 used
  SYS_OPCLASS_AM_NAME_NSP_INDEX: 1024 total in 1 blocks; 24 free (0 chunks); 1000 used
  SYS_STATISTIC_RELID_ATT_INH_INDEX: 1024 total in 1 blocks; 24 free (0 chunks); 1000 used
  ...
 
  • 分析结论:各内存上下文(如 CacheMemoryContext、表索引缓存)的已使用内存均在正常范围(总使用仅数百 KB),无单个模块内存溢出的迹象,初步排除数据库内部内存泄漏或参数配置过高的问题。

(2)recovery.log 启动故障日志

主库 OOM 后重启,recovery.log 记录了恢复过程的错误:
 
/home/kingbase/cluster/kes_cluster/db/bin/network_rewind.sh:行272:/usr/bin/unlink:无法分配内存
could not delete the file "/home/kingbase/cluster/kes_cluster/db/data/rw_status_file", stop the database
sys_ctl: error while loading shared libraries: libss1.so.1.0.0: cannot map zero-fill pages
 
 
  • 关键信息:unlink 命令(删除文件)提示 “无法分配内存”,动态库 libss1.so.1.0.0 无法映射内存。
  • 分析结论:这些错误并非数据库恢复逻辑问题,而是系统级内存耗尽—— 即使执行简单的文件操作或动态库加载,都无法获取足够内存,说明故障根源在系统层面。

2. 第二步:系统日志分析(定位全局内存问题)

系统 message 日志(/var/log/messages)是排查系统级内存问题的核心,需重点关注故障时间点前后的进程内存异常。

(1)系统进程早期内存异常

早在数据库 OOM(15:48)前 40 分钟(15:00 左右),系统其他进程已出现内存不足症状:
 
Jul 18 15:00:11 db0001 com.deepin.api.XEventMonitor[20792]: /usr/lib/deepin-daemon/dde-session-daemon: error while loading shared libraries: libgdk-3.so.0: failed to map segment from shared object
Jul 18 15:02:59 db0001 com.deepin.dde.desktop[20792]: /usr/bin/dde-desktop: error while loading shared libraries: libQt5XdgIconLoader.so.3: failed to map segment from shared object
Jul 18 15:03:21 db0001 com.deepin.dde.desktop[20792]: out of memory
 
 
  • 关键信息:桌面进程(dde-desktop)、守护进程(dde-session-daemon)均出现 “动态库无法映射”“内存不足” 错误,且时间早于数据库 OOM。
  • 分析结论:数据库 OOM 是系统全局内存耗尽的结果,而非原因—— 系统内存已被其他进程占用,导致所有进程(包括数据库)无法分配内存。

(2)kingbase 进程栈错误(确认 OOM 最终表现)

15:48 时,kingbase 进程触发内核级内存错误,最终 OOM:
 
Jul 18 15:48:45 db0001 kernel: [56884604.361326] CPU: 24 PID: 27697 Comm: kingbase Tainted: G      D           4.19.0-arm64-server #3017
Jul 18 15:48:45 db0001 kernel: [56884604.365007] sp : ffff80013f5f7bf0
Jul 18 15:48:45 db0001 kernel: [56884604.376760] Call trace:
Jul 18 15:48:45 db0001 kernel: [56884604.377024]  do_last+0x44/0x848
Jul 18 15:48:45 db0001 kernel: [56884604.377365]  path_openat+0x60/0x238
 
  • 分析结论:kingbase 进程在执行文件操作(path_openat)时触发内存分配失败,内核打印栈跟踪信息,确认 OOM 故障。

3. 第三步:系统资源检查(定位内存占用元凶)

结合日志线索,通过命令排查系统内存占用情况,找到消耗内存的进程:

(1)查看整体内存使用

# 查看内存使用(无 swap 分区)
free -m
# 输出示例:
#              total        used        free      shared  buff/cache   available
# Mem:          64420       62000        1200          0        1220         800
 
 
  • 关键信息:64GB 内存中,已使用内存达 62GB,可用内存仅 800MB,内存使用率超过 96%。

(2)排查高内存占用进程

# 按内存使用率排序,查看前 10 个进程
top -b -n 1 | head -n 20 | grep -E "PID|%MEM"
# 或用 ps 命令精确查询
ps -eo pid,ppid,%mem,%cpu,cmd --sort=-%mem | head -10
 
  • 排查结果:发现杀毒软件进程(如 antivirusd)占用内存达 15GB,且存在多个子进程,总内存占用超过 20GB,是导致系统内存耗尽的直接原因。

三、问题解决与验证

针对 “杀毒软件过度占用内存” 的根因,采取以下措施:

1. 临时恢复:重启杀毒软件释放内存

 
# 停止杀毒软件服务(具体命令需结合杀毒软件类型,如某国产杀毒软件)
systemctl stop antivirus-service
# 验证内存释放情况
free -m
# 输出示例(内存恢复正常):
#              total        used        free      shared  buff/cache   available
# Mem:          64420       38000       24200          0        2220       24800
 
 
  • 效果:内存使用率从 96% 降至 59%,可用内存恢复至 24GB。

2. 数据库重启验证

 
# 清理 OOM 残留的 PID 文件(避免“进程已存在”错误)
rm -f /data/kingbase/v8r3/data/postmaster.pid
# 启动主库
sys_ctl start -D /data/kingbase/v8r3/data -L /var/log/kingbase_start.log
# 验证启动状态
sys_ctl status -D /data/kingbase/v8r3/data
# 成功输出:sys_ctl: server is running (PID: 32100)
 
  • 关键验证:数据库启动过程无动态库加载错误,recovery.log 无内存分配失败信息,主从同步正常,故障彻底解决。

3. 长期优化:避免杀毒软件内存泄漏

  • 升级杀毒软件至最新版本,修复内存泄漏 bug;
  • 配置杀毒软件 “内存限制”(如最大占用不超过 4GB);
  • 添加数据库目录(/data/kingbase)到杀毒软件白名单,避免频繁扫描导致内存升高。

四、通用 KingbaseES OOM 排查流程(可复用)

本次案例的核心经验是 “不能只盯数据库,需结合系统全局分析”。总结以下 5 步排查流程,可应对 90% 以上的 OOM 故障:
 
步骤排查内容核心命令 / 操作排查目标
1 数据库内存日志 查看 sys_log 中的 MemoryContext 占用 排除数据库内部内存泄漏(如单个上下文使用超 GB)
2 数据库参数验证 检查 kingbase.conf
 
shared_buffers(建议 ≤ 物理内存 40%)
 
max_connections(避免连接过多占内存)
确认内存参数未超过系统承载能力
3 系统内存整体检查 free -m(查看总内存 / 可用内存)
 
vmstat 1 5(查看内存交换情况)
判断是否为系统级内存耗尽
4 高内存进程定位 top -o %MEM(按内存排序进程)
 
ps -eo pid,%mem,cmd --sort=-%mem
找到占用内存的非数据库进程(如杀毒软件、其他服务)
5 连接数与会话内存 数据库内执行:
 
select state,count(*) from pg_stat_activity group by state;
 
select sessid,pg_size_pretty(sum(totalsize)) from gs_session_memory_detail group by sessid order by sum(totalsize) desc limit 10;(需 MogDB/openGauss 兼容视图)
排除 “大量活跃连接 / 大会话占用内存” 问题

五、总结

KingbaseES 主库 OOM 故障的排查,核心是区分 “数据库自身问题” 与 “系统环境问题”:
 
  1. 若数据库日志显示内部内存上下文异常(如 shared_buffers 配置远超物理内存),则优先调整数据库参数;
  2. 若系统日志早于数据库出现内存错误,且存在非数据库高内存进程,则需从系统层面释放资源(如重启异常进程、优化服务配置)。

posted on 2025-10-22 10:22  数据与人文  阅读(13)  评论(0)    收藏  举报