Bug #35272 @@global.key_buffer_size = 4294967295 let the server crash
Submitted: 13 Mar 2008 15:45 Modified: 16 Apr 2008 22:45
Reporter: Horst Hunger Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S1 (Critical)
Version:5.1.24-rc OS:Linux (Suse 10.3)
Assigned to: Davi Arnaut CPU Architecture:Any

[13 Mar 2008 15:45] Horst Hunger
Description:
The following setting of key_buffer_size let the server crash:
SET @@global.key_buffer_size = 4294967295;
SET @@global.key_buffer_size = -1;
SET @@global.key_buffer_size = 100000000000;
SET @@global.key_buffer_size = -1024;

the core:

Core was generated by `/work/merge/mysql-5.1-folio3/sql/mysqld --no-defaults --basedir=/work/merge/mys'.
Program terminated with signal 6, Aborted.
#0  0xffffe410 in __kernel_vsyscall ()
(gdb) bt
#0  0xffffe410 in __kernel_vsyscall ()
#1  0xb7f9d397 in pthread_kill () from /lib/libpthread.so.0
#2  0x08443cbb in write_core (sig=6) at stacktrace.c:305
#3  0x082af045 in handle_segfault (sig=6) at mysqld.cc:2489
#4  <signal handler called>
#5  0xffffe410 in __kernel_vsyscall ()
#6  0xb7e038f5 in raise () from /lib/libc.so.6
#7  0xb7e051e1 in abort () from /lib/libc.so.6
#8  0xb7dfcc1e in __assert_fail () from /lib/libc.so.6
#9  0x08297ee5 in Diagnostics_area::set_ok_status (this=0x89f901c,
    thd=0x89f8288, affected_rows_arg=0, last_insert_id_arg=0, message_arg=0x0)
    at sql_class.cc:397
#10 0x081dcc85 in my_ok (thd=0x89f8288, affected_rows=0, id=0, message=0x0)
    at sql_class.h:2147
#11 0x082c3914 in mysql_execute_command (thd=0x89f8288) at sql_parse.cc:3250
#12 0x082c898a in mysql_parse (thd=0x89f8288,
    inBuf=0x8a6fd00 "SET @@global.key_buffer_size = 4294967295", length=41,
    found_semicolon=0xb74b726c) at sql_parse.cc:5626
#13 0x082c9545 in dispatch_command (command=COM_QUERY, thd=0x89f8288,
    packet=0x8a60e49 "SET @@global.key_buffer_size = 4294967295",
    packet_length=41) at sql_parse.cc:1121
#14 0x082ca6af in do_command (thd=0x89f8288) at sql_parse.cc:781
#15 0x082b80bb in handle_one_connection (arg=0x89f8288) at sql_connect.cc:1105
#16 0xb7f98192 in start_thread () from /lib/libpthread.so.0
#17 0xb7e9d02e in clone () from /lib/libc.so.6
(gdb)

How to repeat:
execute the set statements mentioned above.
[13 Mar 2008 16:10] MySQL Verification Team
Thank you for the bug report.

080313 12:58:13 [ERROR] 5.1/libexec/mysqld: Out of memory at line 64, 'my_largepage.c'
080313 12:58:13 [ERROR] 5.1/libexec/mysqld: needed 566346752 byte (553073k), memory in use: 3513285640 bytes (3430944k)
mysqld: sql_class.cc:396: void Diagnostics_area::set_ok_status(THD*, ha_rows, ulonglong, const char*): Assertion `! is_set()' failed.
080313 13:04:21 - mysqld got signal 6 ;
<>
[14 Mar 2008 4:15] Tatiana Azundris Nuernberg
Confirmed as not raised in 5.0

bt:
#3  0xb7dfd801 in abort () from /lib/libc.so.6
#4  0xb7df57bb in __assert_fail () from /lib/libc.so.6
#5  0x0826b9df in Diagnostics_area::set_ok_status (this=0x89c7f48, thd=0x89c72b0, affected_rows_arg=0, last_insert_id_arg=0, message_arg=0x0) at sql_class.cc:389
#6  0x081b0a49 in send_ok (thd=0x89c72b0, affected_rows=0, id=0, message=0x0) at sql_class.h:2105
#7  0x0829734e in mysql_execute_command (thd=0x89c72b0) at sql_parse.cc:3186
#8  0x0829c388 in mysql_parse (thd=0x89c72b0, inBuf=0x8a3ea00 "SET @@global.key_buffer_size = 4294967295", length=41, found_semicolon=0xb74b027c) at sql_parse.cc:5577
#9  0x0829cf44 in dispatch_command (command=COM_QUERY, thd=0x89c72b0, packet=0x8a2fb49 "SET @@global.key_buffer_size = 4294967295", packet_length=41) at sql_parse.cc:1090
#10 0x0829e10a in do_command (thd=0x89c72b0) at sql_parse.cc:764

