---
title: smaps_rollup 信息导致 OBServer 进程内存分配操作卡顿-OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于smaps_rollup 信息导致 OBServer 进程内存分配操作卡顿相关的常见问题和使用技巧，帮助您快速解决smaps_rollup 信息导致 OBServer 进程内存分配操作卡顿的难题。
image: https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*OSPzQ6GUQF4AAAAAQHAAAAgAeiGDAQ/original
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

划线反馈

# smaps_rollup 信息导致 OBServer 进程内存分配操作卡顿

更新时间：2026-08-25 02:41

## 问题现象

在某客户的性能回归测试环境上，发现升级 OBServer 小版本后业务基准压测指标普遍出现了 10%~20% 的性能回退，同时在 observer.log 中出现大量的 `OB_MALLOC COST TOO MUCH TIME` 告警，该告警的含义是 observer 进程的实时内存分配操作过于缓慢：

```javascript
[378757]OB_MALLOC COST TOO MUCH TIME, cost_time=119982, tenant_id=1, label=SqlExecutor, ctx_id=0, prio=0, size=245760,
[374291]OB_MALLOC COST TOO MUCH TIME, cost_time=887726, tenant_id=1001, label=CoStack, ctx_id=8, prio=1, size=638016, owner: ObMalloc, click_count: 2, time dist:[ALLOC_BLOCK#start=0, ALLOC_BLOCK#end=0], seq:[0, 1]
[374291]OB_MALLOC COST TOO MUCH TIME, cost_time=213386, tenant_id=1001, label=CoStack, ctx_id=8, prio=1, size=638208, owner: ALLOC_BLOCK, click_count: 1, time dist:[ALLOC_CHUNK_END=213381], seq:[0]
[374291]OB_MALLOC COST TOO MUCH TIME, cost_time=336210, tenant_id=1001, label=CoStack, ctx_id=8, prio=1, size=638016, owner: ObMalloc, click_count: 2, time dist:[ALLOC_BLOCK#start=0, ALLOC_BLOCK#end=213495], seq:[0, 1]
[386798]OB_MALLOC COST TOO MUCH TIME, cost_time=178243, tenant_id=1001, label=[T]MemoryContext, ctx_id=0, prio=0, size=24,
[373889]OB_MALLOC COST TOO MUCH TIME, cost_time=193289, tenant_id=500, label=CoStack, ctx_id=8, prio=1, size=638208, owner: ALLOC_BLOCK, click_count: 1, time dist:[ALLOC_CHUNK_END=193286], seq:[0]
[373889]OB_MALLOC COST TOO MUCH TIME, cost_time=193920, tenant_id=500, label=CoStack, ctx_id=8, prio=1, size=638016, owner: ObMalloc, click_count: 2, time dist:[ALLOC_BLOCK#start=0, ALLOC_BLOCK#end=193377], seq:[0, 1]
[378757]OB_MALLOC COST TOO MUCH TIME, cost_time=1054873, tenant_id=1, label=SqlExecutor, ctx_id=0, prio=0, size=245760,
[386803]OB_MALLOC COST TOO MUCH TIME, cost_time=527476, tenant_id=500, label=[T]MemoryContext, ctx_id=0, prio=0, size=24,
[386802]OB_MALLOC COST TOO MUCH TIME, cost_time=767643, tenant_id=1001, label=[T]MemoryContext, ctx_id=0, prio=0, size=24,
[374064]OB_MALLOC COST TOO MUCH TIME, cost_time=209409, tenant_id=1, label=CoStack, ctx_id=8, prio=1, size=638016, owner: ObMalloc, click_count: 2, time dist:[ALLOC_BLOCK#start=0, ALLOC_BLOCK#end=1], seq:[0, 1]
[374064]OB_MALLOC COST TOO MUCH TIME, cost_time=338136, tenant_id=1, label=CoStack, ctx_id=8, prio=1, size=638016, owner: ObMalloc, click_count: 2, time dist:[ALLOC_BLOCK#start=1, ALLOC_BLOCK#end=75734], seq:[0, 1]

```

