建立 swap 的方式
Step #1
先建立一個 2G 空白的檔案以供 swap 使用 (以 root 身份操作)
$ dd if=/dev/zero of=/swapfile bs=1M count=2048 2048+0 records in 2048+0 records out 2147483648 bytes (2.1 GB) copied, 6.6971 s, 321 MB/s或
$ fallocate -l 2G /swapfile
Step #2
設定 /swapfile 檔案只限 root 才能讀寫
$ chmod 0600 /swapfile
Step #3
將 /swapfile 檔案設定為 swap格式
$ mkswap /swapfile
Step #4
正式啟用 swap
$ swapon /swapfile
若想重開機就要自動啟用 swap
得在 /etc/fstab 中加這行
/swapfile swap swap defaults 0 0
有關 swap 的使用率
在 /etc/sysctl.conf 檔案中可以設定vm.swappiness=30 (有可能沒這一行,自行加上)
再執行 sysctl -p 生效
0~100, CentOS 7 內定是 30
數字越大,表示系統會越積極使用 swap
所以 vm.swappiness=0 就表示禁止使用 swap
據說設定 0 並非「完全禁用swap」而是盡量、盡量、盡量不使用 swap !!
==>設為 0 時,當作業系統記憶體不足時,可能造成記憶體用量大的程式 (如 mysqld ) 優先被作業系統砍掉 oom (Out Of Memory) !! 要小心!!
查看目前的 swappiness 值
$ cat /proc/sys/vm/swappiness 30
另,可以這樣馬上生效
$ echo 50 > /proc/sys/vm/swappiness
參考 :
5.5. 微調虛擬記憶體 - Red Hat
關於 Swap 的大小
可參考 RedHat 的建議https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/storage_administration_guide/ch-swapspace
Amount of RAM in the system | Recommended swap space | Recommended swap space if allowing for hibernation |
---|---|---|
⩽ 2 GB | 2 times the amount of RAM | 3 times the amount of RAM |
> 2 GB – 8 GB | Equal to the amount of RAM | 2 times the amount of RAM |
> 8 GB – 64 GB | At least 4 GB | 1.5 times the amount of RAM |
> 64 GB | At least 4 GB | Hibernation not recommended |
查詢 swap 的使用情形:
$ swapon -s
Filename Type Size Used Priority
/mnt/ssd0/swapfile1 file 16777212 9131372 -1
$ free -h
total used free shared buff/cache available
Mem: 29G 25G 258M 1.2G 3.7G 2.4G
Swap: 15G 8.7G 7.3G
查詢各個 process 占用 swap 的量
找出那些 process 占用大量 swaphttp://northernmost.org/blog/find-out-what-is-using-your-swap/
getswap.sh
#!/bin/bash # Get current swap usage for all running processes # Erik Ljungstrom 27/05/2011 SUM=0 OVERALL=0 for DIR in `find /proc/ -maxdepth 1 -type d | egrep "^/proc/[0-9]"` ; do PID=`echo $DIR | cut -d / -f 3` PROGNAME=`ps -p $PID -o comm --no-headers` for SWAP in `grep Swap $DIR/smaps 2>/dev/null| awk '{ print $2 }'` do let SUM=$SUM+$SWAP done echo "PID=$PID - Swap used: $SUM - ($PROGNAME )" let OVERALL=$OVERALL+$SUM SUM=0 done echo "Overall swap used: $OVERALL"
這個script 必需以 root 身份執行,執行結果類似:
PID=21477 - Swap used: 0 - (httpd )
PID=21935 - Swap used: 0 - (httpd )
PID=21936 - Swap used: 0 - (httpd )
PID=25008 - Swap used: 0 - (httpd )
PID=25388 - Swap used: 20840 - (memcached )
PID=25731 - Swap used: 13837 - (searchd )
PID=27776 - Swap used: 0 - (kworker/5:0 )
PID=30811 - Swap used: 0 - (kworker/4:1 )
PID=31445 - Swap used: 0 - (kworker/2:2H )
PID=31493 - Swap used: 292 - (mysqld_safe )
PID=32023 - Swap used: 0 - (kworker/2:1H )
PID=32127 - Swap used: 77964 - (mysqld )
PID=32306 - Swap used: 0 - (named )
Overall swap used: 2400564
用這個命令 顯示排序過的資料,比較好閱讀
$ ./getswap.sh | egrep -v "Swap used: 0" |sort -n -k 5 :: :: :: PID=22691 - Swap used: 3472 - (manage_accounts ) PID=1123 - Swap used: 3676 - (manage_addresse ) PID=294 - Swap used: 3888 - (systemd-journal ) PID=1120 - Swap used: 5084 - (manage_accounts ) PID=846 - Swap used: 9544 - (polkitd ) PID=1119 - Swap used: 9936 - (tuned ) PID=1095 - Swap used: 12232 - (dhclient ) PID=466 - Swap used: 15752 - (firewalld ) PID=25388 - Swap used: 20840 - (memcached ) PID=25731 - Swap used: 13837 - (searchd ) PID=1 - Swap used: 35500 - (systemd ) PID=32127 - Swap used: 77964 - (mysqld )
另外,用 top 程式也可以類似功能
執行 top 後,按 f 跳到如下畫面
Fields Management for window 1:Def, whose current sort field is %CPU
Navigate with Up/Dn, Right selects for move then <Enter> or Left commits,
'd' or <Space> toggles display, 's' sets sort. Use 'q' or <Esc> to end!
* PID = Process Id TIME = CPU Time
* USER = Effective User Name * SWAP = Swapped Size (KiB) 游標移到這裡,按空白鍵
* PR = Priority CODE = Code Size (KiB)
* NI = Nice Value DATA = Data+Stack (KiB)
* VIRT = Virtual Image (KiB) nMaj = Major Page Faults
* RES = Resident Size (KiB) nMin = Minor Page Faults
* SHR = Shared Memory (KiB) nDRT = Dirty Pages Count
* S = Process Status WCHAN = Sleeping in Function
* %CPU = CPU Usage Flags = Task Flags <sched.h>
* %MEM = Memory Usage (RES) CGROUPS = Control Groups
* TIME+ = CPU Time, hundredths SUPGIDS = Supp Groups IDs
* COMMAND = Command Name/Line SUPGRPS = Supp Groups Names
PPID = Parent Process pid TGID = Thread Group Id
UID = Effective User Id ENVIRON = Environment vars
RUID = Real User Id vMj = Major Faults delta
RUSER = Real User Name vMn = Minor Faults delta
SUID = Saved User Id USED = Res+Swap Size (KiB)
SUSER = Saved User Name nsIPC = IPC namespace Inode
GID = Group Id nsMNT = MNT namespace Inode
GROUP = Group Name nsNET = NET namespace Inode
PGRP = Process Group Id nsPID = PID namespace Inode
TTY = Controlling Tty nsUSER = USER namespace Inode
TPGID = Tty Process Grp Id nsUTS = UTS namespace Inode
SID = Session Id
nTH = Number of Threads
P = Last Used Cpu (SMP)
再按 q 返回 top 主畫面
就可以看到各 process 的 swap 使用量
Tasks: 95 total, 1 running, 94 sleeping, 0 stopped, 0 zombie top - 16:51:03 up 1 day, 9:16, 1 user, load average: 0.12, 0.07, 0.13 Tasks: 99 total, 1 running, 98 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.0 us, 5.9 sy, 0.0 ni, 94.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 7494428 total, 3448312 free, 1481176 used, 2564940 buff/cache KiB Swap: 8388604 total, 8388604 free, 0 used. 5686356 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND SWAP 1850 mysql 20 0 6013868 839088 9128 S 1.5 11.2 10:00.85 mysqld 77967 1181 root 20 0 1730560 1.371g 316 S 1.7 4.7 3612:26 memcached 31144 17 root 20 0 0 0 0 S 0.7 0.0 5361:41 rcu_sched 0 19376 www 20 0 4311124 800308 37436 S 0.7 2.6 162:26.99 httpd 0 18 root 20 0 0 0 0 S 0.3 0.0 1573:46 rcuos/0 0 20 root 20 0 0 0 0 S 0.3 0.0 1571:28 rcuos/2 0 22 root 20 0 0 0 0 S 0.3 0.0 1382:15 rcuos/4 0 23 root 20 0 0 0 0 S 0.3 0.0 1148:53 rcuos/5 0 24 root 20 0 0 0 0 S 0.3 0.0 1386:56 rcuos/6 0 500 root 0 -20 0 0 0 S 0.3 0.0 320:13.53 kworker/0:1H 0 16493 nobody 20 0 5556776 756068 33764 S 0.3 2.4 124:13.02 httpd 0 19183 nobody 20 0 5516452 884020 37456 S 0.3 2.9 164:48.98 httpd 0 21477 nobody 20 0 5545508 824456 37020 S 0.3 2.7 147:07.38 httpd 0 2 root 20 0 0 0 0 S 0.0 0.0 1:07.09 kthreadd 0 3 root 20 0 0 0 0 S 0.0 0.0 30:35.06 ksoftirqd/0 0 5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H 0 7 root rt 0 0 0 0 S 0.0 0.0 13:32.60 migration/0 0 : : :
還有一個 vmstat 可以持續顯示系統狀態:
$ vmstat 1 20 參數1:秒數,參數2:連續顯示幾次
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 9301876 420408 0 3770532 0 0 179 46 0 0 2 1 96 0 0
0 0 9301876 419852 0 3770884 0 0 296 0 1083 1835 1 1 98 1 0
0 0 9301876 419440 0 3771256 0 0 276 564 1020 1814 1 0 99 0 0
0 0 9301876 419440 0 3771376 0 0 104 0 1306 2331 1 1 98 0 0
0 0 9301876 418200 0 3772672 0 0 1180 248 1974 3424 1 1 97 0 0
0 0 9301876 417524 0 3773180 0 0 808 863 2095 3724 1 1 97 1 0
1 1 9301876 402636 0 3788004 0 0 15112 12 1434 2449 1 1 95 3 0
0 0 9301876 397192 0 3793416 0 0 5120 864 2480 4369 1 1 94 3 0
0 0 9301876 392488 0 3798220 0 0 4772 224 2818 4721 2 1 96 1 0
0 0 9301876 391984 0 3798784 0 0 736 248 2462 4250 2 1 96 1 0
OOM (Out Of Memory)
-
/proc/$PID/oom_adj kernel 2.6.36起 用這個 (可不管oom_score_adj ) 範圍 -1000 ~ 1000
-
/proc/$PID/oom_score oom分數,數字越大 越可能被 Killer 砍掉
-
/proc/$PID/oom_score_adj
參考:理解和配置 Linux 下的 OOM Killer
oomscore.sh
#!/bin/bash printf "PID score process\n" for proc in $(find /proc -maxdepth 1 -regex '/proc/[0-9]+'); do printf "%4d %6d %s\n" \ "$(cat $proc/oom_score)" \ "$(basename $proc)" \ "$(cat $proc/cmdline | tr '\0' ' ' | head -c 50)" done 2>/dev/null | sort -nr | head -n 10
執行結果
$ sh oomscore.sh PID score process 237 32127 /usr/local/mysql/bin/mysqld 30 25388 /usr/local/bin/memcached -d -u root -m 2000 -l 127 18 19183 /home/www/httpd2439/bin/httpd -k start 17 9489 /home/www/httpd2439/bin/httpd -k start 17 21936 /home/www/httpd2439/bin/httpd -k start 17 21477 /home/www/httpd2439/bin/httpd -k start 16 21935 /home/www/httpd2439/bin/httpd -k start 16 19376 /home/www/httpd2439/bin/httpd -k start 16 19182 /home/www/httpd2439/bin/httpd -k start score 數字越大,被系統刪掉的機率越大
怎样避免mysqld被oom-killer杀死?