Bug #10465 | DECIMAL, crash on DELETE | ||
---|---|---|---|
Submitted: | 9 May 2005 9:43 | Modified: | 24 May 2005 19:41 |
Reporter: | Matthias Leich | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server | Severity: | S2 (Serious) |
Version: | 5.0 | OS: | |
Assigned to: | Jani Tolonen | CPU Architecture: | Any |
[9 May 2005 9:43]
Matthias Leich
[9 May 2005 9:45]
Matthias Leich
test case
Attachment: nist_test.test (application/test, text), 3.14 KiB.
[9 May 2005 9:46]
Matthias Leich
master.err
Attachment: master.err (application/octet-stream, text), 4.72 KiB.
[9 May 2005 9:53]
Jan Lindström
Addditional information: 050509 11:56:53InnoDB: Assertion failure in thread 147466 in file row0sel.c line 2082 InnoDB: Failing assertion: dict_col_get_type(field->col)->mtype == dfield_get_type(dfield)->mtype InnoDB: We intentionally generate a memory trap. InnoDB: Submit a detailed bug report to http://bugs.mysql.com. InnoDB: If you get repeated assertion failures or crashes, even InnoDB: immediately after the mysqld startup, there may be InnoDB: corruption in the InnoDB tablespace. Please refer to InnoDB: http://dev.mysql.com/doc/mysql/en/Forcing_recovery.html InnoDB: about forcing recovery. Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 147466 (LWP 15439)] 0x0830ab2a in row_sel_convert_mysql_key_to_innobase (tuple=0x40ad8468, buf=0x8c7741a '¥' <repeats 62 times>, "h4z\025é\a", buf_len=57, index=0x40ae4468, key_ptr=0x65d0143b "¥p'a\bž Å\b\n", key_len=4, trx=0x40ad3468) at row0sel.c:2082 2082 == dfield_get_type(dfield)->mtype); Current language: auto; currently c (gdb) p dict_col_get_type(field->col) $1 = (dtype_t *) 0x40ae30b8 (gdb) p *dict_col_get_type(field->col) $2 = {mtype = 8, prtype = 256, len = 6, prec = 0, mbminlen = 0, mbmaxlen = 0} (gdb) p *dfield_get_type(dfield) $3 = {mtype = 0, prtype = 0, len = 0, prec = 0, mbminlen = 0, mbmaxlen = 0} (gdb) where #0 0x0830ab2a in row_sel_convert_mysql_key_to_innobase (tuple=0x40ad8468, buf=0x8c7741a '¥' <repeats 62 times>, "h4z\025é\a", buf_len=57, index=0x40ae4468, key_ptr=0x65d0143b "¥p'a\bž Å\b\n", key_len=4, trx=0x40ad3468) at row0sel.c:2082 #1 0x0826da23 in ha_innobase::records_in_range(unsigned, st_key_range*, st_key_range*) (this=0x8c76f70, keynr=0, min_key=0x65d00fec, max_key=0x65d00fdc) at ha_innodb.cc:5015 #2 0x0824b286 in check_quick_keys (param=0x65d011fc, idx=0, key_tree=0x8c775e0, min_key=0x65d01438 "", min_key_flag=0, max_key=0x65d01b36 "", max_key_flag=0) at opt_range.cc:5171 #3 0x0824abee in check_quick_select (param=0x65d011fc, idx=0, tree=0x8c775e0) at opt_range.cc:4987 #4 0x08246329 in get_key_scans_params (param=0x65d011fc, tree=0x8c774a8, index_read_must_be_used=false, read_time=3.2999999999999998) at opt_range.cc:3140 #5 0x082434c5 in SQL_SELECT::test_quick_select(THD*, Bitmap<64>, unsigned long long, unsigned long long, bool) (this=0x8c78cb0, thd=0x8c520b8, keys_to_use= {map = 1}, prev_tables=0, limit=18446744073709551615, force_quick_range=false) at opt_range.cc:1786 #6 0x08253946 in SQL_SELECT::check_quick(THD*, bool, unsigned long long) ( this=0x8c78cb0, thd=0x8c520b8, force_quick_range=false, limit=18446744073709551615) at opt_range.h:694 #7 0x08213881 in mysql_delete(THD*, st_table_list*, Item*, st_sql_list*, unsig---Type <return> to continue, or q <return> to quit--- ned long long, unsigned long) (thd=0x8c520b8, table_list=0x8c789a0, conds=0x8c78bc8, order=0x8c523b8, limit=18446744073709551615, options=0) at sql_delete.cc:102 #8 0x081b38df in mysql_execute_command(THD*) (thd=0x8c520b8) at sql_parse.cc:3225 #9 0x081b8d02 in mysql_parse(THD*, char*, unsigned) (thd=0x8c520b8, inBuf=0x8c78930 "DELETE FROM t2 WHERE F1 = 5", length=27) at sql_parse.cc:5243 #10 0x081afbfc in dispatch_command(enum_server_command, THD*, char*, unsigned) (command=COM_QUERY, thd=0x8c520b8, packet=0x8c708d1 "DELETE FROM t2 WHERE F1 = 5", packet_length=28) at sql_parse.cc:1651 #11 0x081af51a in do_command(THD*) (thd=0x8c520b8) at sql_parse.cc:1457 #12 0x081ae781 in handle_one_connection (arg=0x8c520b8) at sql_parse.cc:1114 #13 0x40062f60 in pthread_start_thread () from /lib/i686/libpthread.so.0 #14 0x400630fe in pthread_start_thread_event () from /lib/i686/libpthread.so.0 #15 0x401f5327 in clone () from /lib/i686/libc.so.6 (gdb)
[9 May 2005 10:22]
Jan Lindström
Based on below gdb output, why key_len = 4 when field length is 2 ? Because of this row_sel_convert_mysql_key_to_innobase tryes to convert more than one key to InnoDB. Breakpoint 1, row_sel_convert_mysql_key_to_innobase (tuple=0x40ad9468, buf=0x8c49d80 '¥' <repeats 64 times>, "h4z\025\221", buf_len=57, index=0x40ad8468, key_ptr=0x637a7438 "", key_len=4, trx=0x40acbc68) at row0sel.c:2039 2039 byte* original_buf = buf; Current language: auto; currently c (gdb) next 2040 byte* original_key_ptr = key_ptr; (gdb) 2048 ulint n_fields = 0; (gdb) 2054 key_end = key_ptr + key_len; (gdb) 2058 dtuple_set_n_fields(tuple, ULINT_MAX); (gdb) 2060 dfield = dtuple_get_nth_field(tuple, 0); (gdb) 2061 field = dict_index_get_nth_field(index, 0); (gdb) 2063 if (dfield_get_type(dfield)->mtype == DATA_SYS) { (gdb) p *dfield $1 = {data = 0x0, len = 0, type = {mtype = 4, prtype = 4130038, len = 2, prec = 0, mbminlen = 1, mbmaxlen = 1}} (gdb) p *field $2 = {col = 0x40ad7870, name = 0x40ad79a0 "F1", order = 0, prefix_len = 0, fixed_len = 0, fixed_offs = 0} (gdb) p *(field->col) $3 = {hash = 0x0, ind = 0, clust_pos = 3, ord_part = 1, name = 0x40ad79a0 "F1", type = {mtype = 4, prtype = 4130038, len = 2, prec = 0, mbminlen = 1, mbmaxlen = 1}, table = 0x40ad6e68, aux = 0} (gdb) next 2079 while (key_ptr < key_end) { (gdb) p key_len $4 = 4 (gdb) p key_ptr $5 = (unsigned char *) 0x637a7438 "" (gdb) p key_end $6 = (unsigned char *) 0x637a743c "" (gdb) next 2082 == dfield_get_type(dfield)->mtype); (gdb) 2084 data_offset = 0; (gdb) 2085 is_null = FALSE; (gdb) 2087 if (!(dfield_get_type(dfield)->prtype & DATA_NOT_NULL)) { (gdb) p dfield_get_type(dfield)->prtype $7 = 4130038 (gdb) next 2091 data_offset = 1; (gdb) 2093 if (*key_ptr != 0) { (gdb) p *key_ptr $8 = 0 '\0' (gdb) next 2100 type = dfield_get_type(dfield)->mtype; (gdb) 2104 if (type == DATA_BLOB) { (gdb) p *type Cannot access memory at address 0x4 (gdb) next 2128 } else if (field->prefix_len > 0) { (gdb) p *dfield $9 = {data = 0x0, len = 0, type = {mtype = 4, prtype = 4130038, len = 2, prec = 0, mbminlen = 1, mbmaxlen = 1}} (gdb) next 2143 data_len = dfield_get_type(dfield)->len; (gdb) 2144 data_field_len = data_offset + data_len; (gdb) p data_len $10 = 2 (gdb) next 2147 if (dtype_get_mysql_type(dfield_get_type(dfield)) (gdb) p data_field_len $11 = 3 (gdb) next 2165 if (!is_null) { (gdb) 2166 row_mysql_store_col_in_innobase_format( (gdb) 2173 buf += data_len; (gdb) 2176 key_ptr += data_field_len; (gdb) 2178 if (key_ptr > key_end) { (gdb) 2208 n_fields++; (gdb) 2209 field++; (gdb) 2210 dfield++; (gdb) 2079 while (key_ptr < key_end) { (gdb) p key_ptr $12 = (unsigned char *) 0x637a743b "¥" (gdb) p key_end $13 = (unsigned char *) 0x637a743c "" (gdb) next 2082 == dfield_get_type(dfield)->mtype); (gdb) list 2081 2076 return; 2077 } 2078 2079 while (key_ptr < key_end) { 2080 2081 ut_a(dict_col_get_type(field->col)->mtype 2082 == dfield_get_type(dfield)->mtype); 2083 2084 data_offset = 0; 2085 is_null = FALSE; (gdb) p *field->col $14 = {hash = 0x0, ind = 1, clust_pos = 0, ord_part = 2, name = 0x40ad79a8 "DB_ROW_ID", type = {mtype = 8, prtype = 256, len = 6, prec = 0, mbminlen = 0, mbmaxlen = 0}, table = 0x40ad6e68, aux = 4294967295} (gdb) p dfield $15 = (dfield_t *) 0x40ad94a4 (gdb) p *dfield $16 = {data = 0x0, len = 0, type = {mtype = 0, prtype = 0, len = 0, prec = 0, mbminlen = 0, mbmaxlen = 0}}
[9 May 2005 12:26]
Jan Lindström
Changing category to MySQL Server because this error is most probable in MYSQL code. DECIMAL(4) can be store to 2 bytes. But ha_innobase::records_in_range() gets as a parameter min_key and max_key length 4: #1 0x0826da23 in ha_innobase::records_in_range(unsigned, st_key_range*, st_key_range*) (this=0x8c50080, keynr=0, min_key=0x637a6fec, max_key=0x637a6fdc) at ha_innodb.cc:5015 5015 row_sel_convert_mysql_key_to_innobase( Current language: auto; currently c++ (gdb) p *min_key $1 = {key = 0x637a7438 "", length = 4, flag = HA_READ_KEY_EXACT} (gdb) p *max_key $2 = {key = 0x637a7b36 "", length = 4, flag = HA_READ_AFTER_KEY} (gdb) p/x *max_key.key@4 $5 = {0x0, 0x80, 0x5, 0xa5} (gdb) p/x *min_key.key@4 $6 = {0x0, 0x80, 0x5, 0xa5} Regards, JanL
[9 May 2005 12:52]
Heikki Tuuri
Changed the synopsis, since the FOREIGN KEY had nothing to do with this. --Heikki
[9 May 2005 16:34]
Matthias Leich
I guess I found an easier test case to replay the problem: SET SESSION STORAGE_ENGINE=INNODB; DROP TABLE IF EXISTS t1; CREATE TABLE t1 (GRADE DECIMAL(4) NOT NULL, PRIMARY KEY (GRADE)); INSERT INTO t1 (GRADE) VALUES (151); SELECT GRADE FROM t1; GRADE 151 SELECT GRADE FROM t1 WHERE GRADE= 151; GRADE <---- Where is the record The combination PRIMARY KEY/InnoDB/DECIMAL is important.
[12 May 2005 14:37]
Jani Tolonen
Thank you for your bug report. This issue has been committed to our source repository of that product and will be incorporated into the next release. If necessary, you can access the source repository and build the latest available version, including the bugfix, yourself. More information about accessing the source trees is available at http://www.mysql.com/doc/en/Installing_source_tree.html
[12 May 2005 14:38]
Jani Tolonen
Thank you for your bug report. This issue has been committed to our source repository of that product and will be incorporated into the next release. If necessary, you can access the source repository and build the latest available version, including the bugfix, yourself. More information about accessing the source trees is available at http://www.mysql.com/doc/en/Installing_source_tree.html
[21 May 2005 15:35]
Heikki Tuuri
Jani, if I understand correctly this is an incompatible change, and must be documented prominently. Regards, Heikki
[24 May 2005 19:41]
Paul DuBois
Noted in 5.0 upgrading instructions and 5.0.6 changelog.