注册
DM8 内存管理学习总结
培训园地/ 文章详情 /

DM8 内存管理学习总结

DM_052010 2026/08/25 152 0 0

第一部分:DM8 内存基础

本文内容按以下思路进行编写:

DM8 有哪些内存 → 这些内存如何分类 → 内存池如何工作 → Buffer 如何工作 → SQL 执行时又会产生哪些运行时内存 → 最后用参数把整个体系串起来。

目录

第一部分 DM8 内存基础

  1. DM8 内存总体架构
  2. DM8 内存资源分类
  3. 内存池
  4. Buffer
  5. SQL 运行时内存
  6. DM8 内存参数
  7. DM8 内存结构总图
  8. 知识总结

1. DM8 内存总体架构

1.1 为什么 DM8 需要内存管理体系

数据库运行过程中会频繁进行内存申请和释放。如果每一次内存申请都直接调用操作系统,不仅会增加 OS 调用次数,也不利于数据库自身对内存资源进行统一管理。

因此,DM8 对内部内存对象进行了封装和统一管理,其主要目的包括:

  1. 减少操作系统调用次数;
  2. 通过自有的内存对象定义,更方便了解资源使用情况;
  3. 避免内存泄漏和内存越界问题。

1.2 从 OS 到 DM8

从最宏观的角度,可以把 DM8 内存理解为:
DM内存体系宏观图.png

从资源角度看,达梦数据库向操作系统申请的内存主要有两类对象:

内存池(Memory Pool)和缓冲区(Buffer)。

这两类内存对象彼此独立。数据库启动时按照参数策略进行初始化;Buffer 的资源占用相对固定,并通过内部淘汰算法管理;内存池则可能随着运行情况自动扩展,内部没有 Buffer 那样的淘汰机制。

这是整个 DM8 内存体系中最重要的第一层分类


2. DM8 内存资源分类

2.1 Memory Pool 与 Buffer

以下为内存池和缓冲区的主要区别:

  • 内存池:动态内存资源,可按需扩展

  • 缓冲区:缓存数据,有淘汰机制

两者解决的问题不同。

Memory Pool

核心是:管理数据库运行过程中各种动态内存对象。 关注内存对象管理。

例如:

  • Session 内存;
  • VM 内存;
  • SORT 运行内存;
  • HASH 运行内存;
  • 其他数据库内部运行时对象。

工作原理:申请-->使用-->扩展-->释放

Buffer

核心是:缓存数据库运行过程中频繁访问的数据和相关信息。 关注数据缓存管理。

例如:

  • 数据页;
  • 日志;
  • 数据字典;
  • SQL 缓存等。

工作原理:磁盘内容-->Buffer-->访问-->长期保留 / 淘汰


3. 内存池

3.1 什么是内存池

内存池可以理解为:

DM8 为了统一管理动态内存资源而建立的一种内存管理对象。

每一个内存池都有三个非常重要的属性:

Original Size 初始大小 Extend Size 扩展大小 Target Size 目标大小

其中:

TARGET_SIZE >= ORIGINAL_SIZE

当内存池创建时,DM8 首先申请 ORIGINAL_SIZE 的内存;当池内可用资源不足时,则按照 EXTEND_SIZE 继续申请。

3.2 内存池的生命周期

可以把内存池的基本工作过程理解成:
内存池生命周期.png

内存池不是一次申请完就永远不变,而是具有"初始 → 扩展 → 使用 → 释放"的生命周期。

3.3 Original / Extend / Target 参数

属性 含义 学习关键词
Original Size 创建时申请的大小 起步多少
Extend Size 不够时每次扩展多少 一次扩多少
Target Size 希望维持的目标大小 希望保持多少

需要注意的是,TARGET_SIZE 并不能简单理解成"最大值"。

TARGET_SIZE=0 时,不限制扩展;对于共享内存池,即使 TARGET_SIZE 不为 0,也不限制其扩展,TARGET_SIZE 更多用于提示系统在空闲时尽快将内存占用释放到目标值以下。

因此:

Target 更接近"目标容量",而不是绝对的硬上限。

3.4 内存池的两大类别

DM8 内存池从生命周期和资源共享方式来看,可以重点理解为:
内存池共享私有分类.png

