Commit c0cf5d13 authored by marko's avatar marko

branches/5.1: row_unlock_for_mysql(): Do not unlock records that were

modified by the current transaction.  This bug was introduced or unmasked
in r4400.

rb://97 approved by Heikki Tuuri
parent 97e9f4cb
...@@ -1479,8 +1479,6 @@ row_unlock_for_mysql( ...@@ -1479,8 +1479,6 @@ row_unlock_for_mysql(
btr_pcur_t* pcur = prebuilt->pcur; btr_pcur_t* pcur = prebuilt->pcur;
btr_pcur_t* clust_pcur = prebuilt->clust_pcur; btr_pcur_t* clust_pcur = prebuilt->clust_pcur;
trx_t* trx = prebuilt->trx; trx_t* trx = prebuilt->trx;
rec_t* rec;
mtr_t mtr;
ut_ad(prebuilt && trx); ut_ad(prebuilt && trx);
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
...@@ -1502,6 +1500,11 @@ row_unlock_for_mysql( ...@@ -1502,6 +1500,11 @@ row_unlock_for_mysql(
if (prebuilt->new_rec_locks >= 1) { if (prebuilt->new_rec_locks >= 1) {
rec_t* rec;
dict_index_t* index;
dulint rec_trx_id;
mtr_t mtr;
mtr_start(&mtr); mtr_start(&mtr);
/* Restore the cursor position and find the record */ /* Restore the cursor position and find the record */
...@@ -1511,26 +1514,61 @@ row_unlock_for_mysql( ...@@ -1511,26 +1514,61 @@ row_unlock_for_mysql(
} }
rec = btr_pcur_get_rec(pcur); rec = btr_pcur_get_rec(pcur);
index = btr_pcur_get_btr_cur(pcur)->index;
lock_rec_unlock(trx, rec, prebuilt->select_lock_type); if (prebuilt->new_rec_locks >= 2) {
/* Restore the cursor position and find the record
in the clustered index. */
mtr_commit(&mtr); if (!has_latches_on_recs) {
btr_pcur_restore_position(BTR_SEARCH_LEAF,
clust_pcur, &mtr);
} }
if (prebuilt->new_rec_locks >= 2) { rec = btr_pcur_get_rec(clust_pcur);
mtr_start(&mtr); index = btr_pcur_get_btr_cur(clust_pcur)->index;
}
/* Restore the cursor position and find the record */ /* If the record has been modified by this
transaction, do not unlock it. */
ut_a(index->type & DICT_CLUSTERED);
if (!has_latches_on_recs) { if (index->trx_id_offset) {
btr_pcur_restore_position(BTR_SEARCH_LEAF, clust_pcur, rec_trx_id = trx_read_trx_id(rec
&mtr); + index->trx_id_offset);
} else {
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
rec_trx_id = row_get_rec_trx_id(rec, index, offsets);
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, rec, prebuilt->select_lock_type); lock_rec_unlock(trx, 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, rec,
prebuilt->select_lock_type);
}
}
mtr_commit(&mtr); mtr_commit(&mtr);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment