作者:付祥

现居珠海,次要负责 Oracle、MySQL、mongoDB 和 Redis 保护工作。

本文起源:原创投稿

*爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。


景象

监控告警某台机器闲暇内存低于10%,执行top命令,按内存降序排序,局部输入如下:

[root@mysql-slaver ~]# toptop - 13:45:43 up 1835 days, 20:52,  2 users,  load average: 0.02, 0.03, 0.05Tasks: 210 total,   1 running, 208 sleeping,   1 stopped,   0 zombie%Cpu(s):  0.5 us,  0.6 sy,  0.0 ni, 98.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 stKiB Mem : 32780028 total,   905684 free, 19957900 used, 11916444 buff/cacheKiB Swap:        0 total,        0 free,        0 used.  3448260 avail Mem   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                             2677 mysql     20   0   20.1g  15.1g   3392 S   0.0 48.2 430:17.58 mysqld                                                             10549 polkitd   20   0 3277476   3.1g    632 S   0.3  9.9 146:47.24 redis-server                                                       18183 root      20   0  877308 215868   1892 T   2.7  0.7   2736:45 xxxxxx  442 root      20   0  160244  93016  88552 S   0.3  0.3 314:14.86 systemd-journal                                                    32537 root      20   0  731620  58360  54588 S   0.3  0.2  29:09.61 rsyslogd

total=32G,used=19G,buff/cache=11G,available=3G,最耗内存过程为 MySQL、Redis,总计约18.2G,其余过程占用内存都比拟低,buff/cache 内存中只有3G是无效的,残余8G内存去哪里?

剖析

执行 free 命令进一步查看:

[root@MySQL-slaver ~]# free -m              total        used        free      shared  buff/cache   availableMem:          32011       19490         881        8762       11639        3366Swap:             0           0           0

其中shared占用居然占用了8G内存,通过man查看帮忙:

shared Memory used (mostly) by tmpfs (Shmem in /proc/meminfo, available on kernels 2.6.32, displayed as zero  if  not  avail‐              able)

        shared Memory来源于/proc/meminfo中Shmem,被tmpfs应用,df -h查看:

[root@MySQL-slaver ~]# df -hFilesystem      Size  Used Avail Use% Mounted ondevtmpfs         16G     0   16G   0% /devtmpfs            16G   16K   16G   1% /dev/shmtmpfs            16G  8.6G  7.1G  55% /runtmpfs            16G     0   16G   0% /sys/fs/cgroup

目录/run应用了8.6G内存,和shared占用内存统一,内存都耗费到哪些子目录了?

[root@MySQL-slaver ~]# du -am /run|sort -rn -k1|head -108761    /run7137    /run/systemd7126    /run/systemd/users1624    /run/log/journal/89308070e0c04c6a86bf577f4064efca1624    /run/log/journal1624    /run/log

内存次要耗费在/run/systemd/users和/run/log/journal目录,占用内存别离为7126M、1624M,较为异样的是/run/systemd/users占用内存过高,持续剖析这个目录下有哪些文件

[root@MySQL-slaver ~]# ls -l /run/systemd/userstotal 44-rw-r--r-- 1 root root 41056 Mar 23 14:14 0

乍一看,只有一个文件占用约40k,这和du统计的差别也太大了吧,是不是有暗藏文件:

[root@MySQL-slaver ~]# find /run/systemd/users|less/run/systemd/users/run/systmd/users/0/run/systemd/users/.#0kRUlqC/run/systemd/users/.#0Qxvu5J/run/systemd/users/.#03DvfrF......[root@MySQL-slaver ~]# find /run/systemd/users|wc -l337632[root@MySQL-slaver ~]# ls -l /run/systemd/users/.#00009iJ-rw-r--r-- 1 root root 20480 Sep 26  2018 /run/systemd/users/.#00009iJ[root@MySQL-slaver ~]# ll /run/systemd/users/.#0SEEqoi-rw-r--r-- 1 root root 20480 Mar 23 14:34 /run/systemd/users/.#0SEEqoi[root@MySQL-slaver ~]# uptime 14:45:13 up 1835 days, 21:51,  2 users,  load average: 0.02, 0.08, 0.12

