MySQL 因内存相关错误而崩溃,但大约 50% 的内存未被使用

MySQL 因内存相关错误而崩溃,但大约 50% 的内存未被使用

MySQL 不断崩溃,原因是:InnoDB: Fatal error: cannot allocate memory for the buffer pool。这看起来像是内存问题,互联网似乎证实了这一点。此外,我的机器只有 1GB 的 RAM,因此这也暗示这可能是问题所在。

但是,我的监控工具(来自 rackspace)显示,在崩溃时我只使用了大约 608MB 的内存。此外,如果我通过命令检查内存使用情况free,我会看到类似以下内容:

           total       used       free     shared    buffers     cached
Mem:       1018872     832144     186728      86608      22992     183276
-/+ buffers/cache:     625876     392996
Swap:            0          0          0

此时,请注意,我对 Linux 处理内存的方式非常不熟悉。但在 Google 的帮助下,我发现“缓存”内存应该被视为空闲内存,因为系统会在需要时将其归还(对吗?)。

如果是这样,那么为什么 MySQL 仍然崩溃?

编辑:更多信息。mysqltuner 的 INNODB 部分是这样的:

-------- InnoDB Metrics ----------------------------
[--] InnoDB is enabled.
[OK] InnoDB buffer pool / data size: 128.0M/20.2M
[OK] InnoDB buffer pool instances: 1
[!!] InnoDB Used buffer: 11.83% (969 used/ 8191 total)
[OK] InnoDB Read buffer efficiency: 92.74% (12364 hits/ 13332 total)
[!!] InnoDB Write buffer efficiency: 0.00% (0 hits/ 1 total)
[OK] InnoDB log waits: 0.00% (0 waits / 1 writes)

My.cnf(我删除了所有注释掉的行以使其更具可读性):

[client]
port        = 3306
socket      = /var/run/mysqld/mysqld.sock

[mysqld_safe]
socket      = /var/run/mysqld/mysqld.sock
nice        = 0

[mysqld]
user        = mysql
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
port        = 3306
basedir     = /usr
datadir     = /var/lib/mysql
tmpdir      = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
bind-address        = 127.0.0.1
key_buffer      = 16M
max_allowed_packet  = 16M
thread_stack        = 192K
thread_cache_size       = 8
myisam-recover         = BACKUP
query_cache_limit   = 1M
query_cache_size        = 16M

log_error = /var/log/mysql/error.log

expire_logs_days    = 10
max_binlog_size         = 100M

[mysqldump]
quick
quote-names
max_allowed_packet  = 16M

[mysql]

[isamchk]
key_buffer      = 16M

!includedir /etc/mysql/conf.d/

答案1

您还应该查看正在执行的 SQL - 如果简单查询运行没有问题,则表明该 SQL 需要太多的临时空间。

我担心,将几张表合并 - 并进行排序 - 以及使用 group_by 会耗尽你所拥有的仅有的 1Gb 内存。

答案2

您需要找出innodb_buffer_pool_sizeMySQL 中变量的值。这将告诉您 MySQL 试图分配多少。

检查 /etc/my.cnf 文件中的该值或从 MySQL 命令行运行以下命令

select @@innodb_buffer_pool_size;

运行 mysqltuner 可能更容易

wget http://mysqltuner.pl/ -O mysqltuner.pl
perl mysqltuner.pl

这将告诉您,您的 MySQL 实例是否配置为消耗比服务器可用内存更多的内存。

将 mysqltuner 输出粘贴到这里。

有关该工具的更多信息http://mysqltuner.com/

相关内容