ITPub博客

首页 > 数据库 > 国内数据库 > 达梦数据库top看内存使用率低,free看却很高的问题处理

达梦数据库top看内存使用率低,free看却很高的问题处理

原创 国内数据库 作者:yanhengdoudou 时间:2020-03-14 19:24:01 0 删除 编辑

1         问题描述

   近日,在巡检某达梦数据库系统时,发现top 查看物理内存使用率50%-60% ,但是用free 查看发现,剩余内存1G 多,并且buffer 和cache 也占用不多,才几百兆。如下图:

2         问题分析

   出现上面这个情况,是什么占用了内存呢?

2.1    查看/proc/meminfo 文件

   它是记录系统内存分配使用信息的内核文件。如下图所示:

   从图上可以看到slab 占用了高达约116G ,sReclaimable 可回收86G 多。那么这个slab 是什么呢?

slab 是Linux 操作系统的一种内存分配机制。其工作是针对一些经常分配并释放的对象,如进程描述符等,这些对象的大小一般比较小,如果直接采用伙伴系统来进行分配和释放,不仅会造成大量的内碎片,而且处理速度也太慢。而slab 分配器是基于对象进行管理的,相同类型的对象归为一类( 如进程描述符就是一类) ,每当要申请这样一个对象,slab 分配器就从一个slab 列表中分配一个这样大小的单元出去,而当要释放时,将其重新保存在该列表中,而不是直接返回给伙伴系统,从而避免这些内碎片。slab 分配器并不丢弃已分配的对象,而是释放并把它们保存在内存中。当以后又要请求新的对象时,就可以从内存直接获取而不用重复初始化。

  Slab 分配模式把对象分组放进缓冲区(尽管英文中使用了Cache 这个词,但实际上指的是内存中的区域,而不是指硬件高速缓存)。因为缓冲区的组织和管理与硬件高速缓存的命中率密切相关,因此,Slab 缓冲区并非由各个对象直接构成,而是由一连串的” 大块(Slab )” 构成,而每个大块中则包含了若干个同种类型的对象,这些对象或已被分配,或空闲。一般而言,对象分两种,一种是大对象,一种是小对象。所谓小对象,是指在一个页面中可以容纳下好几个对象的那种。例如,一个inode 结构大约占300 多个字节,因此,一个页面中可以容纳8 个以上的inode 结构,因此,inode 结构就为小对象。Linux 内核中把小于512 字节的对象叫做小对象。实际上,缓冲区就是主存中的一片区域,把这片区域划分为多个块,每块就是一个Slab ,每个Slab 由一个或多个页面组成,每个Slab 中存放的就是对象。

2.2    查看slab 缓存信息

   通过slabtop 命令查看或查看/proc/slabinfo 文件,如下图所示:

   可以发现dentry 占用了超74G 内存。那么这个dentry 是什么呢?

我们知道inode 对应于物理磁盘上的具体对象,而dentry 是一个内存实体,其中的d_inode 成员指向对应的inode ,故可以把dentry 看成是Linux 文件系统中某个索引节点(inode) 的链接,这个索引节点可以是文件,也可以是目录。而 dentry_cache 是目录项高速缓存,是Linux 为了提高目录项对象的处理效率而设计的,它记录了目录项到inode 的映射关系。

2.3    结合dmserver 服务分析

   因为这是一台达梦数据库服务器,上面跑的只有数据库服务,而且使用内存最高的也是dmserver 进程。

  strace 一下dmserver 进程发现其中有非常频繁的stat 系统调用发生,而且stat 的文件总是新的文件名:

strace -fp dmserver 服务的进程号 -e trace=stat

   进一步观察到dmserver 进程会在本地目录下频繁的创建、打开、关闭、删除心跳文件,每秒钟一个新的文件名:

strace -fp dmserver 服务的进程号 -e trace=open,stat,close,unlink

   总结:dmserver 进程频繁的文件io 操作,导致了dentry 占用了系统太多的内存资源。

3         问题解决

   从上面的分析发现是Slab 中 dentry_cache 导致的占用内存过高的问题之后,我们可以通过手动刷新的方式来清理缓存。

echo 3 > /proc/sys/vm/drop_caches      /* 回刷缓冲 */

其中drop_caches 的4 个值有如下含义:

0 :不做任何处理,由系统自己管理

1 :清空pagecache

2 :清空dentries 和inodes

3 :清空pagecache 、dentries 和inodes

   执行清理命令后,free 查看内存使用情况,是正常的。如下图所示:

并且slab 缓存也释放了:

   同时,内核有自动回收机制,可修改触发自动回收的阀值,当slab 空闲内存达到一定量的时候,进行有效的回收。

 


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69949798/viewspace-2679248/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 字段加密解密
请登录后发表评论 登录
全部评论

注册时间:2019-09-29

  • 博文量
    70
  • 访问量
    193375