Bug #56902 Reproducible/systematic core by myisampack (latest 5.1.50 version)
Submitted: 21 Sep 2010 16:43 Modified: 21 Sep 2010 19:04
Reporter: John Sweeney Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: MyISAM storage engine Severity:S1 (Critical)
Version:mysql-5.1.50.tar OS:Linux (Linux 2.6.18-164.el5xen Red Hat)
Assigned to: CPU Architecture:Any
Tags: Contribution, myisampack

[21 Sep 2010 16:43] John Sweeney
Description:
Red Hat Enterprise Linux Server release 5.4 (Tikanga)
Linux 2.6.18-164.el5xen #1 SMP Tue Aug 18 15:59:52 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
MySQL-server-enterprise-5.1.42-0.rhel5

This issue was found using the above software, but was repeated using mysql-5.1.50.

[root@cyclops mars_v19]# pwd
/Database/mysql/mars_v19
[root@cyclops mars_v19]# myisampack cc_evt_hdr_100912_1_bug_new
Compressing cc_evt_hdr_100912_1_bug_new.MYD: (200001 records)
- Calculating statistics
- Compressing file
Segmentation fault (core dumped)
[root@cyclops mars_v19]#

This core occurs systematically, even with the latest version of myisampack. 

The myisam table cc_evt_hdr_100912_1_bug_new is fully functional within mysql for queries and has been "check" within mysql.

| | fields: record: 58616  length: 11  blob-length: 0  length-bytes: 1
| | fields: ===
| | >_mi_read_rnd_static_record
| | <_mi_read_rnd_static_record
| | fields: column:   1  type:  5  pack:  0  zero:    0  lbits:  0  tree:  1  length:    1
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:   2  type:  0  pack:  0  zero:    0  lbits:  0  tree:  2  length:    8
| | fields: FIELD_NORMAL 8 bytes
| | fields: value: 0x82  code: 0x0000000000000056  bits:  8  bin: 01010110
| | fields: value: 0xaa  code: 0x000000000000008e  bits:  8  bin: 10001110
| | fields: value: 0x9a  code: 0x000000000000008c  bits:  8  bin: 10001100
| | fields: value: 0xf1  code: 0x00000000000000b2  bits:  8  bin: 10110010
| | fields: value: 0x79  code: 0x0000000000000061  bits:  8  bin: 01100001
| | fields: value: 0xdd  code: 0x00000000000000ea  bits:  8  bin: 11101010
| | fields: value: 0x7f  code: 0x000000000000008f  bits:  8  bin: 10001111
| | fields: value: 0xe4  code: 0x00000000000000fe  bits:  8  bin: 11111110
| | fields: ---
| | fields: column:   3  type:  5  pack:  0  zero:    0  lbits:  7  tree:  3  length:  100
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:   4  type:  6  pack:  0  zero:    0  lbits:  1  tree:  4  length:    4
| | fields: FIELD_INTERVALL
| | fields: index:    0 code: 0x0000000000000000  bits:  1
| | fields: ---
| | fields: column:   5  type:  5  pack:  0  zero:    0  lbits:  0  tree:  5  length:    1
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:   6  type:  6  pack:  0  zero:    0  lbits:  6  tree:  6  length:   60
| | fields: FIELD_INTERVALL
| | fields: index:    0 code: 0x0000000000000001  bits:  1
| | fields: ---
| | fields: column:   7  type:  5  pack:  0  zero:    0  lbits:  0  tree:  7  length:    1
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:   8  type:  6  pack:  0  zero:    0  lbits:  6  tree:  8  length:   60
| | fields: FIELD_INTERVALL
| | fields: index:    0 code: 0x0000000000000001  bits:  1
| | fields: ---
| | fields: column:   9  type:  6  pack:  0  zero:    0  lbits:  0  tree:  9  length:    2
| | fields: FIELD_INTERVALL
| | fields: index:    0 code: 0x0000000000000000  bits:  1
| | fields: ---
| | fields: column:  10  type:  6  pack:  0  zero:    0  lbits:  1  tree: 10  length:    3
| | fields: FIELD_INTERVALL
| | fields: index:    0 code: 0x0000000000000000  bits:  1
| | fields: ---
| | fields: column:  11  type:  5  pack:  0  zero:    0  lbits:  0  tree: 11  length:    8
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:  12  type:  6  pack:  0  zero:    0  lbits:  0  tree: 12  length:    8
| | fields: FIELD_INTERVALL
| | fields: index:    0 code: 0x0000000000000000  bits:  1
| | fields: ---
| | fields: column:  13  type:  5  pack:  0  zero:    0  lbits:  0  tree: 13  length:    8
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:  14  type:  7  pack:  0  zero:    0  lbits:  0  tree:  2  length:    1
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:  15  type:  7  pack:  0  zero:    0  lbits:  0  tree:  2  length:    1
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:  16  type:  7  pack:  0  zero:    0  lbits:  0  tree:  2  length:    1
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:  17  type:  7  pack:  0  zero:    0  lbits:  0  tree:  2  length:    2
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:  18  type:  7  pack:  0  zero:    0  lbits:  0  tree:  2  length:    4
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:  19  type:  7  pack:  0  zero:    0  lbits:  0  tree:  2  length:    4
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:  20  type:  3  pack:  4  zero:    3  lbits:  0  tree: 14  length:    4
| | fields: FIELD_SKIP_ZERO zeroes only, bits:  1
| | fields: ---
| | fields: column:  21  type:  3  pack:  4  zero:    3  lbits:  0  tree: 14  length:    4
| | fields: FIELD_SKIP_ZERO not only zeroes, bits:  1
| | fields: FIELD_NORMAL 1 bytes
| | fields: value: 0x03  code: 0x0000000000000001  bits:  1  bin: 1
| | fields: ---
| | fields: column:  22  type:  7  pack:  0  zero:    0  lbits:  0  tree:  2  length:    1
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:  23  type:  7  pack:  0  zero:    0  lbits:  0  tree:  2  length:    2
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:  24  type:  7  pack:  0  zero:    0  lbits:  0  tree:  2  length:    2
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:  25  type:  7  pack:  0  zero:    0  lbits:  0  tree:  2  length:    3
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:  26  type:  5  pack:  0  zero:    0  lbits:  0  tree: 15  length:    1
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:  27  type:  7  pack:  0  zero:    0  lbits:  0  tree:  2  length:    3
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:  28  type:  0  pack:  4  zero:    1  lbits:  0  tree: 16  length:    2
| | fields: FIELD_NORMAL 1 bytes
| | fields: value: 0x00  code: 0x0000000000000000  bits:  1  bin: 0
| | fields: ---
| | fields: column:  29  type:  6  pack:  0  zero:    0  lbits:  4  tree: 17  length:   20
| | fields: FIELD_INTERVALL
| | fields: index:    0 code: 0x0000000000000000  bits:  1
| | fields: ---
| | fields: column:  30  type:  5  pack:  0  zero:    0  lbits:  6  tree: 18  length:   45
| | fields: FIELD_CONSTANT/ZERO/CHECK
| | fields: ---
| | fields: column:  31  type:  6  pack:  0  zero:    0  lbits:  6  tree: 19  length:   45
| | fields: FIELD_INTERVALL
| | fields: index:    1 code: 0x000000000000000e  bits:  4
| | fields: ---
| | fields: column:  32  type:  6  pack:  0  zero:    0  lbits:  0  tree: 20  length:    8
| | fields: FIELD_INTERVALL
| | fields: index:    0 code: 0x0000000000000001  bits:  2
| | fields: ---
| | >my_write
| | | my: Fd: 6  Buffer: 0x186baff0  Count: 65520  MyFlags: 52
| | <my_write
| | fields: record: 58617  length: 18446744073709486107  blob-length: 0  length-bytes: 5
| | fields: ===
Segmentation fault

