PostgreSQL中如何配置Huge page的数量
在了解如在PG中如何配置大页之前,我们先要对大页进行一定的了解,为什么要配置大页,配置大页的好处有哪些。
我们日常的操作系统中,程序不直接使用内存,而是使用虚拟内存地址来处理内存分配,避免计算的复杂性和物理地址映射到应用程序内存空间的复杂性。虚拟地址模型在应用程序读取或写入内存时立即将虚拟地址转换为相应的物理内存地址。这种映射结构存储在page tables中,这是一种分层组织的查找表。
如下图,在运行中的程序使用虚拟内存映射到物理内存

下图为虚拟内存通过page table映射到物理内存

地址转换依靠MMU实现,MMU是内存管理单元,是硬件设备,在CPU内部

如下图,使用MMU使用TLB的加速映射

下图说明了TLB的加速原理,如果物理地址在TLB中命中,直接转换为物理地址,只访问一次内存地址,否则扫描page table查找地址然后映射条目到TLB,然后再转换为物理地址,这样就有两次内存访问。最差的是page table也没有,需要从磁盘写到page table,那么这样效率会更慢。

因为TLB只能保存几千个条目,那么我们为了提高性能,可以有两个办法:
- 增加TLB的大小,升本太高,受限硬件,提升有限
- 增加内存page的大小,如果TLB只能对应512个页表项,那么能否每个page对应1G的内存呢,这样程序访问512G的内存,也能保证都利用到TLB缓存了。
如下图,4K,2MB,1GB在256GB内存下对应的页面数

操作系统上的内存分配都是通过分配单个或多个可用内存页来完成的。这些页面都是特定大小,主要取决于操作系统。在Linux上,内存分配使用的默认页面大小是4kB。
因此,我们可以想象,分配大量内存需要在页表中保存大量页面,以便将它们映射到相应的物理地址。查找虚拟地址需要多次内存访问,与CPU速度相比,这是非常昂贵的。因此,cpu现在维护一个叫Translation Lookaside Buffer (TLB)的缓存,TLB是一个加速虚拟内存和物理内存之间转换的缓存。
TLB的大小被限制在几千个条目,特别是在具有高内存特定内存工作负载的系统上,很快就会成为瓶颈。例如,像PostgreSQL这样的数据库使用共享缓存池来实现进程间通信(IPC)、块层访问和其他功能,这很快就会给TLB带来很大的压力,因为虚拟地址映射的数量是有限的。特别是共享缓冲池配置大内存(比如100GB的shared buffer)的时候,这些实例可能因此受到性能影响。
所以我们在内存很大的时候,比如有256G内存,可以设置huge page,提高效率。在x86系统上,我们通常可以设置2MB或1GB大小,IBM POWER允许64kB、16MB和16GB。
在x86架构中,配置大页时,默认的页面大小是2MB。可以通过/proc/meminfo获取你的系统当前设置:
cat /proc/meminfo | grep -i HugePage
AnonHugePages: 161792 kB
ShmemHugePages: 0 kB
FileHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
HugePages_Total为零表示目前没有配置大页面,因此HugePages_Rsvd,HugePages_Free和HugePages_Surp也都为零。Hugepagesize显示了内核中当前为大页面配置的默认大小。在稍后配置大页时,我们将会考虑如何设置这些值。
如下图,可以通过查看/proc/cpuinfo中的flages,是否支持各种大页的尺寸

