点击上方蓝色字体关注我们

本文介绍的是达梦数据库管理系统DM8中内存异常的排查方法。DM在运行过程中,如果发现内存突然飙升,或者占用过大,或者操作系统反复OOM时,需要考虑是否是服务器存在内存异常的问题,按照目前DM的动态视图所能提供的信息,需要获取以下内容:Ø数据库的内存使用情况;
Ø是否存在扩展到非常大的内存池;
Ø确认该内存的详细使用情况;


环境说明



正文

数据库的内存使用情况
(1)操作系统级别的命令判断:
Linux系统可以使用top命令,Windows系统可以使用资源管理器等等,查看数据库占用多少内存。
(2)数据库级别的判断:
数据库使用的内存大致等于 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上,比如操作系统上看到内存占用60G,但BUFFER缓冲区已经占用到50 GB。实际上发生异常的概率较小,应该适当调小BUFFER缓冲区,空出内存给内存池使用。
是否存在使用内存过多的SQL
DM服务器提供会话及语句资源监控视图(需要将参数ENABLE_MONITOR的值设置为1监控才会生效)。 通过查询视图v$SESSION_STAT,V$SQL_STAT可以获SQL内存使用的相关信息。这里主要关注MAX_MEM_USED字段。一般来讲,如果是某条或者特定的几条SQL导致内存增长过多,可以通过这两个视图查询出来。
通过执行以下语句:
SELECT MAX_MEM_USED,SQL_TXT FROM V$SQL_STAT order by MAX_MEM_USED DESC;
可以确定使用内存较大的 SQL,可以针对行的优化(消除 HASH,SORT,DISTINCT 等) 注意:该查询只能查询当前活动 STMT 上的语句消耗情况,历史情况需要查询 V$SQL_STAT_HISTORY,该视图上保留 1 万行 SQLSTAT 历史信息。以上 MAX_MEM_USED 列的单位均为 KB。
是否存在扩展过大的内存池
前面介绍过,正常使用过程中,内存池的大小一般会维持在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;
按照大小降序,或者根据文件名、行号分组,查看是否存在大量某文件某行使用内存未释放的情况,转交研发处理。
内存异常的检查
大致的检查原理如下:
在每次申请内存时,返回的内存块中包含:
返回内存的管理结构大小 + 申请长度 + 一个 ULINT_SIZE大小的内存块
其中首部用于存放管理这块内存结构的结构,实际使用的内存为第二段,最后一段填入一个校验码。校验码为一个固定魔术和该内存管理结构的首地址计算出来的一个常数。
当需要释放内存时,如果 MEMORY_MAGIC_CHECK 为 1 则会根据需要释放内存的地址计算出一个校验码,与该内存结构尾部的校验码比较,若不相等,则说明该片内存可能出现过写溢出,数据库会 HALT 掉。
如果 MEMORY_MAGIC_CHECK 配置为 2 则会在 1 的检查基础上,由于申请内存长度可能是大于需求长度的(因为申请时要求申请大小为 2 的 N 次幂,会在大于需求长度后面的每一位上都添加上特殊校验码,释放时每一位都会检查,检查失败也会 HALT。
如果实际生产中发现MEMORY_MAGIC_CHECK 为 2 比较慢,则可以将MEMORY_MAGIC_CHECK 改为 1。


总结

今天的介绍就到这里,以上这些检查的方法,大家掌握了吗?
本期介绍的是达梦数据库管理系统DM8中内存异常的排查方法,希望能带给大家帮助。想要了解更多往期干货,可访问页面最下方#达梦技术干货攻略#合集或下方相关分享。在此邀请更多学员参与“达梦技术干货投稿活动”,稿件获选后将在达梦“干货分享”专栏进行发布,欢迎来稿!
作者:crossrainbow
审核:培训部


一周热文











达梦E学
微信号:DM-Elearning
扫码关注查看更多内容
点击下方在看,分享本文




