自定义函数查看OS的file cache

简介

在OS中使用cache机制,主要为了提高磁盘的读取效率,避免高频的IO交换。将频繁访问的数据存放在file cache中,下一次在获取的时候就可以直接读取,缓存高命中率对于数据高速检索十分有利。

smem

smem 是一个可以显示 Linux 系统中进程内存使用情况的工具,它可以显示包括进程共享的内存部分,如文件缓存。你可以使用它来查看每个进程的内存使用情况(包括共享内存)。

smem -k 
会有以下字段
PID:监控的进程号
User:监控的进程owner
Command:监控的允许指令
Swap:监控的进程在交换分区(swap)中使用的内存量
USS:监控的进程独占集大小,即该进程唯一占用的内存量,不包括与其他进程共享的内存。这个值表示进程专有的物理内存部分PSS:监控的进程比例集大小,即按比例分摊的共享内存部分。如果两个或多个进程共享同一块内存区域,那么每个进程的 PSS 会分摊这块共享内存的大小。PSS 值为 共享内存的大小 / 共享进程的数量,并加上独占内存。RSS:监控的进程驻留集大小,即进程实际占用的物理内存总量,包括了进程独占的内存和与其他进程共享的内存,但不考虑共享内存的实际使用情况。

smem工具主要是通过解析/proc/{pid}/smaps 文件内容,以进行相应的展示
image.png

查看postgresql 相关进程占用情况

smem -k | grep -E 'User|postgres'

image.png

/proc/{pid}/smaps

系统中每个进程的详细内存映射文件。拥有比smaps 更为详细的信息内容。
以下是postgresql 主进程的

00400000-00c10000 r-xp 00000000 fd:00 1715955                            /home/postgres/pg/bin/postgres
Size:               8256 kB
Rss:                1540 kB
Pss:                 995 kB
Shared_Clean:        756 kB
Shared_Dirty:          0 kB
Private_Clean:       784 kB
Private_Dirty:         0 kB
Referenced:         1540 kB
Anonymous:             0 kB
AnonHugePages:         0 kB
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Locked:                0 kB
ProtectionKey:         0
VmFlags: rd ex mr mp me dw sd
00400000-00c10000 r-xp 00000000 fd:00 1715955 /home/postgres/pg/bin/postgres

00400000-00c10000: 虚拟内存的地址范围,表示此内存段的起始地址(00400000)到结束地址(00c10000)。

r-xp: 这个内存段的权限标识。
r: 可读(Read)。
x: 可执行(Execute)。
p: 私有(Private),表示写入的更改不会共享给其他进程。

00000000: 文件偏移量,表示如果该段映射到文件,文件从哪个偏移开始映射。此处为 00000000,表示从文件开头映射。

fd:00: 设备 ID,指示该文件所在的设备号。

1715955: 该文件的 inode 编号,用于唯一标识文件。

/home/postgres/pg/bin/postgres: 映射的文件路径,表示这个内存段映射的是 Postgres 可执行文件的部分。

Size:

表示这个段在虚拟内存中的总大小。

Rss:

表示已经实际驻留在物理内存中的部分大小,也就是这个段的 1540 KB 已经加载到了 RAM 中。

Pss:

表示按比例分摊的物理内存使用量。如果多个进程共享该内存段,PSS 会根据共享进程数分摊计算。

Shared_Clean:

表示该段有 756 KB 的干净(未修改)内存页被多个进程共享。

Shared_Dirty:

该段的 Shared_Dirty 是 0 KB,表示该段没有被共享的修改页(即未被其他进程修改)。

Private_Clean:

该段的 Private_Clean 是 784 KB,表示该段有 784 KB 的干净(未修改)内存页,仅供当前进程使用,不会与其他进程共享。

Private_Dirty:

该段的 Private_Dirty 是 0 KB,表示该段没有任何私有的修改页。

Referenced:

Referenced 是 1540 KB,表示该段内存自从加载后,已经有 1540 KB 被访问过。