PG中大页的使用
PostgreSQL中,只有shared buffer中可以使用大页来分配内存。而work_mem, maintenance_work_mem, autovacuum_work_mem这些动态内存的分配不会使用大页。此外,用于在并行查询工作之间传输数据和通信的动态共享内存段不会自动请求它们,但有一个例外,我将在下一段关于在Linux上为大型页面配置PostgreSQL的内容中描述。还需要在所谓的mmap段中分配共享缓冲区,这是由shared_memory_type参数控制的。这是Linux上的默认设置。系统V共享内存只被PostgreSQL用来初始化一个非常小的共享内存区域;缓冲池本身是通过mmap分配的。
对于Linux上的PostgreSQL,不建议通过THP配置大页,因为它不会直接分配大页,而是在需要时提供给它们。THP是可切换的,与显式配置的大页相比,它被认为是一个较慢的选择。在这种情况下,FreeBSD等其他操作系统提供了更好的支持。
在PG15中,数据库关闭状态,可以通过命令直接计算需要大页大小,如下:
su - postgres/usr/pgsql-15/bin/postgres --shared-buffers=20GB -D $PGDATA -C shared_memory_size_in_huge_pages
10475
PG中通过huge_pages参数配置是否开启大页
try:尝试分配大页,如果不能,则退回到正常的页面分配(目前的默认设置)
on:shared buffer强制使用大页
off:不使用大页
上面计算出需要设置的大页数后,可以通过修改文件来修改大页数量,注意只是临时修改吗,重启无效
echo 10475 > /proc/sys/vm/nr_hugepages
再次查看大页设置:
grep -i hugepage /proc/meminfo
AnonHugePages: 124928 kB
ShmemHugePages: 0 kB
FileHugePages: 0 kB
HugePages_Total: 10475
HugePages_Free: 10475
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
永久修改配置:
cat /etc/sysctl.d/01-nr-hugepages.conf
vm.nr_hugepages=10475
修改 postgresql.conf文件中以下参数
shared_buffers = 20GB
huges_pages = on
huge_page_size = 0 #use default kernel setting
PostgreSQL必须启动(或重新启动),并且应该通过默认的大页大小分配其共享缓冲池。查看/proc/meminfo信息。输出如下:
grep -i hugepage /proc/meminfo
AnonHugePages: 176128 kB
ShmemHugePages: 0 kB
FileHugePages: 0 kB
HugePages_Total: 10475
HugePages_Free: 10264
HugePages_Rsvd: 10264
HugePages_Surp: 0
Hugepagesize: 2048 kB
使用pmap工具可以查看postmaster进程分配的内存段
pmap $(head -n1 /var/lib/pgsql/15/data/postmaster.pid) | grep huge
00007f11a5400000 21452800K rw-s- anon_hugepage (deleted)
在PostgreSQL如何使用大页面的一节中,我们应该解释一下那里提到的异常。通常,动态共享内存分配是有目的的,例如并行查询工作者处理并行查询时。默认情况下,这些动态分配的内存不是由mmap完成的,而是PostgreSQL在Linux上默认通过shm_open()使用posix API。在这种情况下,不分配大页。但是,在并行查询时,也会产生内存压力,特别是在需要处理大量数据时。
从版本14开始,PostgreSQL提供了参数min_dynamic_shared_memory。配置后,指定的值定义了在服务器启动时创建的共享内存中的额外空间,这些空间应该用于并行查询工作。由于它是与缓冲池一起分配的,因此它也使用了大页进行分配。我们可以扩展上面的例子,并重新计算设置2GB的额外共享内存,用于并行查询:
/usr/pgsql-15/bin/postgres -D $PGDATA --min-dynamic-shared-memory=2GB --shared-buffers=20GB -C shared_memory_size_in_huge_pages
11499
同样,需要停止PostgreSQL实例才能成功执行该命令。与前一个示例相比,现在要保留的大页面的数量增加了2GB。
如果PG版本低于15怎么办?
这些版本更难处理。特别是需要保留多少大页的计算比较麻烦。到目前为止,最好的解决方案就是手动启动PostgreSQL,设置huge_pages=on,然后调试参数。在这种情况下,如果不能分配请求的共享内存大小,PostgreSQL打印以下错误消息:
FATAL: could not map anonymous shared memory: Cannot allocate memory
HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently 21965570048 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.
LOG: database system is shut down
注意HINT部分,它告诉我们PostgreSQL想要分配21965570048字节的共享内存。这个值可以用来计算页面的数量。这个数字的问题是,当我们将共享缓冲区指定为20GB时,这比我们所要求的大一些。这是因为PostgreSQL还需要为其他内部进程(如wal_buffers或max_locks_per_transactions)提供额外的共享内存。扩展可能需要额外的共享
内存。PostgreSQL内部使用了一个近似如下的公式:
((shm size + (BLKSZ - (shm size % BLKSZ))) / (huge page size * 1024)) + 1 = num huge pages
#假设我们的数据库的BLKSZ是以8KB的page编译安装的
((21965570048 + (8192 - (21965570048 % 8192))) / (2048 * 1024)) + 1 = 10475
track_activity_query_size设置
另外要注意track_activity_query_size的设置,默认1024,如果超过,那么pg_stat_activity,pg_stat_statements中记录sql的长度会被截断。但是一定要注意,如果加大该设置,会分配max_connections * track_activity_query_size的内存来保存我们的语句。

如上所述,PostgreSQL使用共享内存来存储这些统计信息。PostgreSQL不能动态更改内存段的大小。因此,更改track_activity_query_size也需要重新启动PostgreSQL。所以在启用实例前,一定要考虑好如何设置该参数。另外还要注意,该参数设置大了,那么pg_stat_statements也会变大,可能也会影响系统性能,一定要注意定期使用该函数重置pg_stat_statements_reset
参考:
https://courses.teresco.org/cs432_f02/lectures/12-memory/12-memory.html
https://www.cybertec-postgresql.com/en/huge-pages-postgresql/
https://www.cybertec-postgresql.com/en/fixing-track_activity_query_size-in-postgresql-conf/
相关文章:
PostgreSQL中如何配置Huge page的数量
在了解如在PG中如何配置大页之前,我们先要对大页进行一定的了解,为什么要配置大页,配置大页的好处有哪些。 我们日常的操作系统中,程序不直接使用内存,而是使用虚拟内存地址来处理内存分配,避免计算的复杂…...
Mysql之binlog日志浅析
一、binlog日志简介 Binlog是MySQL数据库中的二进制日志,用于记录数据库中所有修改操作,包括增删改等操作。binlog以二进制格式保存,可以通过解析binlog文件来查看数据库的操作历史记录。binlog日志可以用于数据恢复、数据备份、数据同步等场…...
js 生成器函数
生成器函数(Generator Function):生成器函数是一种特殊的函数,可以通过yield关键字来暂停和恢复函数的执行,从而实现惰性计算和迭代器的功能。在例子中,我们定义了一个fibonacci生成器函数,它使…...
HCIP OSPF+BGP综合实验
题目 1、该拓扑为公司网络,其中包括公司总部、公司分部以及公司骨干网,不包含运营商公网部分。 2、设备名称均使用拓扑上名称改名,并且区分大小写。 3、整张拓扑均使用私网地址进行配置。 4、整张网络中,运行OSPF协议或者BGP协议…...
牛客网Verilog刷题——VL46
牛客网Verilog刷题——VL46 题目解析答案 题目 根据题目提供的双口RAM代码和接口描述,实现同步FIFO,要求FIFO位宽和深度参数化可配置。电路的接口如下图所示。 双口RAM端口说明: 同步FIFO端口说明: 双口RAM代码如下ÿ…...
C/C++开源库推荐
C/C开源库推荐 主要都是平常用到的,包含windows开发、android开发、后台开发、音视频开发、深度学习等等最后还附带几个其他语言开发的比较好的项目 GUI开发 qt 跨平台开发库,内部封装了各种跨平台工具,但是大多数情况下都被用作开发跨平台…...
git常用命令速查表
1.git add -u [<路径>]: 把<路径>中所有跟踪(tracked)文件中被修改过或已删除文件的信息添加到索引库。它不会处理未跟踪(untracked)的文件。省略<路径>表示:即当前目录。 2.git add -a [<路径&…...
让两个文件夹里的图片名字一模一样
为了做测试集,对应数据和真值 import os import datetimeimage_names os.listdir(r\Images) #print(image_names) #print(len(image_names))mask_names os.listdir(rG:\Mask) #print(mask_names) #print(len(mask_names))#根据你提供的文件名排序结果来看,问题可…...
会议OA系统会议管理模块开发思路(layui搭建)
目录 一.为什么要进行开发 1.开发目的 2.项目流程 A.发起会议请求过程 1.首先实现我们的多选下拉框功能! 2.时间组件功能,并且提交我们新增加的会议内容 3.在进行发起会议编码时遇到的问题,BUG 3.1.有点时候js访问不到路径 3.2在增加…...
rsync 远程同步
目录 一、Rsync 简介 二、同步方式 备份的方式 三、常用Rsync命令 四、配置源的两种表达方法 五、配置服务端与客户端的实验 启动 rsync 服务程序 发起端(192.168.158.21) 编辑 六. 发起端(客户端)配置 rsyncinotify c…...
PostgreSQL数据库中,查询时提示表不存在的解决办法
最近遇到一个奇怪的问题,以前从来没有遇到过,在postgres SCHEMA下执行select * from table1语句时,提示表不存在,而实际这个表确是存在的,只不过是在public SCHEMA下。在public SCHEMA下执行这个sql语句是没有问题的。…...
视频传输网安全防护体系
在电脑、手机信息安全保护得到广泛关注和普及的今天,监控摄像头等设备的安全防护仍为大众所忽略,大量视频监控网络的前端设备和数据没有任何保护,完全暴露在互联网中。 前端IP接入设备与后端业务系统处于直连状态,一旦有攻击者或…...
C# Blazor 学习笔记(1):Blazor基础语法,组件化和生命周期
文章目录 前言基础语法路由Page 页面元素条件生成if / elseforforeach 绑定参数绑定(赋值,单向)参数绑定(双向)事件绑定字典绑定 attributes 组件化如何使用Parameter 参数注入使用回调函数组件声明回调组件注入回调组…...
flutter 导出iOS问题2
问题1:The Swift pod FirebaseCoreInternal depends upon GoogleUtilities, which does not define modules. To opt into those targets generating module maps (which is necessary to import them from Swift when building as static libraries) 参考 正如上图报错第三方…...
syn报文什么时候会被丢弃?
开启tcp_tw_recycle且在NAT下 tcp_tw_recycle重复利用time_wait sockets,会记录最近的连接时间戳,并丢弃远程主机(PAWS机制)所有不严格大于该时间戳的报文。这意味着如果主机在nat下,那么该nat下所有设备将会受影响 TCP半连接队列满了 在半…...
【C++】开源:Linux端V4L2视频设备库
😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍Linux端V4L2视频设备库。 无专精则不能成,无涉猎则不能通。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下…...
基于数据驱动的多尺度表示的信号去噪统计方法研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
【Golang】Golang进阶系列教程--Go 语言 map 如何顺序读取?
文章目录 前言现象原因如何顺序读取推荐阅读 前言 Go 语言中的 map 是一种非常强大的数据结构,它允许我们快速地存储和检索键值对。 然而,当我们遍历 map 时,会有一个有趣的现象,那就是输出的键值对顺序是不确定的。 现象 先看…...
伊语IM即时通讯源码/im商城系统/纯源码IM通讯系统安卓+IOS前端纯原生源码
伊语IM即时通讯源码/im商城系统/纯源码IM通讯系统安卓IOS前端纯原生源码, 后端是java源码。...
C++推理
YOLOv5 OpenCV DNN C导出的 ONNX 模型示例的推理: https://github.com/Hexmagic/ONNX-yolov5/blob/master/src/test.cpphttps://github.com/doleron/yolov5-opencv-cpp-python YOLOv5 OpenVINO C推理示例: GitHub - dacquaviva/yolov5-openvino-cpp-p…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...
