Bug #72995 mysql server crash slient when out of memory using srv_use_sys_malloc
Submitted: 13 Jun 2014 3:23 Modified: 15 Jul 2014 17:54
Reporter: jiang xiaobing Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S3 (Non-critical)
Version:5.6.21 OS:Any
Assigned to: CPU Architecture:Any

[13 Jun 2014 3:23] jiang xiaobing
Description:
when alloc memory failed, ut_a() failed, slient crash the server.

code:

        ulint   retry_count;
        void*   ret;

        if (UNIV_LIKELY(srv_use_sys_malloc)) {
                ret = malloc(n);
                ut_a(ret || !assert_on_error);

                return(ret);
        }

        ut_ad((sizeof(ut_mem_block_t) % 8) == 0); /* check alignment ok */
        ut_a(ut_mem_block_list_inited);

        retry_count = 0;

(gdb) bt
#0  0x00a79402 in __kernel_vsyscall ()
#1  0x00d0f067 in pthread_kill () from /lib/libpthread.so.0
#2  0x08530e8b in my_write_core (sig=6) at /home/mysql/soft/mysql-5.6.16/mysys/stacktrace.c:422
#3  0x082614fe in handle_fatal_signal (sig=146742576) at /home/mysql/soft/mysql-5.6.16/sql/signal_handler.cc:248
#4  <signal handler called>
#5  0x00a79402 in __kernel_vsyscall ()
#6  0x00bb9d10 in raise () from /lib/libc.so.6
#7  0x00bbb621 in abort () from /lib/libc.so.6
#8  0x0869bcdd in ut_malloc_low (n=16777216, assert_on_error=1) at /home/mysql/soft/mysql-5.6.16/storage/innobase/ut/ut0mem.cc:105
#9  0x0863bd48 in row_merge_buf_create (index=0x949068) at /home/mysql/soft/mysql-5.6.16/storage/innobase/row/row0merge.cc:167
#10 0x0863cc89 in row_merge_read_clustered_index (trx=0x8e1b5d0, table=0x7750c0, old_table=0x1507368, new_table=0x1044e38, online=true, index=0x7899e0, fts_sort_idx=0x0, psort_info=0x0, files=0x948eb8,
    key_numbers=0x7899f0, n_index=3, add_cols=0x789b10, col_map=0x789c08, add_autoinc=4294967295, sequence=@0x1060124, block=0xbd9a7000 "")
    at /home/mysql/soft/mysql-5.6.16/storage/innobase/row/row0merge.cc:1255
#11 0x08640adb in row_merge_build_indexes (trx=0x8e1b5d0, old_table=0x1507368, new_table=0x1044e38, online=true, indexes=0x7899e0, key_numbers=0x7899f0, n_indexes=3, table=0x7750c0, add_cols=0x789b10,
    col_map=0x789c08, add_autoinc=4294967295, sequence=@0x1060124) at /home/mysql/soft/mysql-5.6.16/storage/innobase/row/row0merge.cc:3534
#12 0x085c00e6 in ha_innobase::inplace_alter_table (this=0x15176d8, altered_table=0x7750c0, ha_alter_info=0xccb8cfc) at /home/mysql/soft/mysql-5.6.16/storage/innobase/handler/handler0alter.cc:3923
#13 0x083413c8 in mysql_inplace_alter_table (thd=0x8df5560, table_list=0x105ee38, table=0x155c2b0, altered_table=0x7750c0, ha_alter_info=0xccb8cfc,
    inplace_supported=HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE, target_mdl_request=0xccb986c, alter_ctx=0xccb7ea4) at /home/mysql/soft/mysql-5.6.16/sql/handler.h:2863
#14 0x083439a1 in mysql_alter_table (thd=0x8df5560, new_db=0x105f208 "G2", new_name=0x0, create_info=0xccb9e80, table_list=0x105ee38, alter_info=0xccb9f08, order_num=0, order=0x0, ignore=false)
    at /home/mysql/soft/mysql-5.6.16/sql/sql_table.cc:8320
#15 0x08457a86 in Sql_cmd_alter_table::execute (this=0x105f378, thd=0x8df5560) at /home/mysql/soft/mysql-5.6.16/sql/sql_alter.cc:313
#16 0x082f1741 in mysql_execute_command (thd=0x8df5560) at /home/mysql/soft/mysql-5.6.16/sql/sql_parse.cc:4936
#17 0x082f62fd in mysql_parse (thd=0x8df5560, rawbuf=0x105ece8 "alter table sale_award add billid varchar(30) not null default '' after id, add unique index(billid)", length=100, parser_state=0xccbb1d8)
    at /home/mysql/soft/mysql-5.6.16/sql/sql_parse.cc:6235
#18 0x082f78ea in dispatch_command (command=COM_QUERY, thd=0x8df5560, packet=0x1402489 "alter table sale_award add billid varchar(30) not null default '' after id, add unique index(billid)",
    packet_length=100) at /home/mysql/soft/mysql-5.6.16/sql/sql_parse.cc:1334
#19 0x082f9662 in do_command (thd=0x8df5560) at /home/mysql/soft/mysql-5.6.16/sql/sql_parse.cc:1036
#20 0x082ba786 in do_handle_one_connection (thd_arg=0x8df5560) at /home/mysql/soft/mysql-5.6.16/sql/sql_connect.cc:982
#21 0x082ba89c in handle_one_connection (arg=0xcdc0f40) at /home/mysql/soft/mysql-5.6.16/sql/sql_connect.cc:898
#22 0x08582bb0 in pfs_spawn_thread (arg=0xcdab338) at /home/mysql/soft/mysql-5.6.16/storage/perfschema/pfs.cc:1858
#23 0x00d0a45b in start_thread () from /lib/libpthread.so.0
#24 0x00c61c4e in clone () from /lib/libc.so.6

How to repeat:
do some operation need a lot of memory, exp: alter table in my case.

Suggested fix:
add some log before the ut_a() like below in the function when srv_use_system_alloc != true.

                if (retry_count == 0) {
                        ut_print_timestamp(stderr);

                        fprintf(stderr,
                                "  InnoDB: Error: cannot allocate"
                                " %lu bytes of\n"
                                "InnoDB: memory with malloc!"
                                " Total allocated memory\n"
                                "InnoDB: by InnoDB %lu bytes."
                                " Operating system errno: %lu\n"
                                "InnoDB: Check if you should"
                                " increase the swap file or\n"
                                "InnoDB: ulimits of your operating system.\n"
                                "InnoDB: On FreeBSD check you"
                                " have compiled the OS with\n"
                                "InnoDB: a big enough maximum process size.\n"
                                "InnoDB: Note that in most 32-bit"
                                " computers the process\n"
                                "InnoDB: memory space is limited"
                                " to 2 GB or 4 GB.\n"
                                "InnoDB: We keep retrying"
                                " the allocation for 60 seconds...\n",
                                (ulong) n, (ulong) ut_total_allocated_memory,
#ifdef __WIN__
                                (ulong) GetLastError()
#else
                                (ulong) errno
#endif
                                );
                }
[15 Jul 2014 17:54] Sveta Smirnova
Thank you for the reasonable feature request.

This is function ut_malloc_low in storage/innobase/ut/ut0mem.cc