在本文中,我将向您展示如何使用新版本的MySQL(5.7+),以及如何更容易地解决 MySQL内存分配中出现的问题。
首先,MySQL由于内存不足而崩溃的主要情况有3种:
- MySQL试图分配比可用内存更多的内存,因为用户在设置中设定的值过高。例如:您没有正确设置innodb_buffer_pool_size,这种问题很容易修复。
- 服务器上运行有其他进程在分配RAM。例如:它可以是某种应用程序(Java、Python、PHP)、web服务器,甚至是备份(即mysqldump)等。当问题的根源被确定后,就可以直接修复了。
- MySQL中的内存泄漏。这是最坏的情况,我们才需要进行故障排除。
MySQL内存泄漏故障排除
下面是我们可以从下面步骤开始((假设它是一个Linux服务器))
第1部分:Linux操作系统和配置检查
- 通过检查MySQL错误日志和Linux日志文件(例如/var/log/messages或/var/log/syslog)来确定mysql崩溃的原因。比如:你可能会看到一个日志条目说OOM程序杀死了MySQL进程。每当MySQL进程被OOM“dmesg”杀死时,日志中也会显示相关的周围环境细节信息。
- 检查可用的内存数量:
free -g
cat /proc/meminfo - avCheck检查哪些应用程序正在使用RAM:“top”或“htop”(参见常驻内存与虚拟内存)。
- 检查MySQL配置:检查/etc/ MySQL .cnf或一般的/etc/my*(包括/etc/mysql/*和其他文件)。
MySQL可能使用不同的my.cnf运行(运行ps ax| grep MySQL)
5.运行vmstat 5,查看系统是否通过虚拟内存进行读写,以及是否进行交换 - 对于非生产环境,我们可以使用其他工具(如Valgrind、gdb等)来检查MySQL的使用情况
第2部分:检查MySQL内部
现在,我们可以检查MySQL内部的内容,以查找潜在的MySQL内存泄漏。
MySQL在很多地方分配内存,特别是:
- 表缓存(Table cache)
- Performance_schema (运行命令:show engine performance ce_schema
status,并查看最后一行,这可能是系统导致RAM减小(即1G或更少)的原因) - InnoDB (运行show engine InnoDB状态并检查缓冲池部分,为buffer_pool和相关缓存分配的内存)
- 内存中的临时表Temporary tables in RAM (执行查询 select * from
information_schema.tables where engine=‘MEMORY’,来查找内存中的所有临时表) - 准备好特定的SQL语句,在它没有被释放时(通过deallocate命令检查准备好的命令的数量,运行显示全局变量的语句:‘Com_prepare_sql’;show
global status like ‘Com_dealloc_sql’)。
好消息是,从MySQL 5.7开始,在performance_schema中有内存分配。以下是我们如何使用它:
1、首先,我们需要启用收集内存指标。
运行:
UPDATE setup_instruments SET ENABLED = ‘YES’ WHERE NAME LIKE ‘memory/%’;
2、从sys模式运行报告:
select event_name, current_alloc, high_alloc from sys.memory_global_by_current_bytes where current_count > 0;
MySQL [performance_schema]> select event_name, current_alloc, high_alloc from sys.memory_global_by_current_bytes where current_count > 0;
+--------------------------------------------------------------------------------+---------------+-------------+
| event_name | current_alloc | high_alloc |
+--------------------------------------------------------------------------------+---------------+-------------+
| memory/performance_schema/events_statements_history_long | 13.66 MiB | 13.66 MiB |
| memory/performance_schema/events_statements_history_long.sqltext | 9.77 MiB | 9.77 MiB |
| memory/performance_schema/events_statements_history_long.tokens | 9.77 MiB | 9.77 MiB |
| memory/performance_schema/events_statements_summary_by_digest.tokens | 9.77 MiB | 9.77 MiB |
| memory/performance_schema/table_handles | 9.06 MiB | 9.06 MiB |
| memory/performance_schema/events_statements_summary_by_thread_by_event_name | 8.67 MiB | 8.67 MiB |
| memory/performance_schema/memory_summary_by_thread_by_event_name | 5.62 MiB | 5.62 MiB |
| memory/performance_schema/events_statements_summary_by_digest | 4.88 MiB | 4.88 MiB |
| memory/performance_schema/events_statements_summary_by_account_by_event_name | 4.33 MiB | 4.33 MiB |
| memory/performance_schema/events_statements_summary_by_user_by_event_name | 4.33 MiB | 4.33 MiB |
| memory/performance_schema/events_statements_summary_by_host_by_event_name | 4.33 MiB | 4.33 MiB |
...
| memory/sql/THD::db | 19 bytes | 23 bytes |
+--------------------------------------------------------------------------------+---------------+-------------+
90 rows in set (0.02 sec)
3、通常,这将在分配内存时为您提供代码中的位置。它通常是自解释的。在某些情况下,我们可以搜索bug,或者需要检查MySQL源代码。