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 */