暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

DM达梦数据库内存泄漏 异常检查

原创 达梦 2021-01-31
1954

DM 运行过程中,如果发现内存突然飙升,或者占用过大,或者操作系统反复 OOM 时,需要考虑是否是服务器存在内存泄漏问题,按照 DM 的动态视图所能提供的信息,需要获取以下内容:

  • 数据库的内存使用情况

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

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

select (select sum(n_pages * page_size) 
from v$bufferpool) + (select sum(total_size) from v$mem_pool) from dual;

一般来说,发生内存泄漏的都在 mem_pool 上,比如操作系统上看到内存占用 60 GB,但 BUFFER 已经占用到 50 GB,实际上发生泄漏的概率较小,应该适当调小 BUF,空出内存给内存池使用。

  • 是否存在使用内存过多的 SQL

较新版本的 DM 服务器提供会话及语句资源监控视图 ENABLE_MONITOR=1 生效 V$SESSION_STAT V$SQL_STAT 视图上字段比较丰富,我们这里主要关注 MAX_MEM_USED 字段。一般来讲,如果是某条或者特定的几条 SQL 导致内存增长过多,可以通过这两个视图查询出来。

执行以下语句:

SELECT MAX_MEM_USED,SQL_TEXT FROM V$SQL_STAT order by MAX_MEM_USED DESC;

可以确定使用内存较大的 SQL,可以针对行的优化(消除 HASH,SORT,DISTINCT 等),需要注意的是该查询只能查询当前活动 STMT 上的语句消耗情况,历史情况需要查询 V$SQL_STAT_HISTORY,该视图上保留 1 万行 SQLSTAT 历史信息。

以上 MAX_MEM_USED 列的单位均为千。

  • 是否存在扩展过大的内存池

前面介绍过,正常使用过程中,内存池的大小一般会维持在 TARGET_SIZE 左右,不会发生太大的差距,如果发生非常多次计划外的扩展,需要考虑该池是否发生内存泄漏,与之相关的系统视图和系统视图字段为:v$mem_pool 上的 N_EXTEND_EXCLUSIVE 字段。查询语句如下:

Select * from v$mem_pool where n_extend_exclusive  0;

确认池后,通过 MEM_POOL 的 CREATOR 也就是创建这个池的线程号,在 V$SESSIONS 或者 V$SESSIONS_HISTORY 里面确认会话号,然后去 V$SQL_STAT_HISTORY 或者 V$SESSION_STAT_HISTORY 中寻找内存消耗大的 SQL 即可。

查看存在超出计划大小扩展的内存池、计划外扩展次数以及大小,如果池大小为可以通过 INI 调整(如 VM_POOL_TARGET、SESS_POOL_TARGET,但这两个参数慎用,调整过大对并发影响较大),可以适当放大计划大小,再运行观察计划外扩展情况是否有改善,如果仍然存在大量的计划外扩展则需要继续跟进内存使用情况。

  • 确认内存的详细使用情况

详细的内存使用情况需要视图 v$mem_reginfo,该视图在 INI 参数 MEM_LEAK_CHECK = 1 时有效,可动态开启,开启后登记数据库中所有内存的申请释放信息。查询语句如下:

Select sum(reserved_size),fname,lineno
from v$mem_reginfo group by fname,lineno order by sum(reserved_size) desc;

按照大小降序,或者根据文件名、行号分组,查看是否存在大量某文件某行使用内存未释放的情况,转交研发处理。

  • 内存异常的检查

DM 提供自动的内存异常检查,检查参数为 INI 中的 MEMORY_MAGIC_CHECK,默认值为 2,检查原理如下:

在每次申请内存时,返回的内存块中包含:返回内存的管理结构大小+申请长度+一个 ULINT_SIZE 大小的内存块。(其中首部用于存放管理这块内存结构的结构,实际使用的内存为第二段,最后一段填入一个校验码)

校验码为一个固定魔术和该内存管理结构的首地址计算出来的一个常数。每当需要释放内存时,如果 MEMORY_MAGIC_CHECK 为 1 则会根据需要释放内存的地址计算出一个校验码,与该内存结构尾部的校验码比较,若不相等,则说明该片内存可能出现过写溢出,数据库会 HALT 掉。

如果 MEMORY_MAGIC_CHECK 配置为 2 则会在 1 的检查基础上,由于申请内存长度可能是大于需求长度的(因为申请时要求 申请大小为 2 的 N 次幂,会在大于需求长度后面的每一位上都添加上特殊校验码,释放时每一位都回检查,检查失败也会 HALT。

如果实际生产中发现 CHECK 为 2 比较慢,则可以将 MAGIC_CHECK 改为 1。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论