3.5 共享池 Shared Pool

共享池是 DM8 内存体系中的核心资源池。主要可以理解为:
共享池分类.png

其中比较重要的共享池对象包括:

  • SHARE POOL
  • BACKUP POOL
  • TRX
  • DICT CACHE
  • SQL Cache 等。

3.6 SHARE POOL 的作用:池外扩展

共享池除了自身为各种资源提供内存外,还有一个非常重要的作用:

为其他已经达到目标大小的内存池继续扩展提供内存。

这个过程可以用下图直观表示:
池外拓展.png

3.7 其他共享池对象(BACKUP POOL / TRX Pool)

BACKUP POOL

BACKUP POOL 是:

系统正常内存申请失败时使用的备用内存池。

其基本逻辑:正常申请失败后用于应急申请

MEMORY_BAK_POOL 用于控制系统备份内存池大小;正常内存申请失败时,可以从备用池申请。

TRX Pool

TRX 是共享池体系中的一个内存池,其特点是:

  • 初始大小:16K;
  • 扩展大小:64K;
  • 没有限制;
  • 默认存在 WORKER_THREADS + 2 个池;
  • 用于会话上的 purge 事务相关初始内存。

TRX Pool:与事务相关的内存池。

3.8 DICT CACHE

DICT CACHE 即数据字典缓存。它负责存储部分数据字典信息,由 DICT_BUF_SIZE 控制。

DICT CACHE:实际在共享池中。

3.9 共享池分片

共享池逻辑上可以看作一个统一的共享内存池。

但在高并发情况下,如果所有线程都访问同一个池:
共享池竞争.png
容易产生临界区竞争。

因此 DM8 可以对共享池进行物理分片:
共享池分片.png

分片数量由 MEMORY_N_POOLS 控制。

共享池分片有利于降低临界区资源冲突;分片数量过多则可能产生额外空间消耗。

3.10 MPOOL 与 HEAP(内存使用方式)

DM8 内部存在不同的内存使用方式,其中重要的包括:

  • OS_MALLOC / OS_FREE
  • HEAP
  • MPOOL
DM 内部内存管理方式 │ ├── OS_MALLOC / OS_FREE │ ├── HEAP │ └── 从预先申请的堆空间中分配 │ └── MPOOL └── 伙伴算法 + 扩展

OS_MALLOC / OS_FREE

直接调用操作系统的 malloc 等函数申请和释放内存。

HEAP

先申请一片内存,后续从这块堆空间中继续分配;HEAP 也支持扩展。

MPOOL

通过伙伴算法先申请一片大小为 2^n 的初始内存,不够时继续扩展。


4. Buffer

4.1 Buffer 是什么

Buffer 与 Memory Pool 最大的区别是:

Buffer 主要用于缓存数据库内容,而不是单纯保存动态内存对象。

其中数据缓冲区用于存储:

数据页从磁盘读取之后,以及写入磁盘之前的数据。

4.2 Data Buffer

Data Buffer 是最核心的 Buffer。其基本作用:

缓存数据库的数据页,减少磁盘访问,提高数据库访问性能。

可以理解为:
BUFFER分类图.png

4.3 NORMAL Buffer

NORMAL 可以理解为:

普通数据页的默认缓存区域。

主要服务于普通的数据访问。

4.4 KEEP Buffer

KEEP 的定位是:

为需要长期/重点保留的数据提供专用缓冲区。

对应参数:KEEP

4.5 RECYCLE Buffer

RECYCLE 的定位是:

用于不希望长期占用普通 Buffer 的数据。

对应参数:RECYCLE

这样可以将不同类型的数据访问隔离开:

普通数据 热点/希望保留的数据 不希望长期占用普通缓存的数据 ↓ ↓ ↓ NORMAL KEEP RECYCLE

4.6 FAST Buffer

FAST Buffer 是 Data Buffer 体系中的特殊区域。主要用于存储高频访问的"热页"或回滚页,以加速特定类型的访问。

相关参数:FAST_POOL_PAGES,它以页数为单位控制快速缓冲区大小。

同时,ENABLE_FREQROOTS 等参数与 FAST POOL 管理方式相关。