进一步监控后发现，该告警的打印频率约为 30s/次。

## 问题原因

### 排查过程

依次排查 OBServer 服务器上的可疑服务和可疑进程后发现，将运行在该服务器上的 Prometheus 监控工具的 process_exporter 监控进程停掉后，observer.log 日志中 `OB_MALLOC COST TOO MUCH TIME` 告警不再打印。

### 根因分析

`/proc/<pid>/smaps_rollup` 是 Linux 内核提供的一个虚拟文件，用于以聚合形式展示进程的内存使用统计。它从 Linux 4.14 开始引入，位于每个进程的 `/proc/<pid>/` 目录下，是 `/proc/<pid>/smaps` 文件的汇总版本。

该文件的主要作用如下：

- **快速获取进程整体内存统计**：相比 `/proc/<pid>/smaps` 会列出进程的每一个内存映射区域（如代码段、数据段、共享库、堆、栈等）的详细信息，smaps_rollup 将这些信息按字段相加汇总，直接给出整个进程的汇总值。
 - **减少解析开销**：在监控工具（如 top、ps、smem）或自动化脚本中，读取一个文件就能得到关键内存指标，无需遍历成百上千个映射条目。

当 Prometheus 监控工具的 process_exporter 监控进程读取 `/proc/<pid>/smaps_rollup` 时，内核需要：

1. 获取目标进程的内存描述符（`mm_struct`）的读锁（`mmap_lock`）
 2. 遍历进程的所有虚拟内存区域（VMA），累加各区域的 RSS、PSS 等统计数据
 3. 释放锁，将聚合结果返回给用户

为了保证整个遍历过程的正确性，内核会持有该进程的内存管理锁（通常是 `mmap_lock`，即 `mmap_sem`）。该锁用于保护进程的 VMA 列表和页表。在锁被持有时，目标进程的任何需要修改 VMA 或页表的操作（如 `mmap()`、`munmap()`、`mprotect()`、缺页异常等）都会被阻塞，直到锁释放。

因此，取决于当前 observer 进程的虚拟内存（VIRT）和常驻物理内存（RSS）的大小，读取虚拟文件 `/proc/<pid>/smaps_rollup` 的耗时及相应的持锁时间为几毫秒到几秒不等。

在客户出现性能回退问题的环境上，`cat /proc/$(pgrep observer)/smaps_rollup` 命令耗时在 5s 以上，因此会导致 observer 进程的内存分配操作发生卡顿，进而影响到上层业务的 TPS/QPS。

### 测试验证

单节点 Oceanbase 集群当前的 observer 进程内存占用情况如下：

在左侧 Terminal 窗口手工执行命令 `time cat /proc/$(pgrep observer)/smaps_rollup`，同时在右侧 Terminal 窗口对该 OBServer 进程进行 sysbench 压测。

同一时刻对应 OBServer 节点上的 observer.log 日志中出现大量的 `OB_MALLOC COST TOO MUCH TIME` 告警。

## 问题的风险及影响

压测时 observer 内存分配操作过于缓慢，导致业务压测指标偏低。

## 适用版本

- Linux 4.14 及以上内核
 - OBServer 所有版本

## 解决方法

**方法一**：彻底关闭并禁用 Prometheus 监控工具的 process_exporter 监控服务。

**方法二**：继续开启 Prometheus 监控工具的 process_exporter 监控服务，同时在监控对象中跳过收集 `/proc/<pid>/smaps_rollup`。

上一篇

[SQLSTAT 会在用户执行过多 Command 的场景下占用过多内存的原因和解决方法](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000004510194)

下一篇

[OceanBase 数据库高可用](https://www.oceanbase.com/knowledge-base/oceanbase-database-20000000079) ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
