docker启动mysql时内存占用过多

事件: mysql容器内存问题

简述

使用 docker-compose 搭建一个 mysql 环境;
8.0 版本启动正常;
5.7 版本启动后内存占用非常高, 16G 的主机内存占用了 14G, 且内存波动幅度大;

排查后认定是 ulimt 资源限制的问题, 加以限制后解决此问题

现象

使用 docker-compose 搭建一个 mysql 环境, 内容如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
version: '3'
services:
  dbmysql:
    image: mysql:5.7.43
    restart: always
    # mem_limit: 3G
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      TZ: Asia/Shanghai

    ports:
      - 3306:3306
    volumes:
      - mysql_data:/var/lib/mysql
      - ./my.cnf:/etc/mysql/conf.d/my.cnf:ro
volumes:
  mysql_data:

启动成功, 但是主机的内存使用率非常高;
top 查看时发现, mysqld 进程的 VIRT 和 RES 都很高, 明显的异常;

开始以为是版本的原因, 但是更换了几个5.7的版本也是这样;

解决

那就 google 一下吧; 筛选到一篇文章;
https://github.com/containerd/containerd/issues/6707

增加资源限制后的配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
version: '3'
services:
  dbmysql:
    image: mysql:5.7.43
    restart: always
    # mem_limit: 3G
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      TZ: Asia/Shanghai

    ulimits:
      nproc: 65535
      nofile:
        soft: 26677
        hard: 46677

    ports:
      - 3306:3306
    volumes:
      - mysql_data:/var/lib/mysql
      - ./my.cnf:/etc/mysql/conf.d/my.cnf:ro
volumes:
  mysql_data:

问题解决, 内存使用稳定了;

原因分析

这个问题的直接原因是文件描述符上限太大了;

以前的很多软件在启动的时候都会有一些初始化的动作;
如关闭所有能关闭的文件描述符, 关闭所有能关闭的网络 socket 这一类的动作,
避免之前程序的干扰,或者是确认资源能使用;

但是早期版本的 linux 文件描述符上限, 默认一般是 1024, SA优化一般也就修改为 65535,
所以软件启动时很快就能执行完了, 说多也就1-2s; 也不会占用太多内存;

普通软件在未配置的情况也是继承操作系统的这个数值;

可是新版本的 kernel 和 el9+ 等新发行版把这个 系统级别的限制数值提高了非常多;
就导致很多传统软件在未适配的情况要么启动时CPU使用率极高, 要么启动时内存占用非常大;

这里应该是新版本的 containerd 自己单独修改的 ulimit 的上限导致的;
所以这个对容器单独进行资源限制解决了这个问题;

同时此问题未在 mysql 8.0+ 上出现, 猜测应该是程序自己有做优化;

此问题在目前这个过度阶段里面很常见;

比如在 el9 上部署 ceph 集群时,
一旦创建 pool 后, mon 主节点的 CPU使用率就满了,然后被迫自动切换 leader, 然后下一个 leader 又接着打满;
这个问题排查了几天, 最后也还是这这个原因, 限制了 mon 的 limit 资源后就正常了;

微信搜索IT运维小秋

Licensed under CC BY-NC-SA 4.0
转载或引用本文时请遵守许可协议,知会作者并注明出处
不得用于商业用途!
最后更新于 2023-08-04 00:00 UTC