mariadb/storage/innobase/row
Vasil Dimov 86505c3c54 Fix Bug#13510739 63775: SERVER CRASH ON HANDLER READ NEXT AFTER DELETE RECORD.
CREATE TABLE bug13510739 (c INTEGER NOT NULL, PRIMARY KEY (c)) ENGINE=INNODB;
INSERT INTO bug13510739 VALUES (1), (2), (3), (4);
DELETE FROM bug13510739 WHERE c=2;
HANDLER bug13510739 OPEN;
HANDLER bug13510739 READ `primary` = (2);
HANDLER bug13510739 READ `primary` NEXT;  <-- crash

The bug is that in the particular testcase row_search_for_mysql() picked up
a delete-marked record and quit, leaving the cursor non-positioned state and
on the subsequent 'get next' call the code crashed because of the
non-positioned cursor.

In row0sel.cc (line numbers from mysql-trunk):

4653         if (rec_get_deleted_flag(rec, comp)) {
...
4679                 if (index == clust_index && unique_search) {
4680 
4681                         err = DB_RECORD_NOT_FOUND;
4682                         
4683                         goto normal_return;
4684                 }       

it quit from here, not storing the cursor position.

In contrast, if the record=2 is not found at all (e.g. sleep(1) after DELETE
to let the purge wipe it away completely) then 'get = 2' does find record=3
and quits from here:

4366                 if (0 != cmp_dtuple_rec(search_tuple, rec, offsets)) {
...
4394                         btr_pcur_store_position(pcur, &mtr);
4395 
4396                         err = DB_RECORD_NOT_FOUND;
4397 #if 0
4398                         ut_print_name(stderr, trx, FALSE, index->name);
4399                         fputs(" record not found 3\n", stderr);
4400 #endif
4401 
4402                         goto normal_return;

Another fix could be to extend the condition on line 4366 to hold only if
seach_tuple matches rec AND if rec is not delete marked.

Notice that in the above test case if we wait about 1 second somewhere after
DELETE and before 'get = 2', then the testcase does not crash and returns 4
instead. Not sure if this is the correct behavior, but this bugfix removes
the crash and makes the code return what it also returns in the non-crashing
case (if rec=2 is not found during 'get = 2', e.g. we have sleep(1) there).

Approved by:	Marko (http://bur03.no.oracle.com/rb/r/863/)
2011-12-22 12:55:44 +02:00
..
row0ins.c Merge from mysql-5.1.60-release 2011-11-17 00:26:16 +01:00
row0mysql.c (Builtin InnoDB) Fix Bug#59303 Correct URL in crash message 2011-01-06 09:05:45 +02:00
row0purge.c Bug#12963823 CRASH IN PURGE THREAD UNDER UNUSUAL CIRCUMSTANCES 2011-09-22 13:35:02 +03:00
row0row.c Revert most of revno 3560.9.1 (Bug#12704861) 2011-10-26 11:44:28 +03:00
row0sel.c Fix Bug#13510739 63775: SERVER CRASH ON HANDLER READ NEXT AFTER DELETE RECORD. 2011-12-22 12:55:44 +02:00
row0uins.c Applied innodb-5.1 snapshots ss799 and ss854 2006-09-21 01:39:09 -06:00
row0umod.c Revert revno:3452.71.32 (Bug#12612184 fix). 2011-10-26 12:23:57 +03:00
row0undo.c Fix bug#54583. This change reverses rsvn:1350 by getting rid of a bogus assertion 2010-06-25 18:18:41 +10:00
row0upd.c Revert revno:3452.71.32 (Bug#12612184 fix). 2011-10-26 12:23:57 +03:00
row0vers.c Re-enable the debug assertions for Bug#12650861. 2011-06-16 11:51:04 +03:00