RHEL9等系统启动Mysql 5.7后,内存异常占用的问题
问题回顾
使用docker-compose.yaml启动了mysql容器。
启动成功后,使用free -mh查看宿主机内存占用情况,并用docket stats 查看容器情况,mysql竟然占用了16个G
docker-compose.yml
version: '3.1'
services:
db:
image: mysql:5.7
ports:
- "3310:3306"
restart: always
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --init-connect='SET NAMES utf8mb4;' --innodb-flush-log-at-trx-commit=0
environment:
MYSQL_ROOT_PASSWORD: xxxxxxx
MYSQL_DATABASE:xxxxxx
volumes:
- ./datadir:/var/lib/mysql:rw
原因分析
这个问题的直接原因是文件描述符上限太大了;
以前的很多软件在启动的时候都会有一些初始化的动作;
如关闭所有能关闭的文件描述符, 关闭所有能关闭的网络 socket 这一类的动作,
避免之前程序的干扰,或者是确认资源能使用;
但是早期版本的 linux 文件描述符上限, 默认一般是 1024, SA优化一般也就修改为 65535,
所以软件启动时很快就能执行完了, 说多也就1-2s; 也不会占用太多内存;
普通软件在未配置的情况也是继承操作系统的这个数值;
可是新版本的 kernel 和 el9+ 等新发行版把这个 系统级别的限制数值提高了非常多;
就导致很多传统软件在未适配的情况要么启动时CPU使用率极高, 要么启动时内存占用非常大;
这里应该是新版本的 containerd 自己单独修改的 ulimit 的上限导致的;
所以这个对容器单独进行资源限制解决了这个问题;
同时此问题未在 mysql 8.0+ 上出现, 猜测应该是程序自己有做优化;
ulimits:
nproc: 65535
nofile: soft: 26677
hard: 46677
重启容器然后正常了。
还有要提醒容器的系统太老了,都下不到最新软件包了。记得及时更新容器版本。