row0sel.c:

  Fix bug #12947 : a consistent read could return inconsistent results; this bug was introduced in 5.0.5
parent 0e323e56
...@@ -3055,6 +3055,7 @@ row_search_for_mysql( ...@@ -3055,6 +3055,7 @@ row_search_for_mysql(
cursor 'direction' should be 0. */ cursor 'direction' should be 0. */
{ {
dict_index_t* index = prebuilt->index; dict_index_t* index = prebuilt->index;
ibool comp = index->table->comp;
dtuple_t* search_tuple = prebuilt->search_tuple; dtuple_t* search_tuple = prebuilt->search_tuple;
btr_pcur_t* pcur = prebuilt->pcur; btr_pcur_t* pcur = prebuilt->pcur;
trx_t* trx = prebuilt->trx; trx_t* trx = prebuilt->trx;
...@@ -3491,7 +3492,7 @@ rec_loop: ...@@ -3491,7 +3492,7 @@ rec_loop:
/* PHASE 4: Look for matching records in a loop */ /* PHASE 4: Look for matching records in a loop */
rec = btr_pcur_get_rec(pcur); rec = btr_pcur_get_rec(pcur);
ut_ad(!!page_rec_is_comp(rec) == index->table->comp); ut_ad(!!page_rec_is_comp(rec) == comp);
#ifdef UNIV_SEARCH_DEBUG #ifdef UNIV_SEARCH_DEBUG
/* /*
fputs("Using ", stderr); fputs("Using ", stderr);
...@@ -3544,7 +3545,7 @@ rec_loop: ...@@ -3544,7 +3545,7 @@ rec_loop:
/* Do sanity checks in case our cursor has bumped into page /* Do sanity checks in case our cursor has bumped into page
corruption */ corruption */
if (page_rec_is_comp(rec)) { if (comp) {
next_offs = rec_get_next_offs(rec, TRUE); next_offs = rec_get_next_offs(rec, TRUE);
if (UNIV_UNLIKELY(next_offs < PAGE_NEW_SUPREMUM)) { if (UNIV_UNLIKELY(next_offs < PAGE_NEW_SUPREMUM)) {
goto wrong_offs; goto wrong_offs;
...@@ -3711,7 +3712,7 @@ rec_loop: ...@@ -3711,7 +3712,7 @@ rec_loop:
if (!set_also_gap_locks if (!set_also_gap_locks
|| srv_locks_unsafe_for_binlog || srv_locks_unsafe_for_binlog
|| (unique_search && !UNIV_UNLIKELY(rec_get_deleted_flag( || (unique_search && !UNIV_UNLIKELY(rec_get_deleted_flag(
rec, page_rec_is_comp(rec))))) { rec, comp)))) {
goto no_gap_lock; goto no_gap_lock;
} else { } else {
...@@ -3803,7 +3804,12 @@ no_gap_lock: ...@@ -3803,7 +3804,12 @@ no_gap_lock:
} }
} }
if (UNIV_UNLIKELY(rec_get_deleted_flag(rec, page_rec_is_comp(rec)))) { /* NOTE that at this point rec can be an old version of a clustered
index record built for a consistent read. We cannot assume after this
point that rec is on a buffer pool page. Functions like
page_rec_is_comp() cannot be used then! */
if (UNIV_UNLIKELY(rec_get_deleted_flag(rec, comp))) {
/* The record is delete-marked: we can skip it if this is /* The record is delete-marked: we can skip it if this is
not a consistent read which might see an earlier version not a consistent read which might see an earlier version
...@@ -3836,6 +3842,7 @@ requires_clust_rec: ...@@ -3836,6 +3842,7 @@ requires_clust_rec:
the clustered index ("clust_index"). However, after this the clustered index ("clust_index"). However, after this
"if" block, "rec" may be pointing to "if" block, "rec" may be pointing to
"clust_rec" of "clust_index". */ "clust_rec" of "clust_index". */
ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(rec_offs_validate(rec, index, offsets));
/* It was a non-clustered index and we must fetch also the /* It was a non-clustered index and we must fetch also the
...@@ -3858,8 +3865,7 @@ requires_clust_rec: ...@@ -3858,8 +3865,7 @@ requires_clust_rec:
goto next_rec; goto next_rec;
} }
if (UNIV_UNLIKELY(rec_get_deleted_flag(clust_rec, if (UNIV_UNLIKELY(rec_get_deleted_flag(clust_rec, comp))) {
page_rec_is_comp(clust_rec)))) {
/* The record is delete marked: we can skip it */ /* The record is delete marked: we can skip it */
......
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