不看不晓得,一看吓一跳,暗藏文件数高达30w+,最早的文件有2018年的,最新的文件明天产生的,轻易关上一个文件看看:

[root@MySQL-slaver ~]# less /run/systemd/users/.#03DvfrF# This is private data. Do not parse.NAME=rootSTATE=activeRUNTIME=/run/user/0SLICE=user-0.sliceDISPLAY=4231719REALTIME=1521010223727718MONOTONIC=79029110787SESSIONS=4232100 4232099 4232098 ......

保留的是root用户session信息,loginctl查看session信息:

[root@MySQL-slaver ~]# loginctl list-sessions   SESSION        UID USER             SEAT                 24597          0 root                                 146401          0 root                                 133160          0 root                                  82494          0 root                                  82514          0 root                                 106049          0 root   ......[root@MySQL-slaver ~]# loginctl list-sessions|awk '{print $3}'|sort|uniq -c      1       1 listed.   2131 root      1 USER            

root用户session数居然高达2131个,轻易拿一个session看看:

[root@MySQL-slaver ~]# loginctl session-status 2459724597 - root (0)           Since: Tue 2018-03-27 08:35:01 CST; 4 years 11 months ago          Leader: 25599         Service: crond; type unspecified; class background           State: active            Unit: session-24597.scope[root@MySQL-slaver ~]# 

 crond产生的session,这些session都没有调配相干过程,以后状态为active,按session排序后,筛选最近的session查看,都是2018年产生的:

[root@MySQL-slaver ~]# loginctl session-status 243335243335 - root (0)           Since: Sat 2018-07-14 03:29:01 CST; 4 years 8 months ago          Leader: 28376         Service: crond; type unspecified; class background           State: active            Unit: session-243335.scope[root@MySQL-slaver ~]# 

做了一个定时工作测试,session能失常调配过程,工作实现后session敞开:

Mar 23 15:20:01 [localhost] CROND[12334]: (root) CMD (sleep 1200)[root@MySQL-slaver ~]# loginctl session-status 42322064232206 - root (0)           Since: Thu 2023-03-23 15:20:01 CST; 19min ago          Leader: 12330 (crond)         Service: crond; type unspecified; class background           State: opening            Unit: session-4232206.scope                  ├─12330 /usr/sbin/CROND -n                  └─12334 sleep 1200[root@MySQL-slaver ~]# loginctl session-status 4232206Failed to get session: No session '4232206' known[root@MySQL-slaver ~]# lsof -p `pidof dbus-daemon`|grep sessions|wc -l2126[root@MySQL-slaver ~]# lsof -p `pidof dbus-daemon`|tail -5dbus-daem 560 dbus 2139w     FIFO               0,18      0t0  416861417 /run/systemd/sessions/156582.refdbus-daem 560 dbus 2140w     FIFO               0,18      0t0  417383549 /run/systemd/sessions/156774.refdbus-daem 560 dbus 2141w     FIFO               0,18      0t0  417291412 /run/systemd/sessions/156740.refdbus-daem 560 dbus 2142w     FIFO               0,18      0t0  620267085 /run/systemd/sessions/242902.refdbus-daem 560 dbus 2143w     FIFO               0,18      0t0  621086290 /run/systemd/sessions/243335.ref[root@MySQL-slaver ~]# 

解决

集体感觉可选解决方案如下:

1、服务器上次要服务为MySQL和Redis,MySQL作为从库应用,未承载业务读流量,Redis近期将会迁徙,/run/systemd/users目录占用内存尽管在增长,5年了也只占用8G,增量很迟缓,故能够在线膨胀MySQL innodb_buffer_pool_size应用内存,开释一部分内存给操作系统,等Redis迁徙了再做机器重启解决。

2、假如主机不能够重启,通过lsof可知这些暗藏文件以后未被应用,故能够迁徙到其余磁盘目录,看看是否能达到开释内存目标,且这些session都是crond 2018年产生的,并未调配相干过程,故通过loginctl kill-session ID干掉。

目前采取计划1解决。