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 故障的排查,核心是区分 “数据库自身问题” 与 “系统环境问题”:
- 若数据库日志显示内部内存上下文异常(如
shared_buffers配置远超物理内存),则优先调整数据库参数; - 若系统日志早于数据库出现内存错误,且存在非数据库高内存进程,则需从系统层面释放资源(如重启异常进程、优化服务配置)。
浙公网安备 33010602011771号