diff options
Diffstat (limited to 'innobase/row')
-rw-r--r-- | innobase/row/row0ins.c | 9 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 26 | ||||
-rw-r--r-- | innobase/row/row0sel.c | 12 |
3 files changed, 28 insertions, 19 deletions
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index 32aa0385596..be1a48a4b46 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -549,6 +549,15 @@ row_ins_cascade_calc_update_vec( default: ut_error; case 1: + if (UNIV_UNLIKELY( + dtype_get_charset_coll( + dtype_get_prtype(type)) + == DATA_MYSQL_BINARY_CHARSET_COLL)) { + /* Do not pad BINARY + columns. */ + return(ULINT_UNDEFINED); + } + /* space=0x20 */ memset(pad_start, 0x20, pad_end - pad_start); diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 723e305b2ab..937056c300e 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1436,8 +1436,9 @@ trx_register_new_rec_lock() to store the information which new record locks really were set. This function removes a newly set lock under prebuilt->pcur, and also under prebuilt->clust_pcur. Currently, this is only used and tested in the case of an UPDATE or a DELETE statement, where the row lock is of the -LOCK_X type. -Thus, this implements a 'mini-rollback' that releases the latest record +LOCK_X or LOCK_S type. + +Thus, this implements a 'mini-rollback' that releases the latest record locks we set. */ int @@ -1474,7 +1475,14 @@ row_unlock_for_mysql( index = btr_pcur_get_btr_cur(pcur)->index; - if (index != NULL && trx_new_rec_locks_contain(trx, index)) { + if (UNIV_UNLIKELY(index == NULL)) { + fprintf(stderr, +"InnoDB: Error: Index is not set for persistent cursor.\n"); + ut_print_buf(stderr, (const byte*)pcur, sizeof(btr_pcur_t)); + ut_error; + } + + if (trx_new_rec_locks_contain(trx, index)) { mtr_start(&mtr); @@ -1486,11 +1494,7 @@ row_unlock_for_mysql( rec = btr_pcur_get_rec(pcur); - mutex_enter(&kernel_mutex); - - lock_rec_reset_and_release_wait(rec); - - mutex_exit(&kernel_mutex); + lock_rec_unlock(trx, rec, prebuilt->select_lock_type); mtr_commit(&mtr); @@ -1520,11 +1524,7 @@ row_unlock_for_mysql( rec = btr_pcur_get_rec(clust_pcur); - mutex_enter(&kernel_mutex); - - lock_rec_reset_and_release_wait(rec); - - mutex_exit(&kernel_mutex); + lock_rec_unlock(trx, rec, prebuilt->select_lock_type); mtr_commit(&mtr); } diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 1b66f14f5d7..d25023dc6be 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2771,8 +2771,8 @@ row_sel_get_clust_rec_for_mysql( func_exit: *out_rec = clust_rec; - if (prebuilt->select_lock_type == LOCK_X) { - /* We may use the cursor in update: store its position */ + if (prebuilt->select_lock_type != LOCK_NONE) { + /* We may use the cursor in unlock: store its position */ btr_pcur_store_position(prebuilt->clust_pcur, mtr); } @@ -3972,12 +3972,12 @@ got_row: /* We have an optimization to save CPU time: if this is a consistent read on a unique condition on the clustered index, then we do not store the pcur position, because any fetch next or prev will anyway - return 'end of file'. An exception is the MySQL HANDLER command - where the user can move the cursor with PREV or NEXT even after - a unique search. */ + return 'end of file'. Exceptions are locking reads and the MySQL + HANDLER command where the user can move the cursor with PREV or NEXT + even after a unique search. */ if (!unique_search_from_clust_index - || prebuilt->select_lock_type == LOCK_X + || prebuilt->select_lock_type != LOCK_NONE || prebuilt->used_in_HANDLER) { /* Inside an update always store the cursor position */ |