【YashanDB知识库】virt虚拟内存远大于res内存问题分析

简介: 【YashanDB知识库】virt虚拟内存远大于res内存问题分析

YASDB内存占用简介

参数配置:
默认参数配置:DBMS_PARAM高级包生成配置参数
数据库内存配置,使用默认参数步骤:
1、DBMS_PARAM.OPTIMIZE(); //生成默认参数,使用总内存的80%
2、SELECT DBMS_PARAM.SHOW_RECOMMEND() FROM dual; //查看生成的参数
3、EXEC DBMS_PARAM.APPLY_RECOMMEND(); //应用参数,需要重启yasdb
文档路径:YashanDB Doc (yasdb.com)
内存占用计算参数:
DATA_BUFFER_SIZE VM_BUFFER_SIZE SHARE_POOL_SIZE LARGE_POOL_SIZE SCOL_DATA_BUFFER_SIZE COLUMNAR_VM_BUFFER_SIZE 主要是上面这些参数配置内存的总和 + 256M(其他小块内存)

问题:VIRT超过RES十几个G

如下图所示,yasdb满负荷运行后,0任务跑的情况下,virt内存:31.2g,实际内存:21.7g,虚拟内存比实际内存大了10g左右,虚拟内存远大于实际使用内存。
image.png

YASDB内存使用情况
yasdb参数配置,如下图:
image.png

按照yasdb主要内存占用计算:
DATA_BUFFER_SIZE(18306M) + VM_BUFFER_SIZE(2382M) + SHARE_POOL_SIZE(512M) + LARGE_POOL_SIZE(1G) + SCOL_DATA_BUFFER_SIZE(128M) + COLUMNAR_VM_BUFFER_SIZE (128M) = 22480M(21.95g)
RES 21.7g的内存使用和yasdb内存总占用数相符合。
VIRT内存为什么远远大于RES
VIRT:SWAP+RES(虚拟内存大小,包括进程使用的库、代码、数据等,如果申请100M,则增加100M大小)
RES:进程使用的,未被换出的物理内存(包括共享内存大小,如果申请100M,使用10M,则实际为10M)
mmap查看yasdb使用情况
如下图:
strace -f -e "brk,mmap,munmap" -p 2051595

yasdb没有使用mmap等映射接口。
pmap工具,查看进程内存映射信息
pmap命令用于报告进程的内存映射关系(查看进程的内存映像信息)
选项:

-x, --extended:显示扩展格式

-d, --device:显示设备格式

-X:显示比 -x 选项更多的详细信息。注意:格式根据 /proc/PID/smaps 更改

-p, --show-path:在映射列中显示文件的完整路径

-h, --help:显示帮助信息并退出

-V, --version:显示版本信息并退出

扩展格式和设备格式域:

Address: start address of map 映像起始地址

Kbytes: size of map in kilobytes 映像大小

RSS: resident set size in kilobytes 驻留集大小

Dirty: dirty pages (both shared and private) in kilobytes 脏页大小

Mode: permissions on map 映像权限: r=read, w=write, x=execute, s=shared, p=private (copy on write)

Mapping: file backing the map , or ‘[ anon ]’ for allocated memory, or ‘[ stack ]’ for the program stack. 映像支持文件,[anon]为已分配内存 [stack]为程序堆栈

Offset: offset into the file 文件偏移

Device: device name (major:minor) 设备名

pmap -d ${pid}
glibc分配内存机制

导致这种问题的原因是使用glibc的Arena内存池分配了大量的虚拟内存。

glibc大于2.1.1版本时,在glibc分配内存的时候,大内存从从中央分配区分配,小内存则在线程创建时,从缓存区分配。

为了解决分配内存的性能的问题,就引入了这个叫做arena的memory pool。而恰好,在64bit系统下面,它的缺省配置为64M。

一个进程可以最多有cores 8个arena,假如服务器是4核的,那么最多有4 8=32个arena,也就是32 * 64 = 2048M内存

