MySQL配置单线程占用1G内存过高,如何调整降低内存占用?
单线程1G内存的原因
MySQL的单线程内存上限是所有会话级内存参数的总和,不是由单个参数控制的,mysqltuner的计算逻辑为:
单线程内存上限 = read_buffer_size + read_rnd_buffer_size + sort_buffer_size + join_buffer_size + thread_stack + binlog_cache_size
你出现1G单线程预留的核心原因是误将会话级参数当成全局参数调大了,其中sort_buffer_size、join_buffer_size这两个参数是重灾区,只要这两个参数各设512M,加起来就刚好达到1G的单线程预留。这类参数是每个连接执行对应操作时都会独立分配内存,连接数越高内存消耗增长越快,就是你高流量下性能崩盘的核心诱因:内存超用触发大量Swap IO,甚至会被系统OOM机制直接杀掉MySQL进程。
调低参数的操作步骤
- 先执行以下SQL查看当前各会话级参数的配置,确认哪几个参数过高:
SHOW VARIABLES LIKE '%buffer_size%'; SHOW VARIABLES LIKE 'thread_stack'; SHOW VARIABLES LIKE 'binlog_cache_size';
- 按照生产环境通用合理值调整参数,你整机物理内存约63G(从mysqltuner的内存占比推算),参考配置如下:
- sort_buffer_size = 2M(大查询较多的场景最多调到4M)
- join_buffer_size = 1M(多表关联查询多的场景最多调到2M)
- read_buffer_size = 128K(顺序查询多的场景最多调到1M)
- read_rnd_buffer_size = 256K(随机查询多的场景最多调到2M)
- binlog_cache_size = 1M(大事务较多的场景最多调到32M)
- 修改MySQL配置文件(通常为
/etc/my.cnf或/etc/mysql/my.cnf),将上述参数写入配置段后,先备份现有配置再重启MySQL服务生效:
# 备份配置 cp /etc/my.cnf /etc/my.cnf.bak # 重启服务(根据你的系统服务名调整,也可能是mysqld) systemctl restart mysql
- 重启后重新运行mysqltuner校验,此时单线程内存总预留会降到10M以内,配合500的最大连接数,总最大内存占用仅为4.1G全局缓存 + 5G会话预留 = 9.1G,远低于物理内存容量,不会再出现内存超用的问题。
- 如果调整后出现明显的排序、关联类慢查询上涨,可以小幅度上调
sort_buffer_size、join_buffer_size,但要保证单线程总预留不超过20M。
内容的提问来源于stack exchange,提问作者Hillcow
相关产品推荐
相关产品推荐

