Bug #47776 Segfault in handler::ha_update_row() at handler.cc:4690 with Innodb
Submitted: 2 Oct 2009 1:51 Modified: 12 Nov 2009 12:01
Reporter: Patrick Crews Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Partitions Severity:S3 (Non-critical)
Version:5.5 WL#3352 OS:Any
Assigned to: Mikael Ronström CPU Architecture:Any
Tags: crashing bug, innodb, Memory, partitioning, RANGE COLUMN_LIST
Triage: Triaged: D1 (Critical)

[2 Oct 2009 1:51] Patrick Crews
Description:
The following query:
UPDATE `PP_H` SET `varchar_5` = 'z' WHERE ( ( ( `PP_H` . `varchar_5` >= 'j' ) OR `PP_H` . `varchar_5`  IN ('q', 'r' ) ) OR `PP_H` . `int_signed`  BETWEEN 3 AND ( 3 + 8 ) );

On the table below (used in test case) will fail via 'no partition for that value' error despite the UPDATE'd value being within the defined partitions and will crash via segfault on Innodb.  The provided test case works perfectly on MyISAM.

Partition setup used: (full table in the test case)
<snip>
 /*!50100 PARTITION BY range column_list(varchar_5, varchar_10)
subpartition by hash ( year(`date`))
subpartitions 2 (
 partition p0 values less than (column_list('m','m')),
partition p1 values less than (column_list('za','za'))) */;

Partial crash output (full output attached as separate file):
Thread 1 (process 3837):
#0  0xb7f2f430 in __kernel_vsyscall ()
#1  0xb7f121c8 in pthread_kill () from /lib/tls/i686/cmov/libpthread.so.0
#2  0x08de4e4f in my_write_core (sig=6) at stacktrace.c:310
#3  0x0840befc in handle_segfault (sig=6) at mysqld.cc:2569
#4  <signal handler called>
#5  0xb7f2f430 in __kernel_vsyscall ()
#6  0xb7d596d0 in raise () from /lib/tls/i686/cmov/libc.so.6
#7  0xb7d5b098 in abort () from /lib/tls/i686/cmov/libc.so.6
#8  0x08b10a36 in row_update_for_mysql (mysql_rec=0xb689580 "\f?\001p         \001m    ", prebuilt=0xb69b780) at row/row0mysql.c:1355
#9  0x08a4d052 in ha_innobase::update_row (this=0xb6893e8, old_row=0xb689580 "\f?\001p         \001m    ", 
    new_row=0xb689538 "\f?\001p         \001z    ") at handler/ha_innodb.cc:4663
#10 0x0878b533 in handler::ha_update_row (this=0xb6893e8, old_data=0xb689580 "\f?\001p         \001m    ", 
    new_data=0xb689538 "\f?\001p         \001z    ") at handler.cc:4690
#11 0x087b0373 in ha_partition::update_row (this=0xb688eb0, old_data=0xb689580 "\f?\001p         \001m    ", 
    new_data=0xb689538 "\f?\001p         \001z    ") at ha_partition.cc:3090
#12 0x0878b533 in handler::ha_update_row (this=0xb688eb0, old_data=0xb689580 "\f?\001p         \001m    ", 
    new_data=0xb689538 "\f?\001p         \001z    ") at handler.cc:4690
#13 0x0863d305 in mysql_update (thd=0xb653318, table_list=0xb68b0c8, fields=@0xb65474c, values=@0xb654968, conds=0xb68b880, order_num=0, order=0x0, 
    limit=18446744073709551591, handle_duplicates=DUP_ERROR, ignore=false, found_return=0xb27a26a0, updated_return=0xb27a2698) at sql_update.cc:649