Anonymous:

该段的 Anonymous 是 0 KB,表示该段没有任何匿名内存。匿名内存通常是没有文件映射的内存,通常用于堆和栈空间。

AnonHugePages:

AnonHugePages 是 0 KB,表示该段没有使用巨大页(HugePages),巨大页通常用于提升内存管理效率。

Swap:

Swap 是 0 KB,表示该段内存没有被交换到硬盘(即没有被放入 swap 空间)。

KernelPageSize:

KernelPageSize 是 4 KB,表示内核的页面大小为 4 KB,这是常见的内存页大小。

MMUPageSize:

MMUPageSize 是 4 KB,表示内存管理单元(MMU)的页面大小为 4 KB。通常,KernelPageSize 和 MMUPageSize 是相同的。

Locked:

Locked 是 0 KB,表示这个段内存没有被锁定在物理内存中。被锁定的内存无法被交换到磁盘上。

ProtectionKey:

ProtectionKey 是 0,表示该段没有使用内存保护键。这是与现代 CPU 的内存保护机制相关的字段。

VmFlags: rd ex

VmFlags 表示该段内存的各种标志:
rd: 可读(Readable)。
ex: 可执行(Executable)。
mr: 可被内存管理单元(MMU)读取。
mp: 使用了巨页(HugePage)的页中介表(Page Middle Directory)。
me: 支持内存扩展(Memory Expansion)。
dw: 延迟写入(Delayed Write),通常用于文件系统缓存。
sd: 支持软脏页追踪(Soft Dirty),用于记录内存写入状态。

自定义函数

那就数据库端,写个脚本定时查看其file cache情况

CREATE OR REPLACE FUNCTION compare_data(pid integer)
RETURNS SETOF record AS $$
import redef parse_smaps(pid):smaps_file = f"/proc/{pid}/smaps"rows = []try:with open(smaps_file, 'r') as file:current_entry = {}for line in file:if re.match(r'^[0-9a-f]+-[0-9a-f]+', line):if current_entry:rows.append(generate_row(pid, current_entry))current_entry = {}# Extract start_addr, end_addr, offset, device, inode, and pathparts = line.split()current_entry['start_addr'], current_entry['end_addr'] = parts[0].split('-')current_entry['offset'] = parts[2]current_entry['device'] = parts[3]current_entry['inode'] = parts[4]if len(parts) > 5:current_entry['path'] = parts[5]else:current_entry['path'] = Noneelif line.startswith('Size:'):current_entry['Size'] = line.split()[1]elif line.startswith('Rss:'):current_entry['Rss'] = line.split()[1]elif line.startswith('Pss:'):current_entry['Pss'] = line.split()[1]elif line.startswith('Shared_Clean:'):current_entry['Shared_Clean'] = line.split()[1]elif line.startswith('Shared_Dirty:'):current_entry['Shared_Dirty'] = line.split()[1]elif line.startswith('Private_Clean:'):current_entry['Private_Clean'] = line.split()[1]elif line.startswith('Private_Dirty:'):current_entry['Private_Dirty'] = line.split()[1]elif line.startswith('Referenced:'):current_entry['Referenced'] = line.split()[1]elif line.startswith('Anonymous:'):current_entry['Anonymous'] = line.split()[1]elif line.startswith('AnonHugePages:'):current_entry['AnonHugePages'] = line.split()[1]elif line.startswith('Swap:'):current_entry['Swap'] = line.split()[1]elif line.startswith('KernelPageSize:'):current_entry['KernelPageSize'] = line.split()[1]elif line.startswith('MMUPageSize:'):current_entry['MMUPageSize'] = line.split()[1]elif line.startswith('Locked:'):current_entry['Locked'] = line.split()[1]elif line.startswith('ProtectionKey:'):current_entry['ProtectionKey'] = line.split()[1]elif line.startswith('VmFlags:'):current_entry['VmFlags'] = line.split()[1:]if current_entry:rows.append(generate_row(pid, current_entry))except FileNotFoundError:return []return rowsdef generate_row(pid, entry):# Prepare the row as a tuple to returnreturn (pid, entry.get('start_addr'), entry.get('end_addr'), entry.get('offset'), entry.get('device'),entry.get('inode'), entry.get('path'), entry.get('Size'), entry.get('Rss'), entry.get('Pss'),entry.get('Shared_Clean'), entry.get('Shared_Dirty'), entry.get('Private_Clean'), entry.get('Private_Dirty'),entry.get('Referenced'), entry.get('Anonymous'), entry.get('AnonHugePages'), entry.get('Swap'),entry.get('KernelPageSize'), entry.get('MMUPageSize'), entry.get('Locked'), entry.get('ProtectionKey'),' '.join(entry.get('VmFlags', [])))rows = parse_smaps(pid)
# PL/Python expects a return statement with a list of rows to return them as records
return rows
$$ LANGUAGE plpython3u;