面向快速访问场景的数据缓冲区域。

4.7 Buffer Pools 分片

与共享内存池类似,Data Buffer 也是共享资源。

DM8 通过 BUFFER_POOLS 将大的系统缓冲区划分成多个小缓冲区:
BUFFER分片.png

其核心目的:

降低 Buffer 访问时的 mutex 竞争,提高并发性能。

BUFFER_POOLS 将大的系统缓冲区分割成多个部分,使不同数据页尽可能落到不同子池,从而降低竞争。

4.8 Log Buffer

Log Buffer 用于:

缓存日志。

基本过程:事务操作-->产生日志-->Log Buffer-->日志文件

其中:

  • RLOG_BUF_SIZE:控制日志缓冲;
  • RLOG_POOL_SIZE:控制日志缓冲区总大小。

所有线程的日志缓冲区总大小不能超过 RLOG_POOL_SIZE,日志缓冲区所占内存从共享内存池中申请。

这里需要特别说明:Buffer 虽然在资源分类上与 Memory Pool 独立,但某些 Buffer 的具体资源来源仍然可能与共享池有关。

4.9 Dictionary Buffer

Dictionary Buffer:

缓存部分数据字典信息。

核心参数:DICT_BUF_SIZE

4.10 SQL Buffer

SQL Buffer 主要用于 SQL 相关缓存。

SQL │ ├── SQL 信息 ├── 执行相关缓存 └── SQL Cache

其资源扩展可以使用共享池提供的资源。

共享池的使用量可能因为 SQL Cache Management 等模块扩展而明显增加。


5. SQL 运行时内存

5.1 什么是 SQL Runtime

可以先用一句话定义:

SQL Runtime 是 SQL 执行过程中产生的运行时内存资源。

与 Buffer 的区别:

名称 Buffer SQL Runtime
周期 偏长期 偏临时
功能 偏缓存 偏执行
对象 数据库内容 当前 SQL

在SQL执行中会有以下几种运行时内存
SQL运行时内存.png

5.2 Session Runtime Memory

当客户端连接数据库时,DM8 会为 Session 创建相应的会话内存池。

生命周期:

客户端连接-->Session 创建-->创建 Session 内存池-->保存 Session 信息 -->连接断开-->Session 内存池销毁-->内存归还上层内存管理器

Session Pool 是连接生命周期级别的内存。

PARALLEL_POLICY=0同时MPP_INI=0为私有内存池,否则就是共享内存池;

5.3 VM Runtime Memory

执行 SQL 时:

Session-->SQL-->创建 VM 内存池-->保存 SQL 执行信息-->SQL 执行-->执行完成-->VM 内存池销毁-->内存归还 Session Pool

SQL 执行时会从会话池申请 VM 内存池;SQL 执行完成后,VM 内存池销毁,内存归还会话池。

VM 更接近 SQL 执行级别,而 Session Pool 更接近连接级别。

5.4 SORT Runtime Memory

当 SQL 需要排序时,例如:

ORDER BY GROUP BY DISTINCT

会产生排序内存需求。

逻辑过程:

SQL-->需要排序-->SORT Buffer-->执行排序-->SQL 完成-->释放

DM8 中排序缓冲区:

  • 使用时申请;
  • 使用完毕立即销毁;
  • SORT_BUF_SIZE 控制排序缓冲区大小;
  • 其资源来源于共享池。

因此要特别记住:

SORT Buffer 是运行时内存,不是像 Data Buffer 那样长期缓存数据页。

补充说明:由于排序缓冲区是运行时按需申请、用完即毁的,因此在 V$MEM_POOL 中通常不会看到一个名为 SORT_POOL 的持久内存池,其内存使用体现在共享池的瞬时增长中。如需验证,可以在执行大规模排序操作的同时监控共享池的大小变化。

5.5 HASH Runtime Memory

HASH Buffer 用于:HASH JOIN。

其特点:

  • 使用时申请;
  • 使用完成立即销毁;
  • HJ_BUF_SIZE 控制 HASH JOIN 数据缓存大小;
  • 其空间来自 VM → MEMOBJ
  • VM_MEM_HEAP 决定 VM MEMOBJ 的空间来源方式。

