1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Bug#56716 InnoDB locks a record gap without locking the table

row_search_for_mysql(): Acquire an intention lock on the table
before locking the first record gap.
This commit is contained in:
Marko Mäkelä
2010-10-04 13:06:41 +03:00
parent 678bc90ed8
commit 190ebda206
4 changed files with 55 additions and 36 deletions

View File

@ -0,0 +1,4 @@
CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB;
SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE;
a b c
DROP TABLE bug56716;

View File

@ -0,0 +1,10 @@
#
# Bug #56716 InnoDB locks a record gap without locking the table
#
-- source include/have_innodb_plugin.inc
CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB;
SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE;
DROP TABLE bug56716;

View File

@ -1,3 +1,8 @@
2010-09-27 The InnoDB Team
* row/row0sel.c, innodb_bug56716.result, innodb_bug56716.test:
Fix Bug #56716 InnoDB locks a record gap without locking the table
2010-09-06 The InnoDB Team
* dict/dict0load.c, innodb_bug53756.test innodb_bug53756.result
Fix Bug #53756 ALTER TABLE ADD PRIMARY KEY affects crash recovery

View File

@ -3719,6 +3719,42 @@ release_search_latch_if_needed:
clust_index = dict_table_get_first_index(index->table);
/* Do some start-of-statement preparations */
if (!prebuilt->sql_stat_start) {
/* No need to set an intention lock or assign a read view */
if (trx->read_view == NULL
&& prebuilt->select_lock_type == LOCK_NONE) {
fputs("InnoDB: Error: MySQL is trying to"
" perform a consistent read\n"
"InnoDB: but the read view is not assigned!\n",
stderr);
trx_print(stderr, trx, 600);
fputc('\n', stderr);
ut_error;
}
} else if (prebuilt->select_lock_type == LOCK_NONE) {
/* This is a consistent read */
/* Assign a read view for the query */
trx_assign_read_view(trx);
prebuilt->sql_stat_start = FALSE;
} else {
err = lock_table(0, index->table,
prebuilt->select_lock_type == LOCK_S
? LOCK_IS : LOCK_IX, thr);
if (err != DB_SUCCESS) {
goto lock_wait_or_error;
}
prebuilt->sql_stat_start = FALSE;
}
/* Open or restore index cursor position */
if (UNIV_LIKELY(direction != 0)) {
ibool need_to_process = sel_restore_position_for_mysql(
&same_user_rec, BTR_SEARCH_LEAF,
@ -3794,42 +3830,6 @@ release_search_latch_if_needed:
}
}
if (!prebuilt->sql_stat_start) {
/* No need to set an intention lock or assign a read view */
if (trx->read_view == NULL
&& prebuilt->select_lock_type == LOCK_NONE) {
fputs("InnoDB: Error: MySQL is trying to"
" perform a consistent read\n"
"InnoDB: but the read view is not assigned!\n",
stderr);
trx_print(stderr, trx, 600);
fputc('\n', stderr);
ut_a(0);
}
} else if (prebuilt->select_lock_type == LOCK_NONE) {
/* This is a consistent read */
/* Assign a read view for the query */
trx_assign_read_view(trx);
prebuilt->sql_stat_start = FALSE;
} else {
ulint lock_mode;
if (prebuilt->select_lock_type == LOCK_S) {
lock_mode = LOCK_IS;
} else {
lock_mode = LOCK_IX;
}
err = lock_table(0, index->table, lock_mode, thr);
if (err != DB_SUCCESS) {
goto lock_wait_or_error;
}
prebuilt->sql_stat_start = FALSE;
}
rec_loop:
/*-------------------------------------------------------------*/
/* PHASE 4: Look for matching records in a loop */