#14 0x08448cd4 in mysql_execute_command (thd=0xb653318) at sql_parse.cc:3057
#15 0x0845f33f in mysql_parse (thd=0xb653318, 
    inBuf=0xb68aef0 "UPDATE `PP_H` SET `varchar_5` = 'z' WHERE ( ( ( `PP_H` . `varchar_5` >= 'j' ) OR `PP_H` . `varchar_5`  IN ('q', 'r' ) ) OR `PP_H` . `int_signed`  BETWEEN 3 AND ( 3 + 8 ) )", length=171, found_semicolon=0xb27a3054) at sql_parse.cc:6002
#16 0x08461ae4 in dispatch_command (command=COM_QUERY, thd=0xb653318, 
    packet=0xb677fd1 "UPDATE `PP_H` SET `varchar_5` = 'z' WHERE ( ( ( `PP_H` . `varchar_5` >= 'j' ) OR `PP_H` . `varchar_5`  IN ('q', 'r' ) ) OR `PP_H` . `int_signed`  BETWEEN 3 AND ( 3 + 8 ) )", packet_length=171) at sql_parse.cc:1222
#17 0x08465739 in do_command (thd=0xb653318) at sql_parse.cc:855
#18 0x0842a3bf in handle_one_connection (arg=0xb653318) at sql_connect.cc:1131
#19 0xb7f0d4ff in start_thread () from /lib/tls/i686/cmov/libpthread.so.0
#20 0xb7e1249e in clone () from /lib/tls/i686/cmov/libc.so.6

How to repeat:
MTR test case is attached.

Please alter the ENGINE='' clause and observe how the test case performs:
MYISAM: pass
MEMORY:  No partition for that value ('z')
Innodb: Crash via segfault

Suggested fix:
Ensure crash-free, correct query processing
[2 Oct 2009 1:54] Patrick Crews
Full crash output for Innodb crash

Attachment: bug47776_crash_output.txt (text/plain), 13.25 KiB.

[2 Oct 2009 1:55] Patrick Crews
MTR test case.  Alter engine settings for different behavior (MEMORY and InnoDB)

Attachment: bug47776_test.txt (text/plain), 23.83 KiB.

[5 Oct 2009 13:10] Mikael Ronström
create table t1 (a varchar(5))
engine=memory
partition by range column_list(a)
( partition p0 values less than (column_list('m')),
  partition p1 values less than (column_list('za')));
insert into t1 values  ('j');
update t1 set a = 'z' where (a >= 'j');

The above test case is the minimum test case generating this bug.
The problem is that conversion in my_strnxfrm used the wrong length
which led to an erroneus comparison between partition fields and
record value. This was only for character set fields.
[5 Oct 2009 13:16] Mikael Ronström
There was another bug lurking in this same area, where I compared
a my_strnxfrm-converted value with a field in standard format, not
so good. Need to fix this also as part of this bug fix.
[5 Oct 2009 14:14] 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/85764

2884 Mikael Ronstrom	2009-10-05
      BUG#47776, Fixed character set handling, used wrong length, eventually also found that didn't need to convert to my_strnxfrm-format for column list partitioned tables, also column list partitioned tables can use multi-byte character sets in partition fields as well as where strxfrm multiplies the number of bytes in the string
      modified:
        mysql-test/r/partition_innodb.result
        mysql-test/t/partition_innodb.test
        sql/sql_partition.cc
[5 Nov 2009 6:51] Bugs System
Pushed into 6.0.14-alpha (revid:mikael@mysql.com-20091104090210-om5lq1v39ppduu0e) (version source revid:mikael@mysql.com-20091030163450-387z4yevx0lrj3fb) (merge vers: 6.0.14-alpha) (pib:13)
[5 Nov 2009 17:38] Jon Stephens
Discussed with Mikael; he confirmed that this fix was pushed together with main push for WL#3352; closed without further action.
[12 Nov 2009 8:19] Bugs System
Pushed into 5.5.0-beta (revid:alik@sun.com-20091110093229-0bh5hix780cyeicl) (version source revid:mikael@mysql.com-20091028172236-0v5j962mh2opxpkj) (merge vers: 5.5.0-beta) (pib:13)
[12 Nov 2009 12:01] Jon Stephens
Re-closed per previous comments-.