PostgreSQL 内存配置 与 MemoryContext 的生命周期
PostgreSQL 内存配置与MemoryContext的生命周期
PG/GP 内存配置
数据库可用的内存 gp_vmem
整个 GP 数据库可用的内存 gp_vmem:
>>> RAM = 128 * GB
>>> gp_vmem = ((SWAP + RAM) - (7.5*GB + 0.05 * RAM)) / 1.7
>>> print(gp_vmem / GB)
67.11764705882352>>> RAM = 256 * GB
>>> gp_vmem = ((SWAP + RAM) - (7.5*GB + 0.05 * RAM)) / 1.7
>>> print(gp_vmem / GB)
138.64705882352942
内存上限 gp_vmem_protect_limit
每个 Segment 可用的内存上限 gp_vmem_protect_limit:
max_acting_primary_segments = num_segments + 3
gp_vmem_protect_limit = gp_vmem / max_acting_primary_segments
内存配额 gp_statement_mem
每个 Segment 可用的内存配额 gp_statement_mem:
gp_statement_mem = (gp_vmem_protect_limit * 0.9) / max_expected_concurrent_queries
gp_statement_mem = (8192 MB * .9) / 40 = 184MB
注意:实际上的配置名称为statement_mem,并且其值不能突破max_statement_mem的限制。
并发量 max_parallel_workers_per_gather
并发量与内存息息相关,并发越大启动的进程越多,消耗的内存则越大。
show max_parallel_workers; -- default 60show max_parallel_workers_per_gather; -- default 2
set max_parallel_workers_per_gather = 5;
官方参考文档:
- https://gp-docs-cn.github.io/docs/best_practices/sysconfig.html#topic_dt3_fkv_r4__segment_mem_config
- https://gp-docs-cn.github.io/docs/best_practices/workloads.html
PG MemoryContext 生命周期
MemoryContext 生命周期概览
PG 的 MemoryContext 是一个树形结构,每个Query可以对应一个MemoryContext(我们可以称为query_context),query_context会创建Child行级别的MemoryContext,比如下面是Aggregate的2个典型行级别MemoryContext,分别为tuple_context、expr_context:
auto aggstate = reinterpret_cast<::AggState *>((::PlanState *) shadow_ps);
auto tuple_context = aggstate->curaggcontext->ecxt_per_tuple_memory;
auto expr_context = aggstate->tmpcontext->ecxt_per_tuple_memory;
tuple_context 生命周期
一般来说,tuple_context的生命周期比query_context的短,当火山模型中的一行数据完成吐出,或者向量化模型中的一批数据完成吐出,则tuple_context中的内存就可以释放了,tuple_context的生命周期是贯穿每一行的如下步骤:
- 从最底层读取数据到数据。
- 中间的一连串计算算子。
- 结尾的将最终结果吐出给用户。
expr_context 生命周期
但是expr_context的生命周期,一般来说,比tuple_context的更短,expr_context在任何一个算子中,或两个上下依赖的算子中,均可完成其全部生命周期(从创建到销毁内存)。本质上来说,expr_context定位为临时性的内存需求,用完即可释放。
MemoryContext 典型操作
MemoryContext 上下文创建
/** Create working memory for expression evaluation in this context.*/
// src/backend/executor/execUtils.c
econtext->ecxt_per_tuple_memory =AllocSetContextCreate(estate->es_query_cxt,"ExprContext",minContextSize,initBlockSize,maxBlockSize);// src/backend/utils/mmgr/aset.c
MemoryContext
AllocSetContextCreateInternal(MemoryContext parent,const char *name,Size minContextSize,Size initBlockSize,Size maxBlockSize)
{AllocSet set;...// src/backend/utils/mmgr/mcxt.cMemoryContextCreate((MemoryContext) set,T_AllocSetContext,&AllocSetMethods,parent,name);...return set;
}
MemoryContext 上下文切换
auto expr_context = aggstate->tmpcontext->ecxt_per_tuple_memory;
auto oldcxt = ::MemoryContextSwitchTo(expr_context);
MemoryContext 内存释放(整体)
MemoryContextReset() 函数用于释放一个 MemoryContext 中分配的所有内存:
// the tmpcontext is short-live
auto expr_context = aggstate->tmpcontext->ecxt_per_tuple_memory;
::MemoryContextReset(expr_context);
Memory 内存典型操作
内存分配 palloc
void* palloc(Size size)
{/* duplicates MemoryContextAlloc to avoid increased overhead */void *ret;MemoryContext context = CurrentMemoryContext;AssertArg(MemoryContextIsValid(context));AssertNotInCriticalSection(context);if (!AllocSizeIsValid(size))elog(ERROR, "invalid memory alloc request size %zu", size);context->isReset = false;ret = context->methods->alloc(context, size);if (unlikely(ret == NULL)){MemoryContextStats(TopMemoryContext);ereport(ERROR,(errcode(ERRCODE_OUT_OF_MEMORY),errmsg("out of memory"),errdetail("Failed on request of size %zu in memory context \"%s\".",size, context->name)));}VALGRIND_MEMPOOL_ALLOC(context, ret, size);return ret;
}
内存分配并填充0 – palloc0
void* palloc0(Size size)
{/* duplicates MemoryContextAllocZero to avoid increased overhead */void *ret;MemoryContext context = CurrentMemoryContext;AssertArg(MemoryContextIsValid(context));AssertNotInCriticalSection(context);if (!AllocSizeIsValid(size))elog(ERROR, "invalid memory alloc request size %zu", size);context->isReset = false;ret = context->methods->alloc(context, size);if (unlikely(ret == NULL)){MemoryContextStats(TopMemoryContext);ereport(ERROR,(errcode(ERRCODE_OUT_OF_MEMORY),errmsg("out of memory"),errdetail("Failed on request of size %zu in memory context \"%s\".",size, context->name)));}VALGRIND_MEMPOOL_ALLOC(context, ret, size);MemSetAligned(ret, 0, size);return ret;
}
内存重分配 repalloc
/** repalloc* Adjust the size of a previously allocated chunk.*/
void* repalloc(void *pointer, Size size)
{MemoryContext context = GetMemoryChunkContext(pointer);void *ret;if (!AllocSizeIsValid(size))elog(ERROR, "invalid memory alloc request size %zu", size);AssertNotInCriticalSection(context);/* isReset must be false already */Assert(!context->isReset);ret = context->methods->realloc(context, pointer, size);if (unlikely(ret == NULL)){MemoryContextStats(TopMemoryContext);ereport(ERROR,(errcode(ERRCODE_OUT_OF_MEMORY),errmsg("out of memory"),errdetail("Failed on request of size %zu in memory context \"%s\".",size, context->name)));}VALGRIND_MEMPOOL_CHANGE(context, pointer, ret, size);return ret;
}
内存释放 pfree
/** pfree* Release an allocated chunk.*/
void pfree(void *pointer)
{MemoryContext context = GetMemoryChunkContext(pointer);context->methods->free_p(context, pointer);VALGRIND_MEMPOOL_FREE(context, pointer);
}
相关文章:
PostgreSQL 内存配置 与 MemoryContext 的生命周期
PostgreSQL 内存配置与MemoryContext的生命周期 PG/GP 内存配置 数据库可用的内存 gp_vmem 整个 GP 数据库可用的内存 gp_vmem: >>> RAM 128 * GB >>> gp_vmem ((SWAP RAM) - (7.5*GB 0.05 * RAM)) / 1.7 >>> print(gp_vmem / G…...
vue3 组件间通信的方式(setup语法糖写法)
vue3 组件间通信的方式(setup语法糖写法) 1. Props方式 该方式用于父传子,父组件以数据绑定的形式声明要传递的数据,子组件通过defineProps()方法创建props对象,即可拿到父组件传来的数据。 // 父组件 <template><div><son…...

【Cache】Rsync远程同步
文章目录 一、rsync 概念二、rysnc 服务器部署1. 环境配置2. rysnc 同步源服务器2.1 安装 rsync2.2 建立 rsyncd.conf 配置文件2.3 创建数据文件(账号密码)2.4 启动服务2.5 数据配置 3. rysnc 客户端3.1 设置同步方法一方法二 3.2 免交互设置 4. rysnc 认…...

Gitlab升级报错一:rails_migration[gitlab-rails] (gitlab::database_migrations line 51)
Gitlab-ce从V14.0.12升级到V14.3.6或V14.10.5时报错:如下图: 解决办法: 先停掉gitlab: gitlab-ctl stop 单独启动数据库,如果不单独启动数据库,就会报以上错误 sudo gitlab-ctl start postgresql 解决办法&#x…...

chatGPT流式回复是怎么实现的
chatGPT流式回复是怎么实现的 先说结论: chatGPT的流式回复用的就是HTTP请求方案中的server-send-event流式接口,也就是服务端向客户端推流数据。 那eventStream流式接口怎么实现呢,下面就进入正题! 文章目录 chatGPT流式回复…...

使用SpringEL获得字符串中的表达式运算结果
概述 有时候会遇上奇怪的需求,比如解析字符串中表达式的结果。 这个时候自己写解析肯定是比较麻烦的, 正好SprinngEL支持加()、减(-)、乘(*)、除(/)、求余(%)、幂(^)运算,可以免去造轮子的功夫…...

力扣 39. 组合总和
题目来源:https://leetcode.cn/problems/combination-sum/description/ C题解: 递归法。递归前对数组进行有序排序,可方便后续剪枝操作。 递归函数参数:定义两个全局变量,二维数组result存放结果集,数组pa…...

基于BES系列蓝牙耳机NTC充电电池保护电路设计
+hezkz17进数字音频系统研究开发交流答疑 一 在充电电路中NTC作用? 在充电电路中,NTC(Negative Temperature Coefficient)热敏电阻通常被用于温度检测和保护。它具有随温度变化而变化的电阻值。 以下是NTC在充电电路中的几种常见作用: 温度监测:NTC热敏电阻可以用来测量…...
13-C++算法笔记-递归
📚 Introduction 递归是一种常用的算法设计和问题求解方法。它基于问题可以分解为相同类型的子问题,并通过解决子问题来解决原始问题的思想。递归算法在实际编程中具有广泛的应用。 🎯 递归算法解决问题的特点 递归算法具有以下特点&#…...

从古代八卦探究计算机的八进制
八进制,即八卦,是中国古代哲学体系中非常重要的一个概念,它被广泛应用于易经、道家、儒家等诸多领域。随着计算机科学的快速发展,人们开始思考:八进制是否可以应用到计算机上? 一、什么是八进制࿱…...
Linux shell mkfs.ext4命令参数使用
mkfs mkfs是个综合命令 mkfs 然后按两下tab 查看系统支持哪些文件系统的格式化功能 mkfs -t 文件系统格式名 以指定的文件系统格式来进行磁盘格式化 > 等于 mkfs.文件系统格式名 比如: mkfs -t xfs mkfs.xfs 常见的磁盘格式…...

【Docker】子系统与其相关名词的界定、Control Groups等详细讲解
前言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 📕作者简介:热…...
spring事务的传播性与隔离性
spring事务的传播性 REQUIRED(必须的)(TransactionDefinition.PROPAGATION_REQUIRED) 使用当前的事务,如果当前没有事务,则自己新建一个事务,子方法是必须运行在一个事务中的,如果当前存在事务,…...

【设计模式】模板方法与策略模式的结合使用
文章目录 1. 概述1.1.简述模板方法 2.模板方法实现2.1.简单实现2.2.在SpringBoot中的实现 3.模板方法与策略模式的结合使用3.1.代码实现 4.总结 1. 概述 模板方法是一种非常简单的设计模式,只要能够理解面向对象中的继承与多态就能够理解这种设计模式,我…...

Jmeter实现参数加密
目录 一、使用__digest自带函数 以md5加密算法演示使用方法 二、在BeanShell 中使用JAVA代码实现算法加密 规避BUG的方法 JMeter有两种方法可以实现算法加密 一、使用__digest自带函数 参数说明: Digest algorithm:算法摘要,可输入值&a…...
Solon Web 开发:四、认识请求上下文(Context)
Handler Context 架构,是Solon Web 的基础。在 Context (org.noear.solon.core.handle.Context)里可以获取: 请求相关的对象与接口会话状态相关的对象与接口响应相关的对象与接口 或者理解所有请求与响应相关的,都在…...

docker安装RocketMQ(附填坑经验connect to <172.17.0.3:10909> failed)
目录 一、docker部署RocketMQ1、简易说明2、docker拉取RocketMQ镜像\RocketMQ控制台3、获取RocketMQ配置文件4、RocketMQ配置文件描述5、docker启动RocketMQ6、进入RocketMQ控制台 二、填坑经验错误一: connect to <172.17.0.3:10909> failed错误二: maybe your broker m…...

GRU、LSTM、注意力机制(第八次组会)
GRU、LSTM、注意力机制(第八次组会) 一、 GRU二、 LSTM三、 深度RNN、双向RNN四、 注意力机制一、 GRU 二、 LSTM 三、 深度RNN、双向RNN...
问题杂谈(三十六)@RequestBody、@RequestParam和@PathVariable三个注解的区别和使用
总结: 在后端的同一个接收方法里,RequestBody与RequestParam()可以同时使用RequestBody最多只能有一个,而RequestParam()可以有多个RequestBody 接收的是请求体里面的数据,所以一般用POST请求;而RequestParam接收的是…...

Flutter学习四:Flutter开发基础(六)调试Flutter应用
目录 0 引言 1 调试Flutter应用 1.1 日志与断点 1.1.1 debugger() 声明 1.1.2 print和debugPrint 1.1.3 调试模式、中间模式、发布模式 1.1.4 断点 1.2 调试应用程序层 1.2.1 转储Widgets树 1.2.2 转储渲染树 1.2.3 转储Layer树 1.2.4 转储语义树 1.2.5 调度&…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...

如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...