为什么 MySQL 消耗这么多内存?

Jul*_*cia 15 mysql

我有 mysql 5.6.36 数据库,其大小为 ~35G,在 CentOS 7.3 上运行,内存为 48G。

[ UPDATE 17-08-06] 我会在这里更新相关信息。

我看到我的服务器内存不足,即使有大约 48G 的 RAM 也会崩溃。例如,我无法让它在 24G 上运行。这种大小的数据库应该能够运行得少得多。显然,我缺少一些基本的东西。

[更新:17-08-05] 崩溃,我的意思是 mysqld 停止并重新启动,日志中没有任何有用的信息,除了从崩溃中重新启动。另外,有了所有这些记忆,我在恢复过程中遇到了这个错误:

[ERROR] InnoDB: space header page consists of zero bytes in tablespace ./ca_uim/t_qos_snapshot.ibd (table ca_uim/t_qos_snapshot)
Run Code Online (Sandbox Code Playgroud)

我的配置文件的相关部分看起来像这样 [ EDITED 17-08-05 添加缺失的行]:

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
lower_case_table_names = 1
symbolic-links=0
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 
max_allowed_packet = 32M
max_connections = 300
table_definition_cache=2000
innodb_buffer_pool_size = 18G
innodb_buffer_pool_instances = 9
innodb_log_file_size = 1G
innodb_file_per_table=1

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
Run Code Online (Sandbox Code Playgroud)

每个表使用文件是一个疏忽,我需要更改它(我有 6000 个表,其中大部分是分区的)。

运行一小会(一小时)后,mytop 显示:

MySQL on 10.238.40.209 (5.6.36)    load 0.95 1.08 1.01 1/1003 8525 up 0+01:31:01 [17:44:39]
 Queries: 1.5M     qps:  283 Slow:    22.0         Se/In/Up/De(%):    50/07/09/01
 Sorts:     27 qps now:  706 Slow qps: 0.0  Threads:  118 (   3/   2) 43/28/01/00 
 Key Efficiency: 100.0%  Bps in/out: 76.7k/176.8k   Now in/out: 144.3k/292.1k
Run Code Online (Sandbox Code Playgroud)

免费显示:

# free -h
              total        used        free      shared  buff/cache   available
Mem:            47G         40G        1.5G        8.1M        5.1G        6.1G
Swap:          3.9G        508K        3.9G
Run Code Online (Sandbox Code Playgroud)

顶部显示:

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                             
2010 mysql     20   0 45.624g 0.039t   9008 S  95.0 84.4  62:31.93 mysqld                                                              
Run Code Online (Sandbox Code Playgroud)

怎么会这样?这是每个表的相关文件吗?整个数据库都可以放入内存中。我究竟做错了什么?

Abh*_*gal 7

在您的my.cnf(MySQL 配置)文件中:

在 [mysqld] 块中添加设置

[mysqld]

performance_schema = 0
Run Code Online (Sandbox Code Playgroud)

对于 MySQL 5.7.8 以后,您必须添加如下额外设置:

[mysqld]

performance_schema = 0

show_compatibility_56 = 1
Run Code Online (Sandbox Code Playgroud)

注意:这会将您的内存使用量减少到 50%-60% 以上。“show_compatibility_56”是可选的,在某些情况下它有效,最好在添加到配置文件后检查它。

  • 在我的 DO 盒子上,使用 LEMP 堆栈 (MySQL 8),通过在 /etc/mysql/my.cnf 中添加 Performance_schema=0,mysqld 从大约 44% 提高到大约 16-17%。另一个选项(show_compatibility_56)导致 mysqld 无法正确重新启动。请注意,我不需要打开性能模式 - 在关闭之前确保您也不需要它 (3认同)

Jul*_*cia 6

嗯,我解决了这个问题。我感谢那些做出回应的人的所有见解。解决方案很奇怪,我无法解释为什么这可以解决问题,但确实如此。我所做的是将以下行添加到 my.cnf 中:

log_bin
Run Code Online (Sandbox Code Playgroud)

此外,您可能需要添加以下内容:

expire_logs_days = <some number>
Run Code Online (Sandbox Code Playgroud)

我们已经看到至少一个日志累积并填满磁盘的实例。默认值为 0(不自动删除)。https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_expire_logs_days