The length is obviously incorrect as 18446744073709486107 leading to the core.

How to repeat:
I will attach a gziped tarball of the tables MYI,MYD and FRM files, which can be used to reproduce this issue. The core depends on the size and contents of the table and I tried to reduce the size of the table to as small as possible while still producing the core.

64bit linux machine: (the problem also existed with a 32bit myisampack build)

[root@cyclops tmp]# gzip -d mysql_bug.tar.gz
[root@cyclops tmp]# tar -xvf mysql_bug.tar
cc_evt_hdr_100912_1_bug_new.frm
cc_evt_hdr_100912_1_bug_new.MYD
cc_evt_hdr_100912_1_bug_new.MYI
[root@cyclops tmp]# myisampack cc_evt_hdr_100912_1_bug_new
Compressing cc_evt_hdr_100912_1_bug_new.MYD: (200001 records)
- Calculating statistics
- Compressing file
Segmentation fault (core dumped)
[root@cyclops tmp]#                

Suggested fix:
I looked through the code and the problem lies within the function compress_isam_file of the module /storage/myisam/myisampack.c. The variable max_calc_length is incorrectly calculated for the data, when I 'patched' the code to increment this value by one the core no longer occurs and the table is now correctly packed. I do not believe this is a fix, but highlights the incorrect determining of the max length for the given data.

diff ./storage/myisam/myisampack.c ./storage/myisam/myisampack.c.original
2457,2459d2456
<
<   max_calc_length+=1;
<

Here is the existing code with the small workaround:

  /*
    Calculate the maximum number of bits required to pack the records.
    Remember to understand 'max_zero_fill' as 'min_zero_fill'.
    The tree height determines the maximum number of bits per value.
    Some fields skip leading or trailing spaces or zeroes. The skipped
    number of bytes is encoded by 'length_bits' bits.
    Empty blobs and varchar are encoded with a single 1 bit. Other blobs
    and varchar get a leading 0 bit.
  */
  for (i=max_calc_length=0 ; i < isam_file->s->base.fields ; i++)
  {
    if (!(huff_counts[i].pack_type & PACK_TYPE_ZERO_FILL))
      huff_counts[i].max_zero_fill=0;
    if (huff_counts[i].field_type == FIELD_CONSTANT ||
	huff_counts[i].field_type == FIELD_ZERO ||
	huff_counts[i].field_type == FIELD_CHECK)
      continue;
    if (huff_counts[i].field_type == FIELD_INTERVALL)
      max_calc_length+=huff_counts[i].tree->height;
    else if (huff_counts[i].field_type == FIELD_BLOB ||
	     huff_counts[i].field_type == FIELD_VARCHAR)
      max_calc_length+=huff_counts[i].tree->height*huff_counts[i].max_length + huff_counts[i].length_bits +1;
    else
      max_calc_length+=
	(huff_counts[i].field_length - huff_counts[i].max_zero_fill)*
	  huff_counts[i].tree->height+huff_counts[i].length_bits;
  }

  max_calc_length+=1; /* HERE IS THE ONLY MODIFICATION TO WORKAROUND THIS ISSUE */
[21 Sep 2010 16:50] John Sweeney
I have uploaded the file bug-data-56902.zip containing the smallest table I could create while reproducing this problem (myi,frm and myd) to ftp://ftp.mysql.com/pub/mysql/upload/

This zip file bug-data-56902.zip contains the gzipped tarball mysql_bug.tar.gz.
[21 Sep 2010 19:04] Sveta Smirnova
Thank you for the report.

Verified as described.