set_ok_status() complains because status was already set to error; send_ok() should not have been called in sql_parse.cc:3186 or, more to the point, sql_set_variables() should have returned with an error.

Error handling here seems fishy:

#0  init_key_cache (keycache=0x89a5610, key_cache_block_size=1024, use_mem=4294963200, division_limit=100, age_threshold=300) at mf_keycache.c:431
#1  0x086766d6 in resize_key_cache (keycache=0x89a5610, key_cache_block_size=1024, use_mem=4294963200, division_limit=100, age_threshold=300) at mf_keycache.c:646
#2  0x083a0570 in ha_resize_key_cache (key_cache=0x89a5610) at handler.cc:2798
#3  0x082a9bfa in sys_var_key_buffer_size::update (this=0x8992520, thd=0x89c72a8, var=0x8a3ea18) at set_var.cc:2106
#4  0x0829fc1c in set_var::update (this=0x8a3ea18, thd=0x89c72a8) at set_var.cc:3278
#5  0x082a6de6 in sql_set_variables (thd=0x89c72a8, var_list=0x89c87d8) at set_var.cc:3163
#6  0x082972d6 in mysql_execute_command (thd=0x89c72a8) at sql_parse.cc:3179
#7  0x0829c388 in mysql_parse (thd=0x89c72a8, inBuf=0x8a3e900 "SET @@global.key_buffer_size = 4294967295", length=41, found_semicolon=0xb74ad27c) at sql_parse.cc:5577
#8  0x0829cf44 in dispatch_command (command=COM_QUERY, thd=0x89c72a8, packet=0x8a2fa49 "SET @@global.key_buffer_size = 4294967295", packet_length=41) at sql_parse.cc:1090
#9  0x0829e10a in do_command (thd=0x89c72a8) at sql_parse.cc:764
#10 0x0828bbbd in handle_one_connection (arg=0x89c72a8) at sql_connect.cc:1120
[14 Mar 2008 7:26] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/43975

ChangeSet@1.2671, 2008-03-14 08:26:31+01:00, tnurnberg@mysql.com +3 -0
  Bug#35272: @@global.key_buffer_size = 4294967295 let the server crash
  
  When failing to get requested amount of memory for keybuffer,
  we signalled an error to the console and while trying to send
  OK to the client. Hilarity ensued.
  
  We are actually checking the return value of the function that
  detects the error condition now, and propagate it upwards.
[25 Mar 2008 19:00] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/44418

ChangeSet@1.2570, 2008-03-25 15:53:57-03:00, davi@mysql.com +3 -0
  Bug#35272: @@global.key_buffer_size = 4294967295 let the server crash
  
  When trying to get the requested amount of memory for the keybuffer,
  the out of memory could be signaled if one of the tentative allocations
  fail. Later the server would crash (debug assert) when trying to send
  a ok packet with a error set.
  
  The solution is only to signal the error if all tentative allocations
  for the keybuffer fail.
[25 Mar 2008 19:04] Davi Arnaut
Queued to 5.1-bugteam
[27 Mar 2008 15:37] Tatiana Azundris Nuernberg
Docs team: since we INTERNALLY adjust the keybuffer-size downwards until our memory-allocation succeeds, the system variable reflects what we ASKED FOR rather than what we GOT in terms of keybuffer-buffer. Please make explicit in docs that selecting the system variable will show a *maximum-size*, not the *current size* for that buffer!
[27 Mar 2008 16:46] Tatiana Azundris Nuernberg
no-longer-relevant test-case backed out of 5.1-bugteam after discussing with all concerned parties, valeu
[31 Mar 2008 14:54] Bugs System
Pushed into 5.1.24-rc
[3 Apr 2008 13:02] Bugs System
Pushed into 6.0.5-alpha
[16 Apr 2008 22:45] Paul DuBois
Noted in 5.1.24, 6.0.5 changelogs.

Memory-allocation failures for attempts to set key_buffer_size to
large values could result in a server crash.