diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2009-09-08 20:04:58 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2009-09-08 20:04:58 +0400 |
commit | 241c1977dd1d0614c4d6400fa981e7f7facbd153 (patch) | |
tree | 86e5f9ce0d8918d98f3fde0a8bf6939815c7af65 /storage/xtradb/row/row0mysql.c | |
parent | 29f0dcb56337a3e352ad7a70dcff6b25bb605325 (diff) | |
parent | 56bca79f6a2ca554fb59a208e2b160dcb905113d (diff) | |
download | mariadb-git-241c1977dd1d0614c4d6400fa981e7f7facbd153.tar.gz |
Merge xtradb-7 -> MariaDB
Diffstat (limited to 'storage/xtradb/row/row0mysql.c')
-rw-r--r-- | storage/xtradb/row/row0mysql.c | 80 |
1 files changed, 53 insertions, 27 deletions
diff --git a/storage/xtradb/row/row0mysql.c b/storage/xtradb/row/row0mysql.c index 7acc330113b..3a9e1de0125 100644 --- a/storage/xtradb/row/row0mysql.c +++ b/storage/xtradb/row/row0mysql.c @@ -1452,12 +1452,9 @@ row_unlock_for_mysql( and clust_pcur, and we do not need to reposition the cursors. */ { - dict_index_t* index; btr_pcur_t* pcur = prebuilt->pcur; btr_pcur_t* clust_pcur = prebuilt->clust_pcur; trx_t* trx = prebuilt->trx; - rec_t* rec; - mtr_t mtr; ut_ad(prebuilt && trx); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); @@ -1477,9 +1474,12 @@ row_unlock_for_mysql( trx->op_info = "unlock_row"; - index = btr_pcur_get_btr_cur(pcur)->index; + if (prebuilt->new_rec_locks >= 1) { - if (index != NULL && trx_new_rec_locks_contain(trx, index)) { + rec_t* rec; + dict_index_t* index; + dulint rec_trx_id; + mtr_t mtr; mtr_start(&mtr); @@ -1490,45 +1490,71 @@ row_unlock_for_mysql( } rec = btr_pcur_get_rec(pcur); + index = btr_pcur_get_btr_cur(pcur)->index; - lock_rec_unlock(trx, btr_pcur_get_block(pcur), - rec, prebuilt->select_lock_type); - - mtr_commit(&mtr); + if (prebuilt->new_rec_locks >= 2) { + /* Restore the cursor position and find the record + in the clustered index. */ - /* If the search was done through the clustered index, then - we have not used clust_pcur at all, and we must NOT try to - reset locks on clust_pcur. The values in clust_pcur may be - garbage! */ + if (!has_latches_on_recs) { + btr_pcur_restore_position(BTR_SEARCH_LEAF, + clust_pcur, &mtr); + } - if (dict_index_is_clust(index)) { + rec = btr_pcur_get_rec(clust_pcur); + index = btr_pcur_get_btr_cur(clust_pcur)->index; + } - goto func_exit; + if (UNIV_UNLIKELY(!(dict_index_is_clust(index)))) { + /* This is not a clustered index record. We + do not know how to unlock the record. */ + goto no_unlock; } - } - index = btr_pcur_get_btr_cur(clust_pcur)->index; + /* If the record has been modified by this + transaction, do not unlock it. */ - if (index != NULL && trx_new_rec_locks_contain(trx, index)) { + if (index->trx_id_offset) { + rec_trx_id = trx_read_trx_id(rec + + index->trx_id_offset); + } else { + mem_heap_t* heap = NULL; + ulint offsets_[REC_OFFS_NORMAL_SIZE]; + ulint* offsets = offsets_; - mtr_start(&mtr); + *offsets_ = (sizeof offsets_) / sizeof *offsets_; + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); - /* Restore the cursor position and find the record */ + rec_trx_id = row_get_rec_trx_id(rec, index, offsets); - if (!has_latches_on_recs) { - btr_pcur_restore_position(BTR_SEARCH_LEAF, clust_pcur, - &mtr); + if (UNIV_LIKELY_NULL(heap)) { + mem_heap_free(heap); + } } - rec = btr_pcur_get_rec(clust_pcur); + if (ut_dulint_cmp(rec_trx_id, trx->id) != 0) { + /* We did not update the record: unlock it */ + + rec = btr_pcur_get_rec(pcur); + index = btr_pcur_get_btr_cur(pcur)->index; - lock_rec_unlock(trx, btr_pcur_get_block(clust_pcur), - rec, prebuilt->select_lock_type); + lock_rec_unlock(trx, btr_pcur_get_block(pcur), + rec, prebuilt->select_lock_type); + if (prebuilt->new_rec_locks >= 2) { + rec = btr_pcur_get_rec(clust_pcur); + index = btr_pcur_get_btr_cur(clust_pcur)->index; + + lock_rec_unlock(trx, btr_pcur_get_block(clust_pcur), + rec, prebuilt->select_lock_type); + } + } + +no_unlock: mtr_commit(&mtr); } -func_exit: trx->op_info = ""; return(DB_SUCCESS); |