参考文档:
image.png

https://link.juejin.cn/?target=https%3A%2F%2Faccess.redhat.com%2Fdocumentation%2Fen-us%2Fred_hat_enterprise_linux%2F6%2Fhtml%2F6.0_release_notes%2Fcompiler

glibc版本:
image.png

内核数 cores:
image.png

MALLOC_ARENA_MAX:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <pthread.h>

bool kill_th = false;

void *th_func(void *arg){

        int s = 0;
        //int size = 1024*1024*139;
        int size2 = 1024;
        //char *pbuf;
        while(!kill_th){
                if(s == 0){
                   //pbuf = (char *)malloc(size);
                  // free(pbuf);

                   char *pbuf2 = (char *)malloc(size2);
                   free(pbuf2);
                   s = 1;
                }

                sleep(1);
        }
        //free(pbuf);
}

void create_thread(){
    pthread_t tid;
    int nums = 256;
    for(int i = 0; i< nums;i++){
        pthread_create(&tid,NULL,th_func,NULL);
        pthread_detach(tid);
    }

    while(getchar()){
        kill_th = true;
        getchar();
        break;
    }
    return ;
}

int main(int argc,const char **argv) {
    create_thread();
    return 0;
}

超过64M大小的空间不从arena内存池申请。
编译:gcc test.c -lpthread
ulimit -a:

运行测试程序 : ./a.out:
默认MALLOC_ARENA_MAX
arena池默认个数:16 * 8 = 128
默认,cat /proc/$pid/environ,如下图:
image.png

该文件没有MALLOC_ARENA_MAX参数
● 256个线程
内存使用情况:
image.png

pmap -p pid 信息如下:pmap_malloc_arena_max_normal.txt
arena内存池:127 (65344K + 192K)
线程栈空间:256
8192K
8192K 256 + 64M127 = 10176M,
再加上其它小空间,符合虚拟内存使用情况。
● 256个线程退出
内存使用情况:

pmap映射进程信息:pmap_maloc_arena_normal_thread_exit.txt
arena内存池:127 (65344K + 192K)= 8128M
栈空间:仅剩主线程空间
可以看出,线程退出后,arena空间并没有释放。
*export MALLOC_ARENA_MAX = 4

MALLOC_ARENA_MAX 值: cat /proc/$pid/environ:
image.png

可以看到参数MALLOC_ARENA_MAX 配置为4
● 256个线程
top信息:
image.png

pamp -p pid信息: pmap_malloc_arena_max=4.txt
线程栈空间:2568M
arena内存池:3
(65344K + 192k)
● 256线程退出
top信息:
image.png

pamp -p pid信息,如下图:
image.png

arena内存池:3 (65344K + 192k)
yasdb的内存映射情况
参数:
WORK_AREA_STACK_SIZE 2M
WORK_AREA_HEAP_SIZE 512K
得知栈空间大小为2M,堆空间为512K
分析pmap信息:
pmap -p {pid}(yasdb),文件:pmap_yasdb.txt
arena内存池:97
(65024K+512k) + 5 (65216K+320k) + 1(64576K +960K ) + 1 (53824K + 11712K) + 23 (64896K + 640K) = 127 64M = 8128 M
栈空间:390
1984K + 9 8192K = 827.625M
其它:lib库映射空间等
总共相加,大概可以得出与多出的虚拟内存相等。
*配置线程参数一些接口:

每个线程都会分配一个栈(默认8M,可配置)和一个堆空间。
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, stackSize); //配置线程属性->栈空间大小
prctl(PR_SET_NAME, name); //设置线程名
pthread_detach(tid); //线程退出后,自动释放空间。如果没有配置这个需要主动释放pthread_exit。不然会一直占用虚拟内存
ulimit -a可看堆栈默认值,也可配置堆栈默认值。

