以下内容均来自个人笔记并重新梳理,如有错误欢迎指正!
如果对您有帮助,烦请点赞、关注、转发!如果您有其他想要了解的,欢迎私信联系我~
背景介绍
笔者在文章《MySQL 源码构建 Docker 镜像(基于 ARM 64 架构)》中曾提到过,为解决 Kylin V10 的兼容性问题,需要在 MySQL 容器启动脚本 docker-entrypoint.sh 的基础上单独添加 391 行。今天就来具体讲一讲背后的问题、原因,以及完整的解决过程。
先说现象和结论,在 Kylin V10 下的 MySQL 容器,启动时内存占用超过 20GB,无业务运行时内存占用约 16GB,均远高于其他系统下的几百MB,经排查发现 MySQL 的 open_files_limit 参数在 Kylin V10 下取值异常,直接导致上述问题。
过程回顾
1、查看内存分配
首先,笔者通过以下命令得到 MySQL 的内存分配情况,试图找出占用内存较多的类型和事件,但是通过查询结果粗略估算,所有已分配内存加起来还不到 1GB,看起来还算正常。
代码语言:javascript复制# 登录 MySQL 后执行
select event_name,current_alloc from sys.memory_global_by_current_bytes ;
2、调整内存参数
随后,笔者调整思路,尝试找出 MySQL 中与内存相关的参数,进而有针对性地进行优化调整。
通过查阅文献,笔者找到了 MySQL 使用内存的计算方法,涉及的参数如下。
代码语言:javascript复制MySQL 使用内存=
key_buffer_size
query_cache_size
tmp_table_size
innodb_buffer_pool_size
innodb_additional_mem_pool_size
innodb_log_buffer_size
max_connections
×( sort_buffer_size
read_buffer_size
read_rnd_buffer_size
join_buffer_size
thread_stack
binlog_cache_size)
同时,笔者还发现一个可以自动计算 MySQL 使用内存的网站,于是着手将 MySQL 中的参数值与该网站的默认值一一比对,并将不一致的调整为默认值、甚至更低的值。但是最终发现,MySQL 的参数值与默认值偏差并不大,且参数经过调整后,MySQL 的内存占用情况完全没有改善。
附上网站地址:https://www.mysqlcalculator.com
3、找到问题根因
此后,笔者还尝试了其他多种方法,但均以失败告终,这里就不一一赘述了。
笔者只能寄希望于把 Kylin V10 下 MySQL 的参数值与其他系统下 MySQL 的参数值进行比较,最终发现只有 open_files_limit 参数存在巨大差距(忘记存图了,印象中两者相差10240倍?),经查 open_files_limit 参数定义了 MySQL 服务进程可以同时打开的文件数量,会预先分配并占用内存!
代码语言:javascript复制# 登录 MySQL 后执行以下命令,列出所有参数的名称和值,可以复制到文本,通过 vimdiff 进行比较
show variables ;
4、解决取值问题
通过实测发现,直接在 MySQL 中修改 open_files_limit 参数的值并不生效,且 MySQL 容器重启后,open_files_limit 参数会被重置为异常值。
文献显示 open_files_limit 参数的取值与 ulimit 设定的 open files 参数直接相关,笔者猜测是 Kylin V10 存在 MySQL 方面的兼容性问题。
笔者决定修改 MySQL 容器默认的启动脚本 docker-entrypoint.sh,在 MySQL 服务启动前,将 MySQL 容器的 open files 参数强制设定为指定值,并重新构建 MySQL 镜像,最终 Kylin V10 下 MySQL 容器内存占用异常的问题得到解决。
代码语言:javascript复制# 在 docker-entrypoint.sh 的 391 行添加
ulimit -n 1048576 && ulimit -a >/dev/null && ulimit -n
写在最后
现在回顾起来这个问题貌似并不复杂,但是为了静下心研究,当时从周五晚上 9 点一直搞到周六凌晨 3 点,最终问题得到解决笔者还是小有成就感的。笔者不仅快速解决了工作中遇到的问题,还收获了 MySQL 以及其他方面的知识,而且笔者也更加确信,遇到问题时办法总比困难多。