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

时间:2017-08-05 00:00:28

标签: mysql

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

[更新 17-08-06]我将更新相关信息here

我看到我的服务器内存不足,即使使用~48G的RAM也会崩溃。例如,我不能让它在24G上运行。这个大小的DB应该可以运行得少得多。显然,我缺少一些基本的东西。

[更新: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)

我的配置文件的相关部分看起来像这样[已编辑 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

每个表使用文件是一种疏忽,我需要更改它(我有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

免费显示:

# 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

Top显示了这个:

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                                                              

这怎么可能?这是每个表的相关文件吗?整个数据库可以适合内存。我做错了什么?

8 个答案:

答案 0 :(得分:2)

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

log_bin

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

expire_logs_days = <some number>

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

答案 1 :(得分:1)

希望您一次只能信任一个更改,以便您可以跟踪配置原因的进度。 2017-08-07 about 17:00 SHOW GLOBAL VARIABLES表示innodb_buffer_pool_size是128M。请将my.cnf更改为24G,关闭/重新启动。 A)1G的max_allowed_pa​​cket_size可能就是您在配置中的意思,考虑到8/7/2017您的远程代理正在发送1G数据包以便在此设备上进行处理。远程代理如何在安排数据发送方面进行管理,以防止在此主机上单独使用内存时耗尽所有48G?状态表示在8/6/2017上的bytes_received是885,485,832,来自正常运行时间的前1520秒内max_used_connections为86。 B)200的innodb_io_capacity可能是你可能的IOPS的显着节流,    我们在700这里运行.sqlio.exe实用程序用于指导我们这个方向。 C)也应该调整innodb_io_capacity_max。 D)thread_cache_size为11,考虑转到128。 E)thread_concurrency为10,考虑转到30.
F)我理解睡眠ID数量中process-list.txt的长度很可能是由持久连接的使用引起的。连接只是等待客户端的一些额外活动一段时间。 2017年8月8日 G)STATUS Com_begin计数通常非常接近Com_commit计数,而不是你的情况。 8/8/2017 Com_begin为2,Com_commit为709,910,持续11小时的正常运行时间 H)如果可能的话,仅查看3分钟的常规日志可能会有所帮助。 让我发布你的进展情况。

答案 2 :(得分:1)

我会检查 table_open_cache 。你有很多表,它显然反映在每秒平均打开的文件中:当正常值介于1和5之间时大约为48。 这由Table_open_cache_missesTable_open_cache_overflows的值确认, 理想情况下,这些值应该是cero。这意味着尝试使用缓存失败,结果浪费了内存。 您应该尝试将其增加至少至3000并查看结果。

因为你在CentOS上:

  1. 我会仔细检查ulimit它是无限的,或者是6000桌上的20000左右。
  2. 考虑将swappiness设置为1.我认为最好有一些swapps(在观察时)而不是崩溃。

答案 3 :(得分:1)

performance_schema = 0 为我工作。

答案 4 :(得分:0)

结果存储并从内存中提供,并且假设您每秒运行283,那么在任何给定时刻可能会有大量数据被抛出。

我认为你在从服务器中挤出很多东西做得很好。考虑表是一回事,然后是涉及6000个表的模式,以及您每秒对35 GB数据库提取283个查询的事实,并且这些结果在服务时保存在内存中。我们其他人也可以向你学习。

关于MySQL的停止和重启

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

你可能会考虑尝试  建议herehereinnodb_flush_method=normal,但我无法保证会有效。

答案 5 :(得分:0)

使用www.mysqlcalculator.com可以在不到2分钟的时间内对十几种记忆消耗因素进行大脑检查。

118个活动线程可能是合理的,但似乎会导致极端情境切换,试图同时回答118个问题。

如果您能够发布它们,我们很乐意看到您的SHOW GLOBAL STATUS和SHOW GLOBAL VARIABLES。

答案 6 :(得分:0)

请在常规配置中启用MySQL错误日志。 当MySQL崩溃时,请在重新启动之前保护错误日志,并添加可用于您的问题的最后一个错误日志。它应该有一个线索为什么MySQL失败了。 当支持SHOW GLOBAL STATUS报告的活动量时,运行“小”配置将像狗一样运行。 请回到您通常的生产配置。 我正在查看您提供的详细信息,并会在接下来的24小时内提供一些调整建议。似乎大多数进程列表活动都与复制有关。这是真的吗?

答案 7 :(得分:0)

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

在[mysqld]块中添加设置

[mysqld]

performance_schema = 0

对于MySQL 5.7.8及更高版本,您将必须添加以下附加设置:

[mysqld]

performance_schema = 0

show_compatibility_56 = 1

注意:这会将您的内存使用量减少到50%-60%以上