summaryrefslogtreecommitdiff
path: root/storage/innodb_plugin/row/row0sel.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innodb_plugin/row/row0sel.c')
-rw-r--r--storage/innodb_plugin/row/row0sel.c84
1 files changed, 48 insertions, 36 deletions
diff --git a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0sel.c
index aff36b65124..cc7a7a6fe9b 100644
--- a/storage/innodb_plugin/row/row0sel.c
+++ b/storage/innodb_plugin/row/row0sel.c
@@ -3356,6 +3356,7 @@ row_search_for_mysql(
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
+ ibool table_lock_waited = FALSE;
rec_offs_init(offsets_);
@@ -3719,6 +3720,44 @@ 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 {
+wait_table_again:
+ err = lock_table(0, index->table,
+ prebuilt->select_lock_type == LOCK_S
+ ? LOCK_IS : LOCK_IX, thr);
+
+ if (err != DB_SUCCESS) {
+
+ table_lock_waited = TRUE;
+ goto lock_table_wait;
+ }
+ 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 +3833,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 */
@@ -4559,6 +4562,7 @@ lock_wait_or_error:
btr_pcur_store_position(pcur, &mtr);
+lock_table_wait:
mtr_commit(&mtr);
mtr_has_extra_clust_latch = FALSE;
@@ -4576,6 +4580,14 @@ lock_wait_or_error:
thr->lock_state = QUE_THR_LOCK_NOLOCK;
mtr_start(&mtr);
+ /* Table lock waited, go try to obtain table lock
+ again */
+ if (table_lock_waited) {
+ table_lock_waited = FALSE;
+
+ goto wait_table_again;
+ }
+
sel_restore_position_for_mysql(&same_user_rec,
BTR_SEARCH_LEAF, pcur,
moves_up, &mtr);