MySQL:如何降低“最大可能的内存使用量”?

MySQL:如何降低“最大可能的内存使用量”?

我最近遇到了由于内存不足而导致的抖动问题。(我的 VPS 总共有 256M)

我正在尝试使用 mysqltuner.pl 调整 MySQL,并得到以下结果:

-------- 一般统计数据 --------------------------------------------------
[--] 跳过 MySQLTuner 脚本的版本检查
[确定] 当前运行支持的 MySQL 版本 5.0.51a-3ubuntu5.4-log
[OK] 在 64 位架构上运行

-------- 存储引擎统计 ----------------------------------------------------------
[--] 状态:+存档-BDB-Federated-InnoDB-ISAM-NDBCluster
[--] MyISAM 表中的数据:114M(表:454)
[!!] 碎片表总数:34

-  -  -  -  性能指标  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - -
[--] 上升时间:40 秒(570 q [14.250 qps],23 个连接,TX:154K,RX:23K)
[--] 读取/写入:100%/0%
[--] 总缓冲区:全局 338.0M + 每个线程 2.7M(最多 20 个线程)
[!!] 最大可能的内存使用量:392.9M(已安装 RAM 的 153%)
[OK] 慢速查询:0% (5/570)
[OK] 可用连接的最高使用率:15% (3/20)
[!!] 键缓冲区大小/总 MyISAM 索引:8.0M/9.4M
[!!] 密钥缓冲区命中率:57.1% (7 次缓存/3 次读取)
[确定] 查询缓存效率:21.9%(7 个缓存/32 个选择)
[确定] 每日查询缓存修剪次数:0
[确定] 需要临时表的排序:0% (0 个临时排序/1 个排序)
[确定] 磁盘上创建的临时表:0%(磁盘上 0 个/总共 32 个)
[OK] 线程缓存命中率:86% (创建 3 个/连接 23 个)
[OK] 表缓存命中率:26% (128 打开 / 484 打开)
[确定] 已使用的打开文件限制:25% (259/1K)
[OK] 立即获取的表锁:100% (492 立即/492 锁)

-------- 建议 -----------------------------------------------------------------
一般建议:
    运行 OPTIMIZE TABLE 对表进行碎片整理,以获得更好的性能
    MySQL 在过去 24 小时内启动 - 建议可能不准确
    减少总体 MySQL 内存占用,提高系统稳定性
需要调整的变量:
  *** MySQL 的最大内存使用量过高,非常危险 ***
  *** 在增加 MySQL 缓冲区变量之前添加 RAM ***
    密钥缓冲区大小 (> 9.4M)

但我对如何降低最大内存使用量有点困惑?它似乎基于 key_buffer 和 max_connections,但肯定还涉及其他东西?

我的.cnf:

密钥缓冲区 = 8M
最大允许数据包 = 12M
线程堆栈 = 128K
线程缓存大小 = 8
最大连接数 = 20
表缓存 = 128
tmp_table_size = 256M
最大堆表大小 = 256M
连接缓冲区大小 = 256K
查询缓存限制 = 8M
查询缓存大小 = 64M

我一直在尝试阅读 MySQL 调优文章,但它们似乎面向已经知道自己在做什么的人!任何帮助都将不胜感激。谢谢!

答案1

您的服务器有 256M,但您无法全部使用 - 请记住,这会产生一些操作系统开销。此外,正如其他人提到的那样,您投入过多,您肯定会在这里失败。256M 仅够用于小型数据库,而 20 个连接对于您配置的数据库来说已经很多了。

1)将最大连接数减少到 4 个(您使用了 20 个中的 3 个)

2) 更好地优化查询缓存;8M 确实很大,而根据您的命中/修剪,总共 64M 也很多;尝试 4/32 组合,看看效果如何。实际上,我认为 2/24 组合适合您。

3) 您没有需要临时表的排序,为什么其中有 max_heap_table_size 动词?注释掉它,使用默认值

4) 你真的有 128 个表吗?尝试将 table_cache 减半为 64 或 48

5)将thread_cache_size减少到4

6)优化这些表以减少碎片化

这些是一些入门知识。看起来您在配置中输入了一堆数字,而没有进行任何实际分析以了解您需要什么,结果造成了混乱;如果其他方法都失败了,请恢复默认设置并删除自定义设置,然后使用您可以在 Google 上找到的一些性能调优指南重新开始。获取 SHOW VARIABLES 和 SHOW STATUS 的输出,找到无数调优指南中的任何一个,然后将您的实际实数代入其方程式中,这将告诉您需要放入配置文件中的确切数字。

答案2

我不是 MySQL 专家,无法根据这些信息诊断问题,但我尝试在源代码中搜索公式。它在这里:

server_buffers + total_per_thread_buffers * max_connections

在哪里:

server_buffers = key_buffer_size + innodb_buffer_pool_size + innodb_additional_mem_pool_size + innodb_log_buffer_size + query_cache_size

和:

total_per_thread_buffers = read_buffer_size + read_rnd_buffer_size + sort_buffer_size + thread_stack + max_allowed_packet + join_buffer_size

现在您必须检查每个值,并找出哪个值导致了这个巨大的数字。不要毫无保留地相信这个脚本 - 我尝试在我的一个数据库服务器上运行它,它计算出最大内存是物理内存总量的 140%,但系统已经运行多年,没有任何稳定性问题。

祝你好运!

答案3

如果我没记错的话,MySQL Tuner 使用以下公式来估算最大使用量:

read_buffer_size + read_rnd_buffer_size + sort_buffer_size + thread_stack + join_buffer_size

请记住,这并非 100% 正确,实际上只是一个估计,因为 MySQL 中的某些设置没有定义的限制。

您可以开始调低配置文件中的某些设置并再次运行调谐器,但如果您没有时间浪费在更改 my.cnf、重新启动它并运行调谐器上,我建议您寻求专家的帮助。

答案4

使用 mysqlcalculator.com 软件可以节省您很多时间。

相关内容