因此 HASH 可以表示成:

SQL-->HASH JOIN-->VM-->MEMOBJ-->HASH Buffer-->SQL结束-->释放

5.6 VM_MEM_HEAP 的特殊性

VM_MEM_HEAP 有三种模式:

数值 含义
0 创建内存池,空间来自 OS
1 创建堆,空间来自共享池
2 同时创建内存池和堆

SQL Runtime 并不是简单地对应某一个固定内存池,而是存在不同的底层内存资源获取方式。

5.7 SQL Runtime 三大核心

Runtime 对象 作用 生命周期
Session Pool 保存 Session 信息 Session 生命周期
VM Pool 保存 SQL 执行信息 SQL 生命周期
SORT 排序运行内存 当前排序操作
HASH HASH JOIN 运行内存 当前 HASH 操作

6. DM8 内存参数

本节按照内存对象 → 参数 的映射关系来展开

6.1 全局内存边界参数

首先是整个数据库实例层面的参数。

MAX_OS_MEMORY

表示:

DM 服务器能够使用的最大内存占操作系统物理内存的百分比。

默认值为 100,建议一般情况下不要随意修改。

6.2 Shared Pool 参数

共享池核心参数:

参数 含义
MEMORY_POOL 共享内存池初始大小
MEMORY_EXTENT_SIZE 共享池每次扩展大小
MEMORY_TARGET 共享池目标大小
MEMORY_N_POOLS 共享池分片数量
MEMORY_BAK_POOL 备用内存池大小

其中 MEMORY_EXTENT_SIZE 的单位为 MB,默认值为 32 MB。

6.3 Buffer 参数

Data Buffer

BUFFER

系统缓冲区大小。默认值为 8000 MB,一般可用物理内存的 60%~80% 作为推荐参考。

BUFFER_POOLS

系统缓冲区分区数量:

BUFFER │ ├── Pool 0 ├── Pool 1 ├── Pool 2 └── ...

每个分区大小:

BUFFER / BUFFER_POOLS
FAST_POOL_PAGES

控制 FAST Buffer 页数。

KEEP

KEEP Buffer 大小。

RECYCLE

RECYCLE Buffer 大小。

6.4 Log Buffer 参数

RLOG_BUF_SIZE RLOG_POOL_SIZE

关系:

Log Buffer │ ┌───────┴────────┐ │ │ RLOG_BUF_SIZE RLOG_POOL_SIZE 单路日志缓冲 总日志缓冲

所有线程的日志缓冲区总大小不能超过 RLOG_POOL_SIZE

6.5 Dictionary Buffer 参数

DICT_BUF_SIZE │ ▼ DICT CACHE │ ▼ 部分数据字典信息

6.6 SQL Cache 参数

SQL Cache 相关资源主要与 SQL 缓存、执行相关缓存管理有关。

重点关注:CACHE_POOL_SIZE

SQL Cache 等模块的扩展可能进一步消耗共享池资源。

6.7 SQL Runtime 参数

SQL Runtime 最重要的几个参数:

其中:

参数 对象 作用
VM_POOL_SIZE VM VM Pool 大小相关
VM_POOL_TARGET VM VM Pool 目标大小
VM_MEM_HEAP VM VM 内存来源方式
SORT_BUF_SIZE SORT 单会话排序缓冲区大小(会话级参数)
SORT_BUF_GLOBAL_SIZE SORT 全局排序内存上限(系统级参数)
HJ_BUF_SIZE HASH 单会话 HASH JOIN 缓冲区大小(会话级参数)
HJ_BUF_GLOBAL_SIZE HASH 全局 HASH 内存上限(系统级参数)

6.8 内存管理辅助参数

还有几个参数虽然不是"某块业务内存的大小",但属于内存管理体系的重要参数。

MEMORY_LEAK_CHECK

用于开启内存泄漏检测:

0 → 不开启 1 → 开启

开启后,系统会对内存分配进行登记,并可通过 V$MEM_REGINFO 查看。

MEMORY_MAGIC_CHECK

用于内存池校验:

0 → 不校验 1 → 普通校验 2 → 增强校验

6.9 参数体系总表

