【问题标题】:MySQL maximum memory usageMySQL 最大内存使用量
【发布时间】:2010-11-13 19:19:21
【问题描述】:

我想知道如何设置 MySQL 在 Linux 服务器上使用的内存量的上限。

现在,MySQL 将继续在请求每个新查询时占用内存,以致最终耗尽内存。有没有办法限制 MySQL 使用的数量不超过该数量?

【问题讨论】:

  • MySQL 不会“为每个新查询占用内存并最终耗尽”。内存使用比这复杂得多。
  • 对我而言,这篇博文有助于了解影响 MySQL 专用 RAM 数量的最小和最大 tech.labelleassiette.com/…

标签: mysql memory ram


【解决方案1】:

MySQL 的最大内存使用量很大程度上取决于硬件、您的设置数据库本身。

硬件

硬件是显而易见的部分。 RAM 越多,磁盘越快ftw。不要相信那些每月或每周的新闻信件。 MySQL 不能线性扩展——甚至在 Oracle 硬件上也不能。这比那有点棘手。

底线是:对于您的 MySQL 设置推荐什么没有一般的经验法则。这一切都取决于当前的使用情况或预测。

设置和数据库

MySQL 提供了无数变量和开关来优化其行为。如果遇到问题,您真的需要坐下来阅读(f'ing)手册。

关于数据库——一些重要的限制:

  • 表引擎 (InnoDB, MyISAM, ...)
  • 尺寸
  • 指数
  • 用法

stackoverflow 上的大多数 MySQL 技巧都会告诉您 5-8 个所谓的重要设置。首先,并非所有这些都很重要 - 例如将大量资源分配给 InnoDB 而不使用 InnoDB 没有多大意义,因为这些资源被浪费了。

或者——很多人建议增加max_connection 变量——好吧,他们几乎不知道这也意味着MySQL 将分配更多资源来满足max_connections 的需求——如果需要的话。更明显的解决方案可能是关闭 DBAL 中的数据库连接或降低 wait_timeout 以释放这些线程。

如果你明白我的意思——真的有很多很多东西需要阅读和学习。

引擎

表引擎是一个非常重要的决定,许多人很早就忘记了这些,然后突然发现自己与一个 30 GB 大小的 MyISAM 表发生了冲突,该表锁定并阻塞了他们的整个应用程序。

我并不是说MyISAM 很烂,但InnoDB 可以调整为几乎或几乎与MyISAM 一样快的响应速度,并提供UPDATE 上的行锁定等功能而MyISAM 在写入时锁定整个表。

如果您可以在自己的基础架构上运行 MySQL,您可能还想查看percona server,因为其中包括来自 Facebook 和 Google 等公司的大量贡献(他们知道得很快),它还包括Percona 自己替换 InnoDB,称为 XtraDB

请参阅我的 percona-server(和-client)设置(在 Ubuntu 上)的要点:http://gist.github.com/637669

尺寸

数据库大小非常非常重要——信不信由你,Intarwebs 上的大多数人从未处理过大型和编写密集的 MySQL 设置,但这些确实存在。有些人会说“使用 PostgreSQL!!!111”之类的话,但我们暂时忽略它们。

底线是:从尺寸上看,要做出关于硬件的决定。你不能真正让一个 80 GB 的数据库在 1 上快速运行 GB RAM。

指数

不是:越多越好。仅需要设置索引,并且必须使用EXPLAIN 检查使用情况。再加上 MySQL 的 EXPLAIN 确实是有限的,但这只是一个开始。

建议配置

关于这些my-large.cnfmy-medium.cnf 文件——我什至不知道这些文件是为谁而写的。自己动手。

调优入门

tuning primer 是一个很好的开始。这是一个 bash 脚本(提示:你需要 linux),它接受 SHOW VARIABLESSHOW STATUS 的输出并将其包装成希望有用的推荐。如果您的服务器已经运行了一段时间,建议会更好,因为会有数据作为它们的依据。

不过,调音底漆并不是一种神奇的调味汁。您仍然应该阅读它建议更改的所有变量。

阅读

我真的很想推荐mysqlperformanceblog。它是各种 MySQL 相关技巧的绝佳资源。而且不仅是 MySQL,他们还非常了解正确的硬件或 AWS 的推荐设置等。这些人拥有多年的经验。

当然,另一个很棒的资源是planet-mysql

【讨论】:

  • 我不知道tuning primer,和mysqltuner相比如何?
【解决方案2】:

我们使用这些设置:

etc/my.cnf
innodb_buffer_pool_size = 384M
key_buffer = 256M
query_cache_size = 1M
query_cache_limit = 128M
thread_cache_size = 8
max_connections = 400
innodb_lock_wait_timeout = 100

适用于具有以下规格的服务器:

Dell Server
CPU cores: Two
Processor(s): 1x Dual Xeon
Clock Speed: >= 2.33GHz
RAM: 2 GBytes
Disks: 1×250 GB SATA

【讨论】:

  • 我认为你(和你链接到的作者)有 query_cache_size 和 query_cache_limit 错误的方式。你告诉 MySQL:分配一个 1MB 的缓存,但不要在其中放入任何大于 128MB 的查询。 dev.mysql.com/doc/refman/5.0/en/query-cache-configuration.html
  • 我会降低 max_connections。我会决定使用哪个引擎,而不是为两者分配大量空间。
【解决方案3】:

mysqld.exe 在 RAM 中使用 480 mb。我发现我在my.ini中添加了这个参数

table_definition_cache = 400

将内存使用量从 400,000+ kb 减少到 105,000kb

【讨论】:

  • 这属于哪个部分?我将它添加到我的,但服务拒绝启动。
  • 没关系,我将它移到 [wampmysqld] 下,它工作得很好,并且显着减少了我使用的内存。我认为它可能也加快了我的本地主机页面加载速度,现在它们似乎更快了。
  • 虽然默认值和最小值是 400,但在您的情况下是什么导致它高于 400?
【解决方案4】:

数据库内存使用是一个复杂的话题。 MySQL Performance Blog 很好地解决了您的问题,并列出了许多“保留”内存非常不切实际的原因。

如果您真的想施加硬性限制,您可以这样做,但您必须在操作系统级别进行,因为没有内置设置。在 linux 中,您可以使用 ulimit,但您可能必须修改 MySQL 的启动方式才能强制执行此操作。


最好的解决方案是调低你的服务器,这样通常的 MySQL 内存设置的组合将导致你的 MySQL 安装的内存使用率普遍较低。这当然会对您的数据库性能产生负面影响,但是您可以在 my.ini 中调整的一些设置是:

key_buffer_size
query_cache_size
query_cache_limit
table_cache
max_connections
tmp_table_size
innodb_buffer_pool_size

我会从那里开始,看看你是否能得到你想要的结果。有manyarticles关于调整MySQL内存设置。


编辑:

注意一些变量名have changed in the newer 5.1.x releases of MySQL

例如:

table_cache

现在:

table_open_cache

【讨论】:

  • 嗨!感谢您的回答。我注意到人们引用的等式如下:key_buffer_size+(read_buffer_size+sort_buffer_size)*max_connections=Total Memory。我设置了如下:key_buffer_size=128M,read_buffer_size=1M,sort_buffer_size=2M,max_connections=120,服务器总内存为512M。但是,经过多次查询后,可用内存已降至 12M,并且可能会随着进一步使用而继续下降。这是有原因的吗?可以防止吗?谢谢!
  • 或者也许我需要考虑的不是服务器上的总内存(512M)而是空闲内存(即加载所有操作系统相关程序和其他程序后可用的内存)?
  • 如果您要修改 tmp_table_size 以增加可存储在 RAM 中的临时表的大小,请记住同时增加 max_heap_table_size - 因为 MySQL 使用两者中的最小值。 .
  • @TimothyMilsud - 没有这样的公式真正有效。当一个公式声称使用了过多的 RAM 时,大多数服务器运行良好。
【解决方案5】:

关于 MYSQL 是如何吃掉内存的:https://dev.mysql.com/doc/refman/8.0/en/memory-use.html

/etc/my.cnf:

[mysqld]
...

performance_schema = 0

table_cache = 0
table_definition_cache = 0
max_connect_errors = 10000

query_cache_size = 0
query_cache_limit = 0

...

在 256MB 内存的服务器上表现不错。

【讨论】:

  • 为什么table_definition_cache = 0?一些解释会很好。而且你基本上没有缓存查询......如果你query_cache_type = 0 :)
  • @KhomNazid 缓存正在消耗内存,在我的情况下,服务器只有 256Mb 内存,因此此配置有助于保存它。更多关于内存dev.mysql.com/doc/refman/8.0/en/memory-use.html“MySQL 还需要内存用于表定义缓存。table_definition_cache 系统变量定义了表定义缓存中可以存储的表定义的数量。如果使用大量表,可以创建一个大表定义缓存,加快开表速度。表定义缓存占用空间少,不使用文件描述符,与表缓存不同。"
【解决方案6】:

如果您正在寻找优化您的 docker mysql 容器,那么下面的命令可能会有所帮助。我能够将 mysql docker 容器从默认的 480mb 运行到仅仅 100mbs

docker run -d -p 3306:3306 -e MYSQL_DATABASE=test -e MYSQL_ROOT_PASSWORD=tooor -e MYSQL_USER=test -e MYSQL_PASSWORD=test -v /mysql:/var/lib/mysql --name mysqldb mysql -- table_definition_cache=100 --performance_schema=0 --default-authentication-plugin=mysql_native_password

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-12
    • 2017-01-28
    • 2012-09-10
    • 1970-01-01
    • 1970-01-01
    • 2018-03-29
    • 1970-01-01
    相关资源
    最近更新 更多