Bug #27516 divide by zero crash during optimize table
Submitted: 29 Mar 2007 10:30 Modified: 27 Apr 2007 15:35
Reporter: Shane Bester (Platinum Quality Contributor) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: MyISAM storage engine Severity:S1 (Critical)
Version:5.0.40 OS:Any
Assigned to: Sergey Vojtovich CPU Architecture:Any
Tags: crash, optimize table

[29 Mar 2007 10:30] Shane Bester
Description:
I was testing the patch for bug #25521 after running that testcase for 45 minutes got this different crash instead:

mysqld-debug.exe!_aulldiv()  Line 87	Asm
mysqld-debug.exe!ha_myisam::info
mysqld-debug.exe!ha_myisam::open
mysqld-debug.exe!handler::ha_open
mysqld-debug.exe!openfrm
mysqld-debug.exe!open_unireg_entry
mysqld-debug.exe!open_table
mysqld-debug.exe!open_tables
mysqld-debug.exe!open_and_lock_tables
mysqld-debug.exe!mysql_admin_table
mysqld-debug.exe!mysql_optimize_table
mysqld-debug.exe!mysql_execute_command
mysqld-debug.exe!mysql_parse
mysqld-debug.exe!dispatch_command
mysqld-debug.exe!do_command
mysqld-debug.exe!handle_one_connection
mysqld-debug.exe!pthread_start
mysqld-debug.exe!_callthreadstart
mysqld-debug.exe!_threadstart

How to repeat:
compile and run testcase.c from bug #25521
just change the time from 300 to 10000 to let it run longer than 5 minutes

Suggested fix:
see private comment
[11 Apr 2007 7:51] Sergey Vojtovich
Stealing this one as it is rather MyISAM bug and I have a guess how to fix it.
[12 Apr 2007 10:24] Sergey Vojtovich
Repeated on linux. My guess seem to be correct.

(gdb) bt
...
#6  0x08500912 in mi_status (info=0xb7b07f80, x=0xb7d7dd50, flag=26) at mi_info.c:60
...

(gdb) fr 6
(gdb) l
55          x->data_file_length =info->state->data_file_length;
56          x->index_file_length=info->state->key_file_length;
57
58          x->keys             = share->state.header.keys;
59          x->check_time       = share->state.check_time;
60          x->mean_reclength   = info->state->records ?
61            (ulong) ((info->state->data_file_length-info->state->empty)/
62                     info->state->records) : (ulong) share->min_pack_length;
63        }
64        if (flag & HA_STATUS_ERRKEY)
(gdb) p info->state->records
$1 = 0
[12 Apr 2007 12:43] 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/24382

ChangeSet@1.2439, 2007-04-12 16:47:25+05:00, svoj@mysql.com +1 -0
  BUG#27516 - divide by zero crash during optimize table
  
  When a table status is requested by statement like SHOW TABLE
  STATUS and there is another statement (e.g. DELETE) sets
  number of records to 0 concurrently, we may get division by
  zero error, which crashes a server.
  
  This is fixed by using thread local variable x->records instead
  of shared info->state->records when we check if it is zero and
  divide by it.
[13 Apr 2007 8:09] Sergey Vojtovich
Approved by Ramil.
[13 Apr 2007 8:32] Sergei Glukhov
ok to push with discussed indentation fix
[13 Apr 2007 8:35] 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/24455

ChangeSet@1.2439, 2007-04-13 12:38:27+05:00, svoj@mysql.com +1 -0
  BUG#27516 - divide by zero crash during optimize table
  
  When a table status is requested by statement like SHOW TABLE
  STATUS and there is another statement (e.g. DELETE) sets
  number of records to 0 concurrently, we may get division by
  zero error, which crashes a server.
  
  This is fixed by using thread local variable x->records instead
  of shared info->state->records when we check if it is zero and
  divide by it.
[27 Apr 2007 9:21] Bugs System
Pushed into 5.1.18-beta
[27 Apr 2007 9:24] Bugs System
Pushed into 5.0.42
[27 Apr 2007 15:35] Paul DuBois
Noted in 5.0.42, 5.1.18 changelogs.

An interaction between SHOW TABLE STATUS and other concurrent
statements that modify the table could result in a divide-by-zero
error and a server crash.