故障分析 | 数据库服务器内存不足一例分析

news/2024/12/22 9:50:09/

作者:付祥

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

本文来源:原创投稿

*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。


现象

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

[root@mysql-slaver ~]# top
top - 13:45:43 up 1835 days, 20:52,  2 users,  load average: 0.02, 0.03, 0.05
Tasks: 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 st
KiB Mem : 32780028 total,   905684 free, 19957900 used, 11916444 buff/cache
KiB 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 xxxxxx442 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 -mtotal        used        free      shared  buff/cache   available
Mem:          32011       19490         881        8762       11639        3366
Swap:             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 -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs         16G     0   16G   0% /dev
tmpfs            16G   16K   16G   1% /dev/shm
tmpfs            16G  8.6G  7.1G  55% /run
tmpfs            16G     0   16G   0% /sys/fs/cgroup

目录/run使用了8.6G内存,和shared占用内存一致,内存都消耗到哪些子目录了?

[root@MySQL-slaver ~]# du -am /run|sort -rn -k1|head -10
8761    /run
7137    /run/systemd
7126    /run/systemd/users
1624    /run/log/journal/89308070e0c04c6a86bf577f4064efca
1624    /run/log/journal
1624    /run/log

内存主要消耗在/run/systemd/users和/run/log/journal目录,占用内存分别为7126M、1624M,较为异常的是/run/systemd/users占用内存过高,继续分析这个目录下有哪些文件

[root@MySQL-slaver ~]# ls -l /run/systemd/users
total 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 -l
337632[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 ~]# uptime14: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=root
STATE=active
RUNTIME=/run/user/0
SLICE=user-0.slice
DISPLAY=4231719
REALTIME=1521010223727718
MONOTONIC=79029110787
SESSIONS=4232100 4232099 4232098 ......

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

[root@MySQL-slaver ~]# loginctl list-sessionsSESSION        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 -c1 1 listed.2131 root1 USER            

root用户session数竟然高达2131个,随便拿一个session看看:

[root@MySQL-slaver ~]# loginctl session-status 24597
24597 - root (0)Since: Tue 2018-03-27 08:35:01 CST; 4 years 11 months agoLeader: 25599Service: crond; type unspecified; class backgroundState: activeUnit: session-24597.scope
[root@MySQL-slaver ~]# 

crond产生的session,这些session都没有分配相关进程,当前状态为active,按session排序后,挑选最近的session查看,都是2018年产生的:

[root@MySQL-slaver ~]# loginctl session-status 243335
243335 - root (0)Since: Sat 2018-07-14 03:29:01 CST; 4 years 8 months agoLeader: 28376Service: crond; type unspecified; class backgroundState: activeUnit: 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 4232206
4232206 - root (0)Since: Thu 2023-03-23 15:20:01 CST; 19min agoLeader: 12330 (crond)Service: crond; type unspecified; class backgroundState: openingUnit: session-4232206.scope├─12330 /usr/sbin/CROND -n└─12334 sleep 1200
[root@MySQL-slaver ~]# loginctl session-status 4232206
Failed to get session: No session '4232206' known[root@MySQL-slaver ~]# lsof -p `pidof dbus-daemon`|grep sessions|wc -l
2126
[root@MySQL-slaver ~]# lsof -p `pidof dbus-daemon`|tail -5
dbus-daem 560 dbus 2139w     FIFO               0,18      0t0  416861417 /run/systemd/sessions/156582.ref
dbus-daem 560 dbus 2140w     FIFO               0,18      0t0  417383549 /run/systemd/sessions/156774.ref
dbus-daem 560 dbus 2141w     FIFO               0,18      0t0  417291412 /run/systemd/sessions/156740.ref
dbus-daem 560 dbus 2142w     FIFO               0,18      0t0  620267085 /run/systemd/sessions/242902.ref
dbus-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处理。


http://www.ppmy.cn/news/48223.html

相关文章

【每日一练】题目名称:划分窗口

题目描述 给定一个长度为 n 的数组 num 和滑动窗口的大小 size ,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小 3,那么一共存在6 个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}&#xff1b…

《C++高并发服务器笔记——第五章项目实战与总结》

代码地址 《C高并发服务器笔记——第五章》 5.1、阻塞/非阻塞、同步/异步(网络IO)1.阻塞/非阻塞、同步/异步(网络IO)①典型的一次IO的两个阶段是什么? 2.日志系统①基础知识②整体概述③本文内容④单例模式1.经典的线程安全懒汉模式2.局部静…

asp.net+sqlserver基于web的在校大学生贷款管理系统

采用的技术: 1.ASP.NET框架; 2. SQL Server 数据库; 3.AJAX技术:它不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的 Web 应用程序的技术; 4.HTML,CSSDIV,代码实现静态页面; 开…

集合例题,

package com.hspedu.homework;import java.util.*;/*** author 韩顺平* version 1.0*/ SuppressWarnings({"all"}) public class Homework03 {public static void main(String[] args) {Map m new HashMap();m.put("jack", 650);//int->Integerm.put(&…

C# ArrayList

ArrayList 是 System.Collections 命名空间中的一个类,是一个可动态增长和缩减的数组。与 C# 数组不同,ArrayList 可以自动扩容,并支持动态插入和删除元素,可以存储任何类型的对象。 使用 ArrayList 的步骤如下: 引入…

kafka概述

文章目录 1.kafka定义2.消息队列2.1 传统消息队列的应用场景2.2 消息队列的两种模式 3.Kafka 基础架构 1.kafka定义 2.消息队列 目前企业中比较常见的消息队列产品主 要有 Kafka、ActiveMQ 、RabbitMQ 、RocketMQ 等。 在大数据场景主要采用 Kafka 作为消息队列。在 JavaEE 开…

用户画像项目失败的表面原因

▌原因一:混淆了过去和未来 问1:一个用户昨天买了苹果,前天买了苹果,大前天也买了苹果,他今天买不买苹果? 问2:一个用户买了酱油,鸡翅,可乐,请问他是否还需要…

mysql 海量数据设计:对数据库存储有深入研究

索引: 聚簇索引 二级索引 联合索引:最左匹配原则、自动优化顺序 索引优化方向: 存储空间 主键选择:自增主键、随机主键、业务主键 如何设计一个雪花算法: 正数 时间戳 机器id(固定) 服务id 序号 package ut…