相关文章
|
21天前
|
SQL 存储 关系型数据库
【YashanDB知识库】共享从 MySQL异常处理CONTINUE HANDLER的改写方法
【YashanDB知识库】共享从 MySQL异常处理CONTINUE HANDLER的改写方法
|
4天前
|
SQL 测试技术 数据库
【YashanDB知识库】IMP跨网络导入慢问题
问题现象:290M数据,本地导入2分钟,跨机导入耗时显著增加(最高30分钟)。 原因分析:`imp`逐条SQL通过网络传输至yashanDB执行,交互频繁导致性能下降。 影响版本:客户测试环境22.2.8.3。 解决方法:将导入文件上传至与yashanDB同机后使用`imp`,减少网络延迟。 经验总结:优化`imp`工具,支持直接上传文件至服务器端执行,降低网络依赖。
|
4天前
|
监控 数据库
【YashanDB 知识库】ycm 托管数据库时报错 OM host ip:127.0.0.1 is not support join to YCM
在托管数据库时,若 OM 的 IP 被设置为 127.0.0.1,将导致无法托管至 YCM,并使数据库失去监控。此问题源于安装时修改了 OM 的监听 IP。解决方法包括:将 OM 的 IP 修改为本机实际 IP 或 0.0.0.0,同时更新 env 文件及 yasom 后台数据库中的相关配置。经验总结指出,应避免非必要的后台 IP 修改,且数据库安装需遵循规范,不使用仅限本机访问的 IP(如 127.0.0.1)。
|
4天前
|
监控 网络安全 数据库
YashanDB 知识库:ycm 纳管主机安装 YCM-AGENT 时报错 “任务提交失败,无法连接主机”
在安装 ycm-agent 纳管主机时,可能出现因端口未开放导致的报错问题。此问题会阻止 YCM 对主机和数据库的监控功能,影响版本为 `yashandb-cloud-manager-23.2.1.100-linux-aarch64.tar`。原因是目标主机(如 10.149.223.121)未开放 9070 或 9071 端口。解决方法包括关闭防火墙、添加白名单或开放指定端口,需与管理员确认操作。处理过程涉及网络检查、端口测试等步骤。端口问题解决后,若再次安装报唯一键错误,需先移除失败主机再重试。
|
4天前
|
监控 Java Shell
【YashanDB 知识库】ycm 托管数据库时,数据库非 OM 安装无法托管
本文主要介绍了因数据库未按规范使用 yasboot 安装导致的问题及解决方法。问题表现为无 yasom 和 yasagent 进程,且目录结构缺失,致使 ycm 无法托管与监控。分析发现可能是数据库版本旧或安装不规范引起。解决方法为先生成配置文件,安装 yasom 和 yasagent,再生成并修改托管配置模板,最终通过命令完成托管至 yasom 和 ycm。总结强调了按规范安装数据库的重要性以避免类似问题。
|
21天前
|
SQL 关系型数据库 MySQL
【YashanDB知识库】MySQL field 函数的改写方法
【YashanDB知识库】MySQL field 函数的改写方法
|
21天前
|
SQL 存储 缓存
YashanDB内存体系
YashanDB内存体系
|
21天前
|
数据库
【YashanDB知识库】服务器重启后启动yasom和yasagent进程时有告警
【YashanDB知识库】服务器重启后启动yasom和yasagent进程时有告警
|
21天前
|
SQL Oracle 关系型数据库
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
|
23天前
|
SQL Oracle 关系型数据库
【YashanDB知识库】MySQL和YashanDB 隐式转换不一致引起的报错
本文分析了在YashanDB中执行特定SQL语句时出现的类型转换错误问题,并对比了YashanDB、Oracle和MySQL 5.7的行为差异。问题源于隐式类型转换,当数值字段与非法数字字符串(如&#39;1,2&#39;)进行比较时,YashanDB和Oracle会报错,而MySQL 5.7虽不报错但会引发警告。通过调整SQL语句,避免数值与字符串直接比较,可有效解决问题。文章还详细解析了不同值表现不一致的原因,涉及执行计划和过滤条件的实际运行细节。

热门文章

最新文章