Bug #25135 error in innodb index (DATA TUPLE)
Submitted: 18 Dec 2006 10:32 Modified: 4 Jan 2007 16:23
Reporter: [ name withheld ] Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S1 (Critical)
Version:5.0.27 OS:Linux (Linux x86_64)
Assigned to: Heikki Tuuri CPU Architecture:Any

[18 Dec 2006 10:32] [ name withheld ]
Description:
I have problem with index on innoDB table (.ibd file size is 2.1 GB) with this log error:

InnoDB: error in sec index entry update in
InnoDB: index `text` of table `aadb/content`
InnoDB: tuple DATA TUPLE: 2 fields;
 0: len 12; hex 202020202020202020202020; asc             ;; 1: len 6; hex 00002e80a657; asc   .  W;;

InnoDB: record PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 0; hex ; asc ;; 1: len 6; hex 00002e80a655; asc   .  U;;

TRANSACTION 0 2663290153, ACTIVE 0 sec, process no 11466, OS thread id 1160853856 updating or deleting, thread declared inside InnoDB 481
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1216, undo log entries 7
MySQL thread id 22710, query id 12084402 192.168.0.200 aadbuser updating
DELETE FROM content WHERE item_id='�i/\"ў
                                         ▒' AND field_id IN ('headline........','unspecified....5','con_email......1','unspecified....6','abstract.......1','full_text......1','img_upload.....1','img_upload.....2','unspecified....7','start_date.....1','place..........1','category.......1','

I try remove index text and create new but it's not help with the error.

Table structure:
CREATE TABLE content (
  item_id varbinary(16) default '                ',
  field_id varbinary(16) default '                ',
  number bigint(20) default NULL,
  `text` mediumtext,
  flag smallint(6) default NULL,
  KEY item_id (item_id,field_id,`text`(16)),
  KEY `text` (`text`(12))
) ENGINE=InnoDB DEFAULT CHARSET=cp1250;

How to repeat:
I'm sorry I don't know how to repeat without data from my table.
[18 Dec 2006 10:33] [ name withheld ]
log file with error

Attachment: mysqd.log (multipart/alternative, text), 1.00 KiB.

[18 Dec 2006 15:15] Heikki Tuuri
row0upd.c in InnoDB-5.0-svn:

Updates a secondary index entry of a row. */
static
ulint
row_upd_sec_index_entry(
/*====================*/
                                /* out: DB_SUCCESS if operation successfully
                                completed, else error code or DB_LOCK_WAIT */
        upd_node_t*     node,   /* in: row update node */
        que_thr_t*      thr)    /* in: query thread */
{
        ibool           check_ref;
        ibool           found;
        dict_index_t*   index;
        dtuple_t*       entry;
        btr_pcur_t      pcur;
        btr_cur_t*      btr_cur;
        mem_heap_t*     heap;
        rec_t*          rec;
        ulint           err     = DB_SUCCESS;
        mtr_t           mtr;
        trx_t*          trx     = thr_get_trx(thr);

        index = node->index;

        check_ref = row_upd_index_is_referenced(index, trx);

        heap = mem_heap_create(1024);

        /* Build old index entry */
        entry = row_build_index_entry(node->row, index, heap);

        log_free_check();
        mtr_start(&mtr);

        found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur,
                                                                        &mtr);
        btr_cur = btr_pcur_get_btr_cur(&pcur);

        rec = btr_cur_get_rec(btr_cur);

        if (UNIV_UNLIKELY(!found)) {
                fputs("InnoDB: error in sec index entry update in\n"
                        "InnoDB: ", stderr);
                dict_index_name_print(stderr, trx, index);
                fputs("\n"
                        "InnoDB: tuple ", stderr);
                dtuple_print(stderr, entry);
                fputs("\n"
                        "InnoDB: record ", stderr);
                rec_print(stderr, rec, index);
                putc('\n', stderr);

                trx_print(stderr, trx, 0);

                fputs("\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr);

The DELETE command looks for a secondary index entry where the first column is 12 spaces, but ends up on a secondary index record where the first column is the empty string! Since the empty string is in a comparison padded with spaces, these are alphabetically equivalent. But then the next column (ROW_ID) should guide the search to the right record.

I tried to repeat this with the same table definition:

mysql> insert into content(item_id,`text`) values ('223', '');
Query OK, 1 row affected (0.02 sec)

mysql> insert into content(item_id,`text`) values ('333', '            ');
Query OK, 1 row affected (0.02 sec)

mysql> delete from content where item_id = '333';
Query OK, 1 row affected (0.05 sec)

but I was not able to repeat.

Can you repeat the bug if you just restrict the table to the rows that are listed in the DELETE statement?

Regards,

Heikki
[2 Jan 2007 12:10] [ name withheld ]
I'm sorry I can't repeate the bug.
After some index reconstruction (drop/create) and database dumb/restore, I haven't the error messages in my mysql log file.

Thank you for your help.
[19 Nov 2008 14:25] James Day
If it was an upgrade from 4.0 it may have been caused by not doing the required table rebuild. Otherwise, bug #28138 was introduced in 5.0.26 and fixed in 5.0.48 so is a possible cause because of the use of prefix keys.