mirror of
https://github.com/MariaDB/server.git
synced 2026-04-29 03:35:34 +02:00
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/)
This commit is contained in:
parent
b3c3b9f0b1
commit
43ea968d45
7 changed files with 71 additions and 2 deletions
10
mysql-test/suite/innodb/r/innodb_bug13510739.result
Normal file
10
mysql-test/suite/innodb/r/innodb_bug13510739.result
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
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);
|
||||
c
|
||||
HANDLER bug13510739 READ `primary` NEXT;
|
||||
c
|
||||
4
|
||||
DROP TABLE bug13510739;
|
||||
20
mysql-test/suite/innodb/t/innodb_bug13510739.test
Normal file
20
mysql-test/suite/innodb/t/innodb_bug13510739.test
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#
|
||||
# Bug#13510739 63775: SERVER CRASH ON HANDLER READ NEXT AFTER DELETE RECORD.
|
||||
#
|
||||
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
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);
|
||||
|
||||
# this one crashes the server if the bug is present
|
||||
HANDLER bug13510739 READ `primary` NEXT;
|
||||
|
||||
DROP TABLE bug13510739;
|
||||
10
mysql-test/suite/innodb_plugin/r/innodb_bug13510739.result
Normal file
10
mysql-test/suite/innodb_plugin/r/innodb_bug13510739.result
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
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);
|
||||
c
|
||||
HANDLER bug13510739 READ `primary` NEXT;
|
||||
c
|
||||
4
|
||||
DROP TABLE bug13510739;
|
||||
20
mysql-test/suite/innodb_plugin/t/innodb_bug13510739.test
Normal file
20
mysql-test/suite/innodb_plugin/t/innodb_bug13510739.test
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#
|
||||
# Bug#13510739 63775: SERVER CRASH ON HANDLER READ NEXT AFTER DELETE RECORD.
|
||||
#
|
||||
|
||||
-- source include/have_innodb_plugin.inc
|
||||
|
||||
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);
|
||||
|
||||
# this one crashes the server if the bug is present
|
||||
HANDLER bug13510739 READ `primary` NEXT;
|
||||
|
||||
DROP TABLE bug13510739;
|
||||
|
|
@ -4208,7 +4208,9 @@ no_gap_lock:
|
|||
applicable to unique secondary indexes. Current behaviour is
|
||||
to widen the scope of a lock on an already delete marked record
|
||||
if the same record is deleted twice by the same transaction */
|
||||
if (index == clust_index && unique_search) {
|
||||
if (index == clust_index && unique_search
|
||||
&& !prebuilt->used_in_HANDLER) {
|
||||
|
||||
err = DB_RECORD_NOT_FOUND;
|
||||
|
||||
goto normal_return;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
2011-12-22 The InnoDB Team
|
||||
|
||||
* row/row0sel.c:
|
||||
Fix Bug#63775 Server crash on handler read next after delete record.
|
||||
|
||||
2011-12-13 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, innodb.test, innodb.result:
|
||||
|
|
|
|||
|
|
@ -4362,7 +4362,9 @@ no_gap_lock:
|
|||
applicable to unique secondary indexes. Current behaviour is
|
||||
to widen the scope of a lock on an already delete marked record
|
||||
if the same record is deleted twice by the same transaction */
|
||||
if (index == clust_index && unique_search) {
|
||||
if (index == clust_index && unique_search
|
||||
&& !prebuilt->used_in_HANDLER) {
|
||||
|
||||
err = DB_RECORD_NOT_FOUND;
|
||||
|
||||
goto normal_return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue