当我增加max_heap_table_size值时MySQL崩溃

我有一个运行在Ubuntu 12.04服务器上的MySQL实例,配备了120 GB的RAM。 有几个PHP脚本运行,它有时会设置新的MySQL参数。 其中一个脚本在将数据插入MySISAM表之前使用大型MEMORY表进行合并。

最近我更新了max_heap_table_size和tmp_table_size从16 GB到20 GB,以避免“表已满”的错误。 结果MySQL在下次运行脚本时崩溃了。

其实它首先产生了一个痕迹:

14:30:19 UTC - mysqld got signal 11 ; This could be because you hit a bug. It is also possible that this binary or one of the libraries it was linked against is corrupt, improperly built, or misconfigured. This error can also be caused by malfunctioning hardware. We will try our best to scrape up some info that will hopefully help diagnose the problem, but since we have already crashed, something is definitely wrong and this may fail. key_buffer_size=536870912 read_buffer_size=131072 max_used_connections=85 max_threads=700 thread_count=82 connection_count=81 It is possible that mysqld could use up to key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 2055554 K bytes of memory Hope that's ok; if not, decrease some variables in the equation. Thread pointer: 0x7ff66dbb4f30 Attempting backtrace. You can use the following information to find out where mysqld died. If you see no messages after this, something went terribly wrong... stack_bottom = 7ff632b80e60 thread_stack 0x28000 /usr/sbin/mysqld(my_print_stacktrace+0x29)[0x7ff66b087589] /usr/sbin/mysqld(handle_fatal_signal+0x483)[0x7ff66af4c9d3] /lib/x86_64-linux-gnu/libpthread.so.0(+0xfcb0)[0x7ff669c96cb0] /usr/sbin/mysqld(_Z10field_convP5FieldS0_+0x37)[0x7ff66af49077] /usr/sbin/mysqld(_ZN10Item_field13save_in_fieldEP5Fieldb+0x46)[0x7ff66af599b6] /usr/sbin/mysqld(_Z11fill_recordP3THDPP5FieldR4ListI4ItemEb+0x4e)[0x7ff66adf3afe] /usr/sbin/mysqld(_ZN12select_union9send_dataER4ListI4ItemE+0x6f)[0x7ff66aea705f] /usr/sbin/mysqld(+0x32c554)[0x7ff66ae5a554] /usr/sbin/mysqld(+0x3225cf)[0x7ff66ae505cf] /usr/sbin/mysqld(_Z10sub_selectP4JOINP13st_join_tableb+0x7e)[0x7ff66ae5255e] /usr/sbin/mysqld(+0x335274)[0x7ff66ae63274] /usr/sbin/mysqld(_ZN4JOIN4execEv+0xc03)[0x7ff66ae72ec3] /usr/sbin/mysqld(_Z12mysql_selectP3THDPPP4ItemP10TABLE_LISTjR4ListIS1_ES2_jP8st_orderSB_S2_SB_yP13select_resultP18st_select_lex_unitP13st_select_lex+0x130)[0x7ff66ae6e610] /usr/sbin/mysqld(_Z21mysql_derived_fillingP3THDP3LEXP10TABLE_LIST+0x121)[0x7ff66ae13671] /usr/sbin/mysqld(_Z20mysql_handle_derivedP3LEXPFbP3THDS0_P10TABLE_LISTE+0x68)[0x7ff66ae130f8] /usr/sbin/mysqld(_Z20open_and_lock_tablesP3THDP10TABLE_LISTbjP19Prelocking_strategy+0x11a)[0x7ff66adf7c9a] /usr/sbin/mysqld(+0x2fac95)[0x7ff66ae28c95] /usr/sbin/mysqld(_Z21mysql_execute_commandP3THD+0x16a6)[0x7ff66ae307f6] /usr/sbin/mysqld(_Z11mysql_parseP3THDPcjP12Parser_state+0x10f)[0x7ff66ae35a0f] /usr/sbin/mysqld(_Z16dispatch_command19enum_server_commandP3THDPcj+0x1e71)[0x7ff66ae37951] /usr/sbin/mysqld(_Z24do_handle_one_connectionP3THD+0x1bd)[0x7ff66aeddd9d] /usr/sbin/mysqld(handle_one_connection+0x50)[0x7ff66aedde00] /lib/x86_64-linux-gnu/libpthread.so.0(+0x7e9a)[0x7ff669c8ee9a] /lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7ff6693bf3fd] Trying to get some variables. Some pointers may be invalid and cause the dump to abort. Query (7fea98004a80): is an invalid pointer Connection ID (thread ID): 15144 Status: NOT_KILLED The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains information that should help you find out what is causing the crash. 

一小时后发生崩溃/重启:

 131122 15:30:24 [Warning] Using unique option prefix myisam-recover instead of myisam-recover-options is deprecated and will be removed in a future release. Please use the full name instead. 131122 15:30:24 [Warning] Using unique option prefix myisam-recover instead of myisam-recover-options is deprecated and will be removed in a future release. Please use the full name instead. 131122 15:30:24 [Note] Plugin 'FEDERATED' is disabled. 131122 15:30:24 InnoDB: The InnoDB memory heap is disabled 131122 15:30:24 InnoDB: Mutexes and rw_locks use GCC atomic builtins 131122 15:30:24 InnoDB: Compressed tables use zlib 1.2.3.4 131122 15:30:24 InnoDB: Initializing buffer pool, size = 128.0M 131122 15:30:24 InnoDB: Completed initialization of buffer pool 131122 15:30:24 InnoDB: highest supported file format is Barracuda. InnoDB: Log scan progressed past the checkpoint lsn 1319218667 131122 15:30:24 InnoDB: Database was not shut down normally! InnoDB: Starting crash recovery. 

不幸的是,我没有binlog或慢查询日志输出到这里,但我可以说的是,PHP脚本继续生成堆栈跟踪后运行。 它在mysql重启过程中停止。

硬件故障不应该被考虑,因为这个错误已经发生在2个不同的服务器上。

造成这次事故的原因是什么? 我怎样才能find最大的max_heap_table_size和tmp_table_size我可以使用,而不会崩溃的MySQL?

 ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 1031141 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 1031141 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited 

对于Ubuntu 12.04,1,mysql版本是5.5.34

有了120GB的内存,机器似乎也有多个物理CPU和一个非统一内存访问(NUMA)架构……如果是这样的话,你可以拥有足够的可用内存,没有足够的可用内存。

如果我目前正在跟踪,那么当MySQL尝试增加分配给MEMORY表的内存时,可能会遇到这个问题,并遇到与在此架构上运行时Linux处理内存分配的方式有关的错误:只考虑直接连接到一个特定CPU上的存储棒上的可用存储器,该存储器被某种程度上任意select为“存储器请求将被服务的那个” – 尽pipe其他物理存储器在母板。

NUMA在理论上是好的,但可能不是理想的单一进程需要大量的内存,如MySQL的情况下…但有一个解决方法。

修复将通过添加以下行来修改mysqld_safe脚本:

 cmd="/usr/bin/numactl --interleave all $cmd" 

紧随此后

 cmd="$NOHUP_NICENESS" 

这里解释了原因,这篇文章写了一篇很好的文章,解释为什么具有这种体系结构的MySQL服务器为什么在可用内存的情况下进行大量交换? 然而,这是笔者后来指出的一个更大问题的症状,“并不完全是交换问题”,即使交换失效,也可能包括“失败的内存分配”。

http://blog.jcole.us/2010/09/28/mysql-swap-insanity-and-the-numa-architecture/

当然,我猜测这是否适用于您的系统,但似乎是一个有价值的可能性。 当我尝试configuration一个64GB InnoDB缓冲池时,我遇到了一个新的128GB计算机上的问题,并且MySQL无法在没有其他运行的计算机上find64GB的空闲空间时,我正好使用了此修补程序。 当我意识到我能够成功使用的最高价值是拥有4个物理处理器的16核机器的总内存的1/4以下…有点像你似乎碰到的东西……是当我把问题的性质放在一起。

tmp_table_size的文档说这个设置是临时表可以在内存中的最大大小。 超过这个大小不会触发任何表是完整的错误; 它会触发从使用内存中的表到磁盘上使用MyISAM表的更改。

系统崩溃了,因为你正在让临时表占用比应该多的内存。 与内存表相同。

你应该放下tmp_table_size的方式 。 请记住,这个设置不是整体最大值。 这是每个临时表的最大值。 如果你有5个查询做一个庞大的临时表(比如说每个20GB以下),现在你的临时表使用了100GB的内存。 添加在第六,你已经使用了更多的RAM比服务器已经总共。

如果您的脚本实际上正在使用MEMORY存储引擎,那么在将数据写入MyISAM文件之后,应该考虑更改该数据。 如果真的需要在临时桌面上执行这么快的性能,那么您应该考虑获得更快的存储容量(例如Fusion-io , Virident等)。 如果这些技术太过于昂贵或过于昂贵,我至less会考虑使用消费级固态硬盘。

当数据caching到系统内存(未使用的RAM)时,MyISAMperformance最佳。 如果你的脚本在每次大量查询(使用MEMORY引擎)的时候都把caching送出去,你的MyISAM性能将会受到影响。

我怀疑这个脚本是在使用MEMORY存储引擎来“提高”它的性能。 如果它是一个临时表,它应该使用临时表,并且你的tmp_table_size应该是小得多的东西,在tmp_table_size中断之后强制它到磁盘。

max_heap_table_size和tmp_table_size的默认值都是16MB。 如果可能,我build议将设置更改回默认值。 在监视资源使用情况(磁盘I / O,总内存使用情况,CPU使用情况等)的同时,以小增量向上调整,直到find可用于数据集的设置。