如何查找使用 linux 交换的内容或交换中的内容?

Rad*_*dík 12 linux memory fedora swap

我有一个带有 28GB RAM 和 2GB 交换空间的虚拟 linux(Fedora 17)服务器。服务器正在运行一个 MySQL 数据库,该数据库设置为使用大部分 RAM。

运行一段时间后,服务器开始使用 swap 来换出未起诉的页面。这很好,因为我的 swappiness 默认为 60,这是预期的行为。

奇怪的是 top/meminfo 中的数字与来自进程的信息不对应。即服务器报告这些数字:

/proc/meminfo:
SwapCached:        24588 kB
SwapTotal:       2097148 kB
SwapFree:         865912 kB

top:
Mem:  28189800k total, 27583776k used,   606024k free,   163452k buffers
Swap:  2097148k total,  1231512k used,   865636k free,  6554356k cached
Run Code Online (Sandbox Code Playgroud)

如果我使用https://serverfault.com/a/423603/98204 中的脚本,它会报告合理的数字(bash'es、systemd 等交换的几 MB)和 MySQL 的一大笔分配(我省略了很多输出行):

892        [2442] qmgr -l -t fifo -u
896        [2412] /usr/libexec/postfix/master
904        [28382] mysql -u root
976        [27559] -bash
984        [27637] -bash
992        [27931] SCREEN
1000       [27932] /bin/bash
1192       [27558] sshd: admin@pts/0
1196       [27556] sshd: admin [priv]
1244       [1] /usr/lib/systemd/systemd
9444       [26626] /usr/bin/perl /bin/innotop
413852     [31039] /usr/libexec/mysqld --basedir=/usr --datadir=/data/mysql --plugin-dir=/usr/lib64/mysql/plugin --log-error=/data/mysql/err --open-files-limit=8192 --pid-file=/data/mysql/pid --socket=/data/mysql/mysql.sock --port=3306
449264   Total Swap Used
Run Code Online (Sandbox Code Playgroud)

所以如果我得到正确的脚本输出,总交换使用量应该是 449264K = ca。440MB 与 mysql 使用 ca。90% 的交换。

问题是为什么这与 top 和 meminfo 数字相差如此之大?有什么方法可以“转储”交换信息以查看其中的实际内容,而不是汇总所有进程的交换使用情况?

在分析问题时,我提出了不同的想法,但它们似乎都是错误的:

  1. 脚本输出不是以 KB 为单位的。即使它以 512 或 4KB 为单位,它也不会匹配。实际上比率 (1200:440) 大约是 3:1,这是一个“奇怪”的数字。
  2. https://serverfault.com/a/477664/98204 中所述,交换中有一些页面以某种方式在进程之间共享。如果这是真的,我怎样才能找到这样使用的实际内存数量?我的意思是它需要使 cca 800MB 不同。在这种情况下,这听起来并不正确。
  3. 已经完成的进程使用了​​交换中的一些“旧”页面。如果我能够找出这个“可免费”交换的金额,我不会介意。
  4. 交换中的页面已被交换回内存,并且处于交换状态,以防它们在 RAM 中没有更改并且需要再次交换,如 https://serverfault.com/a/100636/98204 中所述。但是 SwapCached 值只有 24MB。

奇怪的是,swap 使用率在缓慢增加,而脚本的总和输出大致相同。在过去 3 天内,使用的交换从 1100MB 增加到当前的 1230MB,而总和从 430MB 增加到当前的 449MB(大约)。

服务器有足够的空闲(可用)RAM,所以我可以关闭交换并重新打开它。或者我可以将 swappiness 设置为 0,这样只有在没有其他方法时才会使用交换。但我想解决这个问题,或者至少找出造成这种情况的原因。

小智 9

Fedora 18 及更高版本已smem在存储库中。您可以下载 python 脚本并从源代码安装。

这是我的机器的示例输出(有些剪断和匿名):

# smem -s swap -t -k -n
  PID User     Command                         Swap      USS      PSS      RSS 
20917 1001     bash                               0     1.1M     1.1M     1.9M 
28329 0        python /bin/smem -s swap -t        0     6.3M     6.5M     7.4M 
 2719 1001     gnome-pty-helper               16.0K    72.0K    73.0K   516.0K 
  619 0        @sbin/mdadm --monitor --sca    28.0K    72.0K    73.0K   248.0K 

[big snip]

32079 42       gnome-shell --mode=gdm         41.9M     1.9M     2.0M     5.0M 
32403 1001     /opt/google/chrome/chrome -    43.1M   118.5M   119.4M   132.3M 
 4844 1002     /opt/google/chrome/chrome      48.1M    38.1M    41.9M    51.9M 
 5411 1002     /opt/google/chrome/chrome -    54.6M    33.4M    33.5M    36.8M 
 5624 1002     /opt/google/chrome/chrome -    72.4M    54.9M    55.5M    65.7M 
24328 1002     /opt/Adobe/Reader9/Reader/i    77.5M     1.9M     2.0M     5.2M 
 4921 1002     /opt/google/chrome/chrome -   147.2M   258.4M   259.4M   272.0M 
-------------------------------------------------------------------------------
  214 14                                       1.1G     1.1G     1.2G     1.7G 
Run Code Online (Sandbox Code Playgroud)

该源还提供smemcap将存储所有相关数据,以便稍后可以在其上运行 smem。

   To  capture  memory statistics on resource-constrained systems, the the
   smem source includes a utility named  smemcap.   smemcap  captures  all
   /proc entries required by smem and outputs them as an uncompressed .tar
   file to STDOUT.  smem can analyze the output using the --source option.
   smemcap is small and does not require Python.
Run Code Online (Sandbox Code Playgroud)


小智 4

您应该在另一台计算机上检查此脚本,因为我的系统显示正确的交换使用情况:

# Your_script.sh
111280   Total Swap Used
# free
Swap:     33551716     120368   33431348
Run Code Online (Sandbox Code Playgroud)

非常接近 111280 ~= 120368。

另外,看看这个脚本:

对于 /proc/* 中的 proc;执行 cat $proc/smaps 2>/dev/null | awk '/Swap/{swap+=$2}END{打印交换 "\t' readlink $proc/exe'"}'; 完成 | 排序 -n | awk '{total+=$1}/[0-9]/;END{打印总计“\tTotal”}'

从这个线程:

https://unix.stackexchange.com/questions/71714/linux-total-swap-used-swap-used-by-processes