PostgreSQL 教程: 计算内存使用量

一月 17, 2024

摘要:在本教程中,您将学习如何计算 PostgreSQL 的内存使用量。

PostgreSQL 架构

PostgreSQL 的架构基于三个基本部分:进程、内存和磁盘。

内存可分为两类:

  • 本地内存:由每个后端进程加载,供自己用于查询处理。它分为以下子类:
    • 工作内存:工作内存用于按 ORDER BY 和 DISTINCT 操作对元组进行排序,以及连接表。
    • 临时缓冲区:用于存储临时表。
    • 本地缓存:用于缓存执行计划、关系和系统表信息。
  • 共享内存:由 PostgreSQL 服务器在启动时分配,供所有进程使用。它分为以下子类:
    • 共享缓冲池:PostgreSQL 从磁盘加载包含表和索引的页面,以直接从内存工作,从而减少磁盘访问。
    • WAL 缓冲区:WAL 数据是 PostgreSQL 中的事务日志,包含了在数据库中进行的更改。WAL 缓冲区是在将 WAL 数据写入磁盘到 WAL 文件之前临时存储的区域。在提交事务的时候,PostgreSQL 会刷写 WAL 数据到磁盘。这对于避免在服务器发生故障时丢失信息非常重要。

Linux 进程 smaps 文件

/proc/PID/smaps 是一个基于 maps 文件的扩展,它会显示每个进程映射的内存消耗。对于每个映射(又名虚拟内存区域或 VMA),有一系列行,如下所示:

00400000-00914000 r-xp 00000000 09:00 3545633                            /usr/pgsql/bin/postgres
Size:               5200 kB
Rss:                 964 kB
Pss:                 214 kB
Shared_Clean:        964 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         0 kB
Referenced:          964 kB
Anonymous:             0 kB
AnonHugePages:         0 kB
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Locked:                0 kB
00b13000-00b14000 r--p 00513000 09:00 3545633                            /usr/pgsql/bin/postgres
Size:                  4 kB
Rss:                   4 kB
Pss:                   0 kB
Shared_Clean:          0 kB
...

其中第一行显示的信息与 /proc/PID/maps 中显示的映射信息相同。以下几行显示了映射的大小(size);支持 VMA 时分配的每个页面的大小(KernelPageSize),通常与页表条目中的大小相同;支持 VMA 时 MMU 使用的页面大小(在大多数情况下,与 KernelPageSize 相同);当前驻留在 RAM 中的映射量(RSS);该进程在此映射中的比例份额(PSS);以及映射中干净和弄脏的共享页面和私有页面的数量。

一个进程的 “比例集大小”(PSS)是它在内存中的页面数,其中每个页除以共享它的进程数。因此,如果一个进程有 1000 个私有页面,还有 1000 个页面与另外一个进程共享,则其 PSS 将为 1500。“Pss_Dirty” 是 PSS 中由脏页组成的部分。

内存使用量计算

要在 Linux 上计算 PostgreSQL 进程的内存使用量,请执行以下操作:

ps -u postgres o pid= | \
sed 's# *\(.*\)#/proc/\1/smaps#' | \
xargs sudo grep ^Pss: | \
awk '{A+=$2} END{print A}'
  • 首先,获取用户postgres下运行的所有进程的进程 PID

  • 然后获取每个进程的相应smaps文件(/proc/PID/smaps)的名称

  • 然后从该文件中获取Pss行,该行包含了 “比例堆栈大小”,它将共享内存除以附加到它的进程数

  • 最后,将数字相加