执行函数

SELECT * FROM compare_data(39469) AS t(pid integer, start_addr text, end_addr text, "offset" text, device text, inode text, path text, size text, rss text, pss text, shared_clean text, shared_dirty text, private_clean text, private_dirty text, referenced text, anonymous text, anonhugepages text, swap text, kernelpagesize text, mmupagesize text, "locked" text, protectionkey text, vmflags text);

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/56617.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot比Spring多哪些注解

Spring Boot相对于Spring框架而言,引入了一些特有的注解来简化配置、自动装配组件和实现声明式服务。以下是一些Spring Boot相对于Spring框架特有的主要注解: SpringBootApplication: 作用:标注一个主程序类,表明这是一…

前端怎么实现电子签名

电子签名(e-signature)作为一种数字化的签署方式,广泛应用于合同、协议等文件的确认中。随着科技的发展,前端技术也为电子签名的实现提供了便利。本文将探讨在前端如何实现电子签名,包括技术选型、实现步骤及注意事项。…

【即见未来,为何不拜】聊聊分布式系统中的故障监测机制——Phi Accrual failure detector

前言 昨天在看tcp拥塞控制中的BBR(Bottleneck Bandwidth and Round-trip propagation time)算法时,发现了这一特点: 在BBR以前的拥塞控制算法中(如Reno、Cubic、Vegas),都依赖于丢包事件的发生,在高并发时则会看到网络波动的现象…

uni-app使用v-show编译成微信小程序的问题

问题 在uni-app使用v-show语法编译成微信小程序会有一个问题 当我们设置成v-show"false" 在Hbuilder X里面确实没有显示 然后运行到 微信开发程序里面 发现显示了出来,说明设置的 v-show"false"没有起作用 解决办法 首先去uniapp官网查看v…

uniapp打包安卓apk步骤

然后安装在手机上就可以啦

【npm问题】报错信息

一、问题 npm ERR! code FETCH_ERROR npm ERR! errno FETCH_ERROR npm ERR! invalid json response body at https://r.cnpmjs.org/npm reason: Invalid response body while trying to fetch https://r.cnpmjs.org/npm: Socket timeout npm ERR! A complete log of this run c…

火狐浏览器 Firefox v131.0.2 第三方tete009编译便携版

火狐浏览器是一款非常优秀的浏览器,它的兼容性和稳定性非常出色,备受全球用户的青睐。Firefox便携版是Firefox浏览器的一个特别版本,它可以在没有安装的情况下使用,非常方便。tete009 Firefox 编译版的启动和加载图片时间是所有火…

985研一学习日记 - 2024.10.17

一个人内耗,说明他活在过去;一个人焦虑,说明他活在未来。只有当一个人平静时,他才活在现在。 日常 1、起床6:00√ 2、健身1个多小时 今天练了二头和背部,明天练胸和三头 3、LeetCode刷了3题 旋转图像&#xff1a…

Ubuntu内存扩容

目录 vmware设置Ubuntu设置查看 读研后发现,Ubuntu的使用量直线上升,之前给配置了20g内存,安装了个ros后,没啥内存了。本文实现给Ubuntu扩容。 vmware设置 这里 我使用别人的截图来演示。 我在这里改成了60 Ubuntu设置 sudo a…

rust不允许在全局区定义普通变量!

文章目录 C 中的全局变量Rust 中的全局变量设计哲学的体现 在 C 和 Rust 中,全局变量的处理方式体现了这两种语言设计哲学上的一些根本性差异: C 中的全局变量 C 允许在全局作用域中定义变量。这些变量在程序的整个生命周期内都存在,从程序开…

JS 分支语句

目录 1. 表达式与语句 1.1 表达式 1.2 语句 1.3 区别 2. 程序三大流控制语句 3. 分支语句 3.1 if 分支语句 3.2 双分支 if 语句 3.3 双分支语句案例 3.3.1 案例一 3.3.2 案例二 3.4 多分支语句 1. 表达式与语句 1.1 表达式 1.2 语句 1.3 区别 2. 程序三大流控制语…

python教程:python中的继承及其使用的案例

在 Python 中,继承是一种面向对象编程的核心概念,允许一个类从另一个类继承属性和方法。通过继承,子类(派生类)可以重用父类(基类)的代码,同时还能扩展或重写父类的功能。继承使代码…

Python知识点:基于Python技术和工具,如何使用Chainlink进行链下数据访问

开篇,先说一个好消息,截止到2025年1月1日前,翻到文末找到我,赠送定制版的开题报告和任务书,先到先得!过期不候! 如何使用Chainlink进行链下数据访问 在区块链开发中,智能合约通常需…

每天花2分钟学数字化转型,第三讲:数智化

​对于智能化(intelligence),我的理解是:你中有我,我中有你「人机一体」的世界。 阅读本文,你将快速知晓“智能化”的定义与价值,通过生活实例让你对智能化有一个全新的理解。 最后还会介绍“…

Vue.js 组件开发基本步骤

Vue.js 是一个构建用户界面的渐进式框架,它被设计为能够轻松地被集成进项目的部分功能,或者用于构建完整的前端应用。组件化是 Vue.js 的核心概念之一,它允许开发者将界面拆分成独立、可复用的组件,每个组件负责应用中的一小部分功…

021 elasticsearch索引管理

文章目录 索引的管理1创建索引库2删除索引3设置mapping创建索引库时定义mapping先创建索引库然后设置mapping 4设置settings创建索引库时设置settings创建索引之后修改settings 概念说明索引库(indexes)索引库包含一堆相关业务,结构相似的文档document数据&#xff…

ROS2中级面试题汇总

大家好,我是小白小帅,继更新了ros2初级面试题汇总之后,我又马不停蹄的整理了关于ros2的中级面试题(共25道),这些问题也相较于初级面试题上升了一定难度,希望小伙伴们打牢ros2基础,如…

键盘突然用不了,怎么处理

文章目录 1、切换输入法试试2、检查键盘的3个指示灯是否全亮 1、切换输入法试试 2、检查键盘的3个指示灯是否全亮 检查键盘的三个指示灯通常指的是 Num Lock、Caps Lock 和 Scroll Lock 键的状态灯 检查键盘的三个指示灯通常指的是 Num Lock、Caps Lock 和 Scroll Lock 键的状…

全栈开发小项目

用到的技术栈: nodejswebpackknockoutmongodbPM2rabbitmq 以下是一个综合指南,展示如何将 Node.js、Webpack、Knockout.js、MongoDB、PM2 和 RabbitMQ 集成到一个项目中。 我们将在这一项目中添加 RabbitMQ,用于处理消息队列。这对于任务分…

Keil中代码补全功能和自动缩进功能设置

一、自动缩进功能的设置,在按回车键换行或者按Tab键的时候是有缩进的,还可以进行缩进设置。可以通过以下步骤进行设置:①Edit(编辑)->②Configuration(配置)->③Tab size(Tab缩进长度)在T…