我有一台虚拟 Linux (Fedora 17) 服务器,配备 28GB RAM 和 2GB 交换空间。该服务器正在运行一个设置为使用大部分 RAM 的 MySQL DB。
运行一段时间后,服务器开始使用 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
如果我使用来自的脚本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
因此,如果我正确获取脚本输出,则总交换使用量应为 449264K = 约 440MB,其中 mysql 使用约 90% 的交换空间。
问题是,为什么这与 top 和 meminfo 数字相差这么大?有没有办法“转储”交换信息以查看其中实际的内容,而不是汇总所有进程的交换使用情况?
在分析这个问题时,我提出了不同的想法,但它们似乎都是错误的:
- 脚本输出不是以 KB 为单位的。即使以 512 或 4KB 为单位,也不会匹配。实际上,比例 (1200:440) 约为 3:1,这是一个“奇怪”的数字。
- 交换区中有一些页面以某种方式在进程之间共享,如https://serverfault.com/a/477664/98204。如果这是真的,我如何才能找到实际使用的内存数量?我的意思是它需要大约 800MB 的差异。在这种情况下,这听起来不对。
- 交换区中有一些“旧”页面,由已完成的进程使用。如果我能找出这个“可释放”交换区有多少,我就不会介意这些。
- 交换区中有一些页面已被交换回内存,并且处于交换区中,以防它们在 RAM 中没有发生变化,需要再次交换出去,如 https://serverfault.com/a/100636/98204。但是SwapCached值只有24MB。
奇怪的是,交换空间使用量在缓慢增加,而脚本输出的总和大致相同。在过去 3 天中,交换空间使用量从 1100MB 增加到当前的 1230MB,而总和从 430MB 增加到当前的 449MB(大约)。
服务器有足够的可用 RAM,所以我可以关闭交换然后再打开。或者我可以将 swappiness 设置为 0,这样只有在没有其他办法的情况下才会使用交换。但我想解决这个问题,或者至少找出导致此问题的原因。
答案1
Fedora 18 及以上版本已包含smem
在 repos 中。你可以从以下位置下载 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
该源还提供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.
答案2
您应该在另一台机器上检查这个脚本,因为我的系统显示正确的交换使用情况:
# Your_script.sh
111280 Total Swap Used
# free
Swap: 33551716 120368 33431348
非常接近 111280 ~= 120368。
另外,看看这个脚本:
对于 /proc/* 中的 proc;执行 cat $proc/smaps 2>/dev/null | awk'/Swap/{swap+=$2}END{打印 swap "\t' '
readlink $proc/exe
"}';完成 | 排序 -n | awk'{total+=$1}/[0-9]/;END{打印 total "\tTotal"}'
来自此主题:
https://unix.stackexchange.com/questions/71714/linux-total-swap-used-swap-used-by-processes