内存体系 核心对象 主要参数
全局 DM 可用内存范围 MAX_OS_MEMORY
Shared Pool 共享内存池 MEMORY_POOL
Shared Pool 扩展 MEMORY_EXTENT_SIZE
Shared Pool 目标 MEMORY_TARGET
Shared Pool 分片 MEMORY_N_POOLS
Backup 备用池 MEMORY_BAK_POOL
Data Buffer 系统缓冲区 BUFFER
Data Buffer 分片 BUFFER_POOLS
FAST 快速缓冲区 FAST_POOL_PAGES
KEEP KEEP Buffer KEEP
RECYCLE RECYCLE Buffer RECYCLE
Log 日志缓冲区 RLOG_BUF_SIZE / RLOG_POOL_SIZE
Dictionary 字典缓存 DICT_BUF_SIZE
SQL SQL Cache CACHE_POOL_SIZE
Session Session Pool SESS_POOL_SIZE / SESS_POOL_TARGET
VM VM Pool VM_POOL_SIZE / VM_POOL_TARGET
VM VM 内存来源 VM_MEM_HEAP
SORT 排序运行内存 SORT_BUF_SIZE / SORT_BUF_GLOBAL_SIZE
HASH HASH 运行内存 HJ_BUF_SIZE / HJ_BUF_GLOBAL_SIZE
管理 内存泄漏检查 MEMORY_LEAK_CHECK
管理 内存校验 MEMORY_MAGIC_CHECK

详细的参数说明可参考DM8 DBA系统管理员手册


7. DM8 内存结构总图

DM内存结构总图.png

:上图中 Memory Pool 下的 "Shared Pool" 与 "Runtime/Private" 为管理维度的并列关系,不代表其资源来源完全独立。

7.1 按资源来源角度划分

如果从资源分配角度观察,图还可以进一步简化:
DM内存结构总图按资源来源.png

这里要特别强调:

"内存对象分类"和"内存资源来源"是两个不同维度。

例如:

SORT │ └── 属于 SQL Runtime │ └── SORT_BUF_SIZE │ └── 资源来源:SHARE POOL
LOG │ └── 属于 Buffer │ └── LOG_BUF_SIZE │ └── 资源来源:SHARE POOL

又例如:

HASH │ └── 属于 SQL Runtime │ └── HJ_BUF_SIZE │ └── VM → MEMOBJ │ └── 具体来源受 VM_MEM_HEAP 控制

8. 知识总结

DM8 内存首先分成两大类

DM8 Memory ├── Memory Pool └── Buffer

这是最重要的一级分类。

Memory Pool 负责动态内存对象

Memory Pool ├── Shared Pool ├── Runtime / Private Pool ├── Session ├── VM ├── TRX ├── DICT ├── LOG └── SQL Cache 等

它的核心特征是:

可以根据运行情况扩展,没有 Buffer 那样的数据页淘汰机制。

Buffer 负责缓存

Buffer ├── Data Buffer │ ├── NORMAL │ ├── KEEP │ ├── RECYCLE │ └── FAST ├── Log Buffer ├── Dictionary Buffer └── SQL Buffer

核心特征:

缓存数据库内容,并通过相应的缓存管理/淘汰机制提高访问效率。

SQL Runtime 负责 SQL 执行过程中的临时内存

SQL Runtime ├── Session ├── VM ├── SORT └── HASH

核心特征:

生命周期通常与 Session 或 SQL/具体操作相关,用完释放。

参数小结

参数分类图:
内存相关参数分类.png

常见内存对象小结

常见内存对象的划分

内存对象 功能分类 资源管理 实际来源
数据缓冲区 缓冲区 独立缓冲区资源 OS
SQL 缓冲区 缓冲区 缓冲区 共享池
字典缓冲区 缓冲区 缓冲区 共享池
日志缓冲区 缓冲区 缓冲区 共享池
Session Pool 内存池 运行时内存池 根据配置决定
VM Pool 内存池 运行时内存池 根据 VM 机制决定
Sort Buffer 排序区 运行时内存池 共享池
Hash Buffer 哈希区 运行时内存池 VM→MEMOBJ→VM_MEM_HEAP
评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服