☰
Oracle vs DM 内存结构差异:运维必须知道的坑
2026/10/6 13:52:03 网站建设 项目流程

随着信创国产化替代深入,越来越多业务从 Oracle 迁移到达梦(DM)数据库。很多 DBA 刚上手时会习惯性沿用 Oracle 运维思路,结果在内存管理、故障排查、性能调优上频频踩坑。

本质原因只有一个: 两者内存结构看似相似,底层模型完全不同,直接决定了运维方式天差地别。

01先搞懂底层:为什么运维会不一样?

1. Oracle:多进程架构

一块全局共享内存: SGA

每个连接独立私有内存: PGA

进程之间内存隔离,互不干扰

2. 达梦 DM:单进程多线程架构

整个数据库只有一个主进程:dmserver

所有线程共用同一块共享内存地址空间

没有真正意义上的 PGA,私有内存从共享池申请

一句话结论: Oracle 是 “分灶吃饭”,DM 是 “大锅饭”。Oracle 一个会话崩了不影响全局;DM 一个线程失控可能拖垮整个库。

02日常运维中的真实差异

1.内存查看与监控思路不同

Oracle 重点看两块:

SGA 共享内存(数据缓存、SQL 缓存、日志缓冲)

PGA 私有内存(排序、哈希、会话私有)

show sga;

select * from v$pgastat;

DM 只盯一块核心:共享内存池

数据缓冲区 BUFFER

SQL 缓存、字典缓存

会话私有内存、排序哈希内存均来自这里

select * from v$mem_pool;

select * from v$bufferpool;

运维差异:Oracle看命中率、看自动扩展是否正常;DM必须盯内存剩余空间,光看命中率会误判

2.大SQL、排序、哈希连接风险不同

Oracle

排序、哈希内存来自 PGA,进程隔离

单个会话内存爆了,只会报错退出,不影响其他业务

DM

SORT_BUF_SIZE、HJ_BUF_SIZE 全部来自共享内存池

高并发大排序、大表关联极易瞬间吃满内存

轻则全库卡顿,重则 dmserver 异常退出

运维差异:Oracle慢SQL影响自身;DM慢SQL可能“一颗老鼠屎坏一锅汤”

3. 内存溢出(OOM)后果完全不同

Oracle

PGA 溢出:单个进程报错

SGA 溢出:数据库异常但一般不会整机宕机

DM

单进程模型,任何线程内存越界

直接导致 整个数据库进程崩溃

日志可能只残留碎片信息,定位难度更高

运维差异:DM 必须严格限制:大 SQL 并发、不合理排序与关联、过度连接

4. 参数调整:Oracle 灵活,DM 偏刚性

Oracle

支持 AMM / ASMM 自动内存管理SGA 组件可在线伸缩,大部分参数可动态调整

DM

核心内存参数多为 静态参数 ,修改必须重启:

BUFFER 数据缓冲区

MEMORY_POOL 共享内存池

RLOG_BUF_SIZE 日志缓冲区

运维差异: Oracle 可在线救火调优DM 更依赖前期规划,出问题后只能 “事后优化”

5. 连接数与高并发风险不同

Oracle 每个连接有独立 PGA,连接增多内存增长平缓

DM 所有会话线程共享一块地址空间连接数暴涨 → 会话上下文内存激增 → 共享池吃紧 → 库夯住

运维差异: DM 必须严格控制 MAX_SESSIONS,不能盲目扩容连接

6. 内存碎片问题:DM 更敏感

Oracle PGA 独立分配释放,碎片影响小

DM 多线程频繁申请 / 释放内存,易产生 共享内存碎片 表现:内存总量充足,但提示 “无法分配内存”;业务时快时慢;重启后明显恢复

运维差异: Oracle 基本不用关心碎片;DM 需要定期观察内存碎片,高发场景需规划周期性重启

03一张表看懂核心运维差异

04迁移运维建议

√ 不要把 DM 当 Oracle 运维 别再用 PGA 思路去理解 DM 的私有内存。

√ DM 优先控制大 SQL 全表扫描、大排序、大哈希连接必须提前优化。

√ 连接池必须规范 禁止短连接风暴,严控最大连接数。

√ 内存参数提前规划 不追求极端大内存,预留安全余量,避免撑满。

√ 出现莫名卡顿优先查内存 内存碎片、共享池耗尽是 DM 高频故障点。

√ 高并发业务务必压测 尤其排序、统计类报表,极易触发内存风险。

05 结 语

Oracle 与 DM 看似都是关系型数据库,内存结构名词也高度相似,但底层模型决定了运维逻辑完全不同。

从 Oracle 迁移到达梦,最危险的不是语法不兼容,而是用旧经验运维新架构。理解内存差异,才能真正做到平稳迁移、稳定运行。

附录1:会话内存异常排查

1.登录数据库

[root ]# /home/dmdba/dmdbms/bin/disql SYSDBA/SYSDBA

服务器[LOCALHOST:5236]:处于主库打开状态

2.内存使用情况

操作系统级别的命令判断:TOP、WINDOWS 资源管理器等,查看数据占用多少内存。

数据库级别的判断:数据库使用的内存大致等于 BUFFER_SIZE + POOL_SIZE,对应的 SQL 语句如下:

select

(select sum(n_pages) * page()/1024/1024 from v$bufferpool)||'MB' as BUFFER_SIZE,

(select sum(total_size)/1024/1024 from v$mem_pool)||'MB' as mem_pool,

(select sum(n_pages) * page()/1024/1024 from v$bufferpool)+(select sum(total_size)/1024/1024 from v$mem_pool)||'MB' as TOTAL_SIZE

from dual;

行号 BUFFER_SIZE mem_pool TOTAL_SIZE

---------- ----------- -------- ----------

1 1308MB 1780MB 3088MB

说明:

① BUFFER_SIZE:系统缓冲区大小,以 M 为单位。推荐值:系统缓冲区大小为可用物理内存的 60%~80%。有效值范围(8~1048576)。

② MEM_POOL:共享内存池大小,以 M 为单位。共享内存池是由 DM 管理的内存。有效值范围:32 位平台为(642000),64 位平台为(6467108864)。

③ TOTAL_SIZE:BUFFER_SIZE 和 MEM_POOL 的总和。

3.查看sql占用内存情况

内存不足常见原因有如下两种情况:

① memory_target 设置为 0,导致会话使用的内存未释放,可以考虑修改 memory_target 参数。

② 会话执行的 sql 消耗大量的内存。如下sql查询内存使用较多的语句

SELECT "SESSID", MAX_MEM_USED||'KB',SQL_TXT FROM V$SQL_STAT

order by MAX_MEM_USED DESC;

行号 SESSID MAX_MEM_USED||'KB'

---------- -------------------- ------------------

SQL_TXT

------------------------------------------------------------------------------------------------------------------------------------------

4 139672852769784 127090624KB

select f_getsequence(?) from dual

5 139672684044120 31416064KB

UPDATE stat_service_request_trend SET request_sum = request_sum + 1,success_sum = success_sum + 1,error_sum = error_sum + 1 - 1,gtw_error_sum = gtw_error_sum + 1 - 1,gtw_avg_time = (gtw_avg_time * request_sum + 232) / (request_sum + 1),gtw_total_time = gtw_total_time + 232,biz_error_sum = biz_error_sum + 1 -1,biz_avg_time = (biz_avg_time * request_sum + 209) / (request_sum + 1),biz_total_time = biz_total_time + 209 WHERE (stat_id = ?)

注意:V$SQL_STAT视图需要开启监控功能才能收集数据,需设置以下参数:

ENABLE_MONITOR=1

MONITOR_SQL_EXEC=1

ENABLE_MONITOR_DMSQL=1

4.查看内存池使用信息

查询内存池使用信息的 sql 语句如下所示,单位是 M。

select name,is_shared,is_overflow,org_size/1024/1024,TOTAL_size/1024/1024,RESERVED_SIZE/1024/1024,DATA_SIZE/1024/1024,EXTEND_SIZE,TARGET_SIZE,N_EXTEND_NORMAL,N_EXTEND_EXCLUSIVE from v$mem_pool where rownum<20 order by TOTAL_size desc;

行号 name is_shared is_overflow org_size/1024/1024 TOTAL_size/1024/1024 RESERVED_SIZE/1024/1024 DATA_SIZE/1024/1024

---------- --------------- --------- ----------- -------------------- -------------------- ----------------------- --------------------

EXTEND_SIZE TARGET_SIZE N_EXTEND_NORMAL N_EXTEND_EXCLUSIVE

-------------------- -------------------- --------------- ------------------

1 SHARE POOL 000 Y N 500 500 236 145

33554432 15728640000 0 0

2 MON ITEM ARR Y N 9 169 160 117

8388608 0 3 0

3 BACKUP POOL Y N 4 4 0 0

33554432 4194304 0 0

4 RT_MEMOBJ_VPOOL Y N 1 1 0 0

1048576 33554432 0 0

说明:

① N_EXTEND_EXCLUSIVE 如果长期大于 0,说明长期从池外扩展,可能存在内存泄露,需要重点关注。

② 若使用到备份池,则需要保持高度关注。

③ 内存池创建的线程号 creator 可以与 session 的 thrd_id 关联,查看对应的某个会话的内存使用情况,查看方法可以参考 单个会话内存使用情况。

④ 若 RESERVED_SIZE 比 org_size 小,说明内存池非常空闲,可以减小对应的初始内存,避免浪费。

⑤ 若 TOTAL_size 比 TARGET_SIZE 大,说明内存池不够,经常向池外申请,需要把对应参数调大。

可以通过 v$sysstat 视图监控内存的使用情况

select name ,stat_val/1024/1024 from v$sysstat where CLASSID=11 ;

SQL> select name ,stat_val/1024/1024 from v$sysstat where CLASSID=11 ;

行号 name stat_val/1024./1024.

---------- -------------------------------- --------------------

1 bytes allocated from os 0

2 memory pool size in bytes 1773.3748779296875

3 memory used bytes 1057.3709716796875

4 memory used bytes from os 902

5 hj buffer total used in M 0

6 hj buffer merge used in M 0

7 hagr buffer used in M 0

8 package info cache used in bytes 0

9 huge buffer total pages 0.01953125

10 huge buffer free pages 0.048828125

11 huge buffer mem use pages 0

12 huge buffer mem alloc count 0

13 huge buffer mem free count 0

14 huge buffer reserve count 0

15 sort buf global total size(MB) 0.00095367431640625

16 sort buf global used size(MB) 0

memory pool size in bytes:内存池总的大小。

memory used bytes:内存池使用的内存大小。

memory used bytes from os:内存池从操作系统分配的大小

5.单个会话内存使用情况

SELECT A.CREATOR,B.SQL_TEXT,SUM(A.TOTAL_SIZE)/1024.0/1024.0

TOTAL_M,SUM(A.DATA_SIZE) /1024.0/1024.0 DATA_SIZE_M

FROM V$MEM_POOL A,V$SESSIONS B

WHERE A.CREATOR = B.THRD_ID

GROUP BY A.CREATOR, B.SQL_TEXT

ORDER BY TOTAL_M DESC;

行号 CREATOR

---------- -----------

SQL_TEXT

------------------------------------------------------------------------------------------------------------------------------------------

TOTAL_M DATA_SIZE_M

------- -------------------

1 3725701 SELECT A.CREATOR , B.SQL_TEXT , SUM(A.TOTAL_SIZE)/1024.0/1024.0 TOT AL_M, SUM(A.DATA_SIZE) /1024.0/1024.0 DATA_SIZE_M FROM V$MEM_POOL A, V$SESSIONS B WHERE A.CREATOR = B.THRD_ID GRO UP BY A.CREATOR, B.SQL_TEXT ORDER BY TOTAL_M DESC;

27.25 20.6313934326171875

2 642185

select f_getsequence(?) from dual

10.1875 2.19039154052734375

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询