Below is the list of changes that have just been committed into a local
5.0 repository of marko. When marko does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.1909 05/07/19 11:50:28 marko@stripped +1 -0
InnoDB: Optimize lock0lock.c (avoid computing heap_no).
innobase/lock/lock0lock.c
1.64 05/07/19 11:50:18 marko@stripped +198 -136
Avoid recomputing heap_no. This seems to improve
test-wisconsin performance by 3.7 %.
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: marko
# Host: hundin.mysql.fi
# Root: /home/marko/mysql-5.0-current
--- 1.63/innobase/lock/lock0lock.c 2005-07-01 20:42:11 +03:00
+++ 1.64/innobase/lock/lock0lock.c 2005-07-19 11:50:18 +03:00
@@ -1282,7 +1282,7 @@
lock_rec_get_next(
/*==============*/
/* out: next lock, NULL if none exists */
- rec_t* rec, /* in: record on a page */
+ ulint heap_no,/* in: heap number of the record */
lock_t* lock) /* in: lock */
{
#ifdef UNIV_SYNC_DEBUG
@@ -1290,17 +1290,10 @@
#endif /* UNIV_SYNC_DEBUG */
ut_ad(lock_get_type(lock) == LOCK_REC);
- if (page_rec_is_comp(rec)) {
- do {
- lock = lock_rec_get_next_on_page(lock);
- } while (lock && !lock_rec_get_nth_bit(lock,
- rec_get_heap_no(rec, TRUE)));
- } else {
- do {
- lock = lock_rec_get_next_on_page(lock);
- } while (lock && !lock_rec_get_nth_bit(lock,
- rec_get_heap_no(rec, FALSE)));
- }
+ do {
+ ut_ad(lock_get_type(lock) == LOCK_REC);
+ lock = lock_rec_get_next_on_page(lock);
+ } while (lock && !lock_rec_get_nth_bit(lock, heap_no));
return(lock);
}
@@ -1312,7 +1305,8 @@
lock_rec_get_first(
/*===============*/
/* out: first lock, NULL if none exists */
- rec_t* rec) /* in: record on a page */
+ rec_t* rec, /* in: record on a page */
+ ulint heap_no)/* in: heap number of the record */
{
lock_t* lock;
@@ -1322,8 +1316,6 @@
lock = lock_rec_get_first_on_page(rec);
if (UNIV_LIKELY_NULL(lock)) {
- ulint heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
-
while (lock && !lock_rec_get_nth_bit(lock, heap_no)) {
lock = lock_rec_get_next_on_page(lock);
}
@@ -1488,6 +1480,7 @@
for a supremum record we regard this always a gap
type request */
rec_t* rec, /* in: record */
+ ulint heap_no,/* in: heap number of the record */
trx_t* trx) /* in: transaction */
{
lock_t* lock;
@@ -1499,7 +1492,7 @@
|| (precise_mode & LOCK_MODE_MASK) == LOCK_X);
ut_ad(!(precise_mode & LOCK_INSERT_INTENTION));
- lock = lock_rec_get_first(rec);
+ lock = lock_rec_get_first(rec, heap_no);
while (lock) {
if (lock->trx == trx
@@ -1517,7 +1510,7 @@
return(lock);
}
- lock = lock_rec_get_next(rec, lock);
+ lock = lock_rec_get_next(heap_no, lock);
}
return(NULL);
@@ -1536,6 +1529,7 @@
ulint wait, /* in: LOCK_WAIT if also waiting locks are
taken into account, or 0 if not */
rec_t* rec, /* in: record to look at */
+ ulint heap_no,/* in: heap number of hte record */
trx_t* trx) /* in: transaction, or NULL if requests by all
transactions are taken into account */
{
@@ -1548,7 +1542,7 @@
ut_ad(gap == 0 || gap == LOCK_GAP);
ut_ad(wait == 0 || wait == LOCK_WAIT);
- lock = lock_rec_get_first(rec);
+ lock = lock_rec_get_first(rec, heap_no);
while (lock) {
if (lock->trx != trx
@@ -1560,7 +1554,7 @@
return(lock);
}
- lock = lock_rec_get_next(rec, lock);
+ lock = lock_rec_get_next(heap_no, lock);
}
return(NULL);
@@ -1578,6 +1572,7 @@
possibly ORed to LOCK_GAP or LOC_REC_NOT_GAP,
LOCK_INSERT_INTENTION */
rec_t* rec, /* in: record to look at */
+ ulint heap_no,/* in: heap number of the record */
trx_t* trx) /* in: our transaction */
{
lock_t* lock;
@@ -1585,16 +1580,30 @@
ut_ad(mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */
- lock = lock_rec_get_first(rec);
+ lock = lock_rec_get_first(rec, heap_no);
- while (lock) {
- if (lock_rec_has_to_wait(trx, mode, lock,
- page_rec_is_supremum(rec))) {
+ if (UNIV_LIKELY_NULL(lock)) {
+ if (page_rec_is_supremum(rec)) {
- return(lock);
+ do {
+ if (lock_rec_has_to_wait(trx, mode, lock,
+ TRUE)) {
+ return(lock);
+ }
+
+ lock = lock_rec_get_next(heap_no, lock);
+ } while (lock);
+ } else {
+
+ do {
+ if (lock_rec_has_to_wait(trx, mode, lock,
+ FALSE)) {
+ return(lock);
+ }
+
+ lock = lock_rec_get_next(heap_no, lock);
+ } while (lock);
}
-
- lock = lock_rec_get_next(rec, lock);
}
return(NULL);
@@ -1610,19 +1619,14 @@
/*==========================*/
/* out: lock or NULL */
ulint type_mode, /* in: lock type_mode field */
- rec_t* rec, /* in: record */
+ ulint heap_no, /* in: heap number of the record */
+ lock_t* lock, /* in: lock_rec_get_first_on_page() */
trx_t* trx) /* in: transaction */
{
- lock_t* lock;
- ulint heap_no;
-
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */
- heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
- lock = lock_rec_get_first_on_page(rec);
-
while (lock != NULL) {
if (lock->trx == trx
&& lock->type_mode == type_mode
@@ -1702,13 +1706,13 @@
ulint type_mode,/* in: lock mode and wait flag, type is
ignored and replaced by LOCK_REC */
rec_t* rec, /* in: record on page */
+ ulint heap_no,/* in: heap number of the record */
dict_index_t* index, /* in: index of record */
trx_t* trx) /* in: transaction */
{
page_t* page;
lock_t* lock;
ulint page_no;
- ulint heap_no;
ulint space;
ulint n_bits;
ulint n_bytes;
@@ -1720,9 +1724,8 @@
page = buf_frame_align(rec);
space = buf_frame_get_space_id(page);
page_no = buf_frame_get_page_no(page);
- heap_no = rec_get_heap_no(rec, page_is_comp(page));
- ut_ad(!!page_is_comp(page) == index->table->comp);
+ ut_ad((ibool) !!page_is_comp(page) == index->table->comp);
/* If rec is the supremum record, then we reset the gap and
LOCK_REC_NOT_GAP bits, as all locks on the supremum are
@@ -1799,6 +1802,7 @@
{
lock_t* lock;
trx_t* trx;
+ ulint heap_no;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
@@ -1808,7 +1812,7 @@
we do not enqueue a lock request if the query thread should be
stopped anyway */
- if (que_thr_stop(thr)) {
+ if (UNIV_UNLIKELY(que_thr_stop(thr))) {
ut_error;
@@ -1817,7 +1821,7 @@
trx = thr_get_trx(thr);
- if (trx->dict_operation) {
+ if (UNIV_UNLIKELY(trx->dict_operation)) {
ut_print_timestamp(stderr);
fputs(
" InnoDB: Error: a record lock wait happens in a dictionary operation!\n"
@@ -1827,18 +1831,20 @@
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n",
stderr);
}
-
+
+ heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
+
/* Enqueue the lock request that will wait to be granted */
- lock = lock_rec_create(type_mode | LOCK_WAIT, rec, index, trx);
+ lock = lock_rec_create(type_mode | LOCK_WAIT, rec,
+ heap_no, index, trx);
/* Check if a deadlock occurs: if yes, remove the lock request and
return an error code */
- if (lock_deadlock_occurs(lock, trx)) {
+ if (UNIV_UNLIKELY(lock_deadlock_occurs(lock, trx))) {
lock_reset_lock_and_trx_wait(lock);
- lock_rec_reset_nth_bit(lock, rec_get_heap_no(rec,
- page_rec_is_comp(rec)));
+ lock_rec_reset_nth_bit(lock, heap_no);
return(DB_DEADLOCK);
}
@@ -1884,13 +1890,11 @@
ulint type_mode,/* in: lock mode, wait, gap etc. flags;
type is ignored and replaced by LOCK_REC */
rec_t* rec, /* in: record on page */
+ ulint heap_no,/* in: heap number of the record */
dict_index_t* index, /* in: index of record */
trx_t* trx) /* in: transaction */
{
lock_t* lock;
- lock_t* similar_lock = NULL;
- ulint heap_no;
- ibool somebody_waits = FALSE;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
@@ -1898,11 +1902,11 @@
ut_ad((type_mode & (LOCK_WAIT | LOCK_GAP))
|| ((type_mode & LOCK_MODE_MASK) != LOCK_S)
|| !lock_rec_other_has_expl_req(LOCK_X, 0, LOCK_WAIT,
- rec, trx));
+ rec, heap_no, trx));
ut_ad((type_mode & (LOCK_WAIT | LOCK_GAP))
|| ((type_mode & LOCK_MODE_MASK) != LOCK_X)
|| !lock_rec_other_has_expl_req(LOCK_S, 0, LOCK_WAIT,
- rec, trx));
+ rec, heap_no, trx));
type_mode = type_mode | LOCK_REC;
@@ -1922,32 +1926,37 @@
/* Look for a waiting lock request on the same record or on a gap */
- heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
lock = lock_rec_get_first_on_page(rec);
while (lock != NULL) {
if (lock_get_wait(lock)
&& (lock_rec_get_nth_bit(lock, heap_no))) {
- somebody_waits = TRUE;
+ goto somebody_waits;
}
lock = lock_rec_get_next_on_page(lock);
}
- /* Look for a similar record lock on the same page: if one is found
- and there are no waiting lock requests, we can just set the bit */
+ if (!(type_mode & LOCK_WAIT)) {
+
+ /* Look for a similar record lock on the same page:
+ if one is found and there are no waiting lock requests,
+ we can just set the bit */
- similar_lock = lock_rec_find_similar_on_page(type_mode, rec, trx);
+ lock = lock_rec_find_similar_on_page(type_mode, heap_no,
+ lock_rec_get_first_on_page(rec), trx);
- if (similar_lock && !somebody_waits && !(type_mode & LOCK_WAIT)) {
+ if (lock) {
- lock_rec_set_nth_bit(similar_lock, heap_no);
+ lock_rec_set_nth_bit(lock, heap_no);
- return(similar_lock);
+ return(lock);
+ }
}
- return(lock_rec_create(type_mode, rec, index, trx));
+somebody_waits:
+ return(lock_rec_create(type_mode, rec, heap_no, index, trx));
}
/*************************************************************************
@@ -1968,11 +1977,11 @@
ulint mode, /* in: lock mode: LOCK_X or LOCK_S possibly
ORed to either LOCK_GAP or LOCK_REC_NOT_GAP */
rec_t* rec, /* in: record */
+ ulint heap_no,/* in: heap number of record */
dict_index_t* index, /* in: index of record */
que_thr_t* thr) /* in: query thread */
{
lock_t* lock;
- ulint heap_no;
trx_t* trx;
#ifdef UNIV_SYNC_DEBUG
@@ -1988,15 +1997,13 @@
|| mode - (LOCK_MODE_MASK & mode) == 0
|| mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP);
- heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
-
lock = lock_rec_get_first_on_page(rec);
trx = thr_get_trx(thr);
if (lock == NULL) {
if (!impl) {
- lock_rec_create(mode, rec, index, trx);
+ lock_rec_create(mode, rec, heap_no, index, trx);
if (srv_locks_unsafe_for_binlog) {
trx_register_new_rec_lock(trx, index);
@@ -2050,6 +2057,7 @@
ulint mode, /* in: lock mode: LOCK_X or LOCK_S possibly
ORed to either LOCK_GAP or LOCK_REC_NOT_GAP */
rec_t* rec, /* in: record */
+ ulint heap_no,/* in: heap number of record */
dict_index_t* index, /* in: index of record */
que_thr_t* thr) /* in: query thread */
{
@@ -2071,12 +2079,12 @@
trx = thr_get_trx(thr);
- if (lock_rec_has_expl(mode, rec, trx)) {
+ if (lock_rec_has_expl(mode, rec, heap_no, trx)) {
/* The trx already has a strong enough lock on rec: do
nothing */
err = DB_SUCCESS;
- } else if (lock_rec_other_has_conflicting(mode, rec, trx)) {
+ } else if (lock_rec_other_has_conflicting(mode, rec, heap_no, trx)) {
/* If another transaction has a non-gap conflicting request in
the queue, as this transaction does not have a lock strong
@@ -2091,8 +2099,8 @@
if (!impl) {
/* Set the requested lock on the record */
- lock_rec_add_to_queue(LOCK_REC | mode, rec, index,
- trx);
+ lock_rec_add_to_queue(LOCK_REC | mode, rec, heap_no,
+ index, trx);
if (srv_locks_unsafe_for_binlog) {
trx_register_new_rec_lock(trx, index);
}
@@ -2126,6 +2134,7 @@
que_thr_t* thr) /* in: query thread */
{
ulint err;
+ ulint heap_no;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
@@ -2140,14 +2149,16 @@
|| mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP
|| mode - (LOCK_MODE_MASK & mode) == 0);
- if (lock_rec_lock_fast(impl, mode, rec, index, thr)) {
+ heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
+
+ if (lock_rec_lock_fast(impl, mode, rec, heap_no, index, thr)) {
/* We try a simplified and faster subroutine for the most
common cases */
err = DB_SUCCESS;
} else {
- err = lock_rec_lock_slow(impl, mode, rec, index, thr);
+ err = lock_rec_lock_slow(impl, mode, rec, heap_no, index, thr);
}
return(err);
@@ -2399,8 +2410,8 @@
#endif /* UNIV_SYNC_DEBUG */
heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
-
- lock = lock_rec_get_first(rec);
+
+ lock = lock_rec_get_first(rec, heap_no);
while (lock != NULL) {
if (lock_get_wait(lock)) {
@@ -2409,7 +2420,7 @@
lock_rec_reset_nth_bit(lock, heap_no);
}
- lock = lock_rec_get_next(rec, lock);
+ lock = lock_rec_get_next(heap_no, lock);
}
}
@@ -2427,11 +2438,21 @@
the locks on this record */
{
lock_t* lock;
+ ulint heir_heap_no;
+ ulint heap_no;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */
- lock = lock_rec_get_first(rec);
+ if (page_rec_is_comp(rec)) {
+ heir_heap_no = rec_get_heap_no(heir, TRUE);
+ heap_no = rec_get_heap_no(rec, TRUE);
+ } else {
+ heir_heap_no = rec_get_heap_no(heir, FALSE);
+ heap_no = rec_get_heap_no(rec, FALSE);
+ }
+
+ lock = lock_rec_get_first(rec, heap_no);
/* If srv_locks_unsafe_for_binlog is TRUE, we do not want locks set
by an UPDATE or a DELETE to be inherited as gap type locks. But we
@@ -2445,10 +2466,11 @@
lock_rec_add_to_queue(LOCK_REC | lock_get_mode(lock)
| LOCK_GAP,
- heir, lock->index, lock->trx);
+ heir, heir_heap_no,
+ lock->index, lock->trx);
}
- lock = lock_rec_get_next(rec, lock);
+ lock = lock_rec_get_next(heap_no, lock);
}
}
@@ -2465,11 +2487,21 @@
the locks on this record */
{
lock_t* lock;
+ ulint heir_heap_no;
+ ulint heap_no;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */
- lock = lock_rec_get_first(rec);
+ if (page_rec_is_comp(rec)) {
+ heir_heap_no = rec_get_heap_no(heir, TRUE);
+ heap_no = rec_get_heap_no(rec, TRUE);
+ } else {
+ heir_heap_no = rec_get_heap_no(heir, FALSE);
+ heap_no = rec_get_heap_no(rec, FALSE);
+ }
+
+ lock = lock_rec_get_first(rec, heap_no);
while (lock != NULL) {
if (!lock_rec_get_insert_intention(lock)
@@ -2478,10 +2510,11 @@
lock_rec_add_to_queue(LOCK_REC | lock_get_mode(lock)
| LOCK_GAP,
- heir, lock->index, lock->trx);
+ heir, heir_heap_no,
+ lock->index, lock->trx);
}
- lock = lock_rec_get_next(rec, lock);
+ lock = lock_rec_get_next(heap_no, lock);
}
}
@@ -2498,37 +2531,44 @@
ulint comp) /* in: nonzero=compact page format */
{
lock_t* lock;
- ulint heap_no;
+ ulint receiver_heap_no;
+ ulint donator_heap_no;
ulint type_mode;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */
- heap_no = rec_get_heap_no(donator, comp);
-
- lock = lock_rec_get_first(donator);
+ if (UNIV_LIKELY(comp)) {
+ receiver_heap_no = rec_get_heap_no(donator, TRUE);
+ donator_heap_no = rec_get_heap_no(donator, TRUE);
+ } else {
+ receiver_heap_no = rec_get_heap_no(donator, FALSE);
+ donator_heap_no = rec_get_heap_no(donator, FALSE);
+ }
+
+ lock = lock_rec_get_first(donator, donator_heap_no);
- ut_ad(lock_rec_get_first(receiver) == NULL);
+ ut_ad(lock_rec_get_first(receiver, receiver_heap_no) == NULL);
while (lock != NULL) {
type_mode = lock->type_mode;
- lock_rec_reset_nth_bit(lock, heap_no);
+ lock_rec_reset_nth_bit(lock, donator_heap_no);
- if (lock_get_wait(lock)) {
+ if (UNIV_UNLIKELY(lock_get_wait(lock))) {
lock_reset_lock_and_trx_wait(lock);
}
/* Note that we FIRST reset the bit, and then set the lock:
the function works also if donator == receiver */
- lock_rec_add_to_queue(type_mode, receiver, lock->index,
- lock->trx);
- lock = lock_rec_get_next(donator, lock);
+ lock_rec_add_to_queue(type_mode, receiver, receiver_heap_no,
+ lock->index, lock->trx);
+ lock = lock_rec_get_next(donator_heap_no, lock);
}
- ut_ad(lock_rec_get_first(donator) == NULL);
+ ut_ad(lock_rec_get_first(donator, donator_heap_no) == NULL);
}
/*****************************************************************
@@ -2548,9 +2588,9 @@
page_cur_t cur1;
page_cur_t cur2;
ulint old_heap_no;
+ ulint new_heap_no;
UT_LIST_BASE_NODE_T(lock_t) old_locks;
mem_heap_t* heap = NULL;
- rec_t* sup;
ulint comp;
lock_mutex_enter_kernel();
@@ -2588,8 +2628,6 @@
lock = lock_rec_get_next_on_page(lock);
}
- sup = page_get_supremum_rec(page);
-
lock = UT_LIST_GET_FIRST(old_locks);
comp = page_is_comp(page);
@@ -2610,8 +2648,17 @@
page_cur_get_rec(&cur2),
rec_get_data_size_old(
page_cur_get_rec(&cur2))));
- old_heap_no = rec_get_heap_no(page_cur_get_rec(&cur2),
- comp);
+ if (UNIV_LIKELY(comp)) {
+ old_heap_no = rec_get_heap_no(
+ page_cur_get_rec(&cur2), TRUE);
+ new_heap_no = rec_get_heap_no(
+ page_cur_get_rec(&cur1), TRUE);
+ } else {
+ old_heap_no = rec_get_heap_no(
+ page_cur_get_rec(&cur2), FALSE);
+ new_heap_no = rec_get_heap_no(
+ page_cur_get_rec(&cur1), FALSE);
+ }
if (lock_rec_get_nth_bit(lock, old_heap_no)) {
@@ -2620,9 +2667,10 @@
lock_rec_add_to_queue(lock->type_mode,
page_cur_get_rec(&cur1),
+ new_heap_no,
lock->index, lock->trx);
- /* if ((page_cur_get_rec(&cur1) == sup)
+ /* if ((page_cur_is_after_last(&cur1))
&& lock_get_wait(lock)) {
fprintf(stderr,
"---\n--\n!!!Lock reorg: supr type %lu\n",
@@ -2630,7 +2678,7 @@
} */
}
- if (page_cur_get_rec(&cur1) == sup) {
+ if (page_cur_is_after_last(&cur1)) {
break;
}
@@ -2668,9 +2716,8 @@
page_cur_t cur1;
page_cur_t cur2;
ulint heap_no;
- rec_t* sup;
ulint type_mode;
- ulint comp;
+ ut_ad(page_is_comp(page) == page_is_comp(new_page));
ut_ad(page == buf_frame_align(rec));
lock_mutex_enter_kernel();
@@ -2681,12 +2728,8 @@
table to the end of the hash chain, and lock_rec_add_to_queue
does not reuse locks if there are waiters in the queue. */
- sup = page_get_supremum_rec(page);
-
lock = lock_rec_get_first_on_page(page);
- comp = page_is_comp(page);
-
while (lock != NULL) {
page_cur_position(rec, &cur1);
@@ -2701,13 +2744,14 @@
/* Copy lock requests on user records to new page and
reset the lock bits on the old */
- while (page_cur_get_rec(&cur1) != sup) {
- ut_ad(comp || 0 == ut_memcmp(page_cur_get_rec(&cur1),
+ while (!page_cur_is_after_last(&cur1)) {
+ ut_ad(page_is_comp(page)
+ || 0 == ut_memcmp(page_cur_get_rec(&cur1),
page_cur_get_rec(&cur2),
rec_get_data_size_old(
page_cur_get_rec(&cur2))));
heap_no = rec_get_heap_no(page_cur_get_rec(&cur1),
- comp);
+ page_is_comp(page));
if (lock_rec_get_nth_bit(lock, heap_no)) {
type_mode = lock->type_mode;
@@ -2718,8 +2762,13 @@
lock_reset_lock_and_trx_wait(lock);
}
+ heap_no = rec_get_heap_no(
+ page_cur_get_rec(&cur2),
+ page_is_comp(page));
+
lock_rec_add_to_queue(type_mode,
page_cur_get_rec(&cur2),
+ heap_no,
lock->index, lock->trx);
}
@@ -2757,15 +2806,13 @@
page_cur_t cur2;
ulint heap_no;
ulint type_mode;
- ulint comp;
ut_a(new_page);
lock_mutex_enter_kernel();
lock = lock_rec_get_first_on_page(page);
- comp = page_is_comp(page);
- ut_ad(comp == page_is_comp(new_page));
+ ut_ad(page_is_comp(page) == page_is_comp(new_page));
ut_ad(page == buf_frame_align(rec));
while (lock != NULL) {
@@ -2780,12 +2827,14 @@
reset the lock bits on the old */
while (page_cur_get_rec(&cur1) != rec) {
- ut_ad(comp || 0 == ut_memcmp(page_cur_get_rec(&cur1),
+ ut_ad(page_is_comp(page)
+ || 0 == ut_memcmp(page_cur_get_rec(&cur1),
page_cur_get_rec(&cur2),
rec_get_data_size_old(
page_cur_get_rec(&cur2))));
- heap_no = rec_get_heap_no(page_cur_get_rec(&cur1),
- comp);
+ heap_no = rec_get_heap_no(
+ page_cur_get_rec(&cur1),
+ page_is_comp(page));
if (lock_rec_get_nth_bit(lock, heap_no)) {
type_mode = lock->type_mode;
@@ -2796,8 +2845,13 @@
lock_reset_lock_and_trx_wait(lock);
}
+ heap_no = rec_get_heap_no(
+ page_cur_get_rec(&cur2),
+ page_is_comp(page));
+
lock_rec_add_to_queue(type_mode,
page_cur_get_rec(&cur2),
+ heap_no,
lock->index, lock->trx);
}
@@ -2825,16 +2879,15 @@
page_t* right_page, /* in: right page */
page_t* left_page) /* in: left page */
{
- ulint comp;
lock_mutex_enter_kernel();
- comp = page_is_comp(left_page);
- ut_ad(comp == page_is_comp(right_page));
+ ut_ad(page_is_comp(left_page) == page_is_comp(right_page));
/* Move the locks on the supremum of the left page to the supremum
of the right page */
lock_rec_move(page_get_supremum_rec(right_page),
- page_get_supremum_rec(left_page), comp);
+ page_get_supremum_rec(left_page),
+ page_is_comp(left_page));
/* Inherit the locks to the supremum of left page from the successor
of the infimum on right page */
@@ -3189,7 +3242,7 @@
goto retry;
}
- if (ret == LOCK_VICTIM_IS_START) {
+ if (UNIV_UNLIKELY(ret == LOCK_VICTIM_IS_START)) {
if (lock_get_type(lock) & LOCK_TABLE) {
table = lock->un_member.tab_lock.table;
index = NULL;
@@ -4392,6 +4445,7 @@
{
trx_t* impl_trx;
lock_t* lock;
+ ulint heap_no;
ut_a(rec);
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -4399,9 +4453,11 @@
lock_mutex_enter_kernel();
+ heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
+
if (!page_rec_is_user_rec(rec)) {
- lock = lock_rec_get_first(rec);
+ lock = lock_rec_get_first(rec, heap_no);
while (lock) {
ut_a(lock->trx->conc_state == TRX_ACTIVE
@@ -4419,7 +4475,7 @@
ut_a(lock->index == index);
}
- lock = lock_rec_get_next(rec, lock);
+ lock = lock_rec_get_next(heap_no, lock);
}
lock_mutex_exit_kernel();
@@ -4427,19 +4483,18 @@
return(TRUE);
}
- if (index && (index->type & DICT_CLUSTERED)) {
+ if (!index);
+ else if (index->type & DICT_CLUSTERED) {
impl_trx = lock_clust_rec_some_has_impl(rec, index, offsets);
if (impl_trx && lock_rec_other_has_expl_req(LOCK_S, 0,
- LOCK_WAIT, rec, impl_trx)) {
+ LOCK_WAIT, rec, heap_no, impl_trx)) {
ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, rec,
- impl_trx));
+ heap_no, impl_trx));
}
- }
-
- if (index && !(index->type & DICT_CLUSTERED)) {
+ } else {
/* The kernel mutex may get released temporarily in the
next function call: we have to release lock table mutex
@@ -4449,14 +4504,14 @@
rec, index, offsets);
if (impl_trx && lock_rec_other_has_expl_req(LOCK_S, 0,
- LOCK_WAIT, rec, impl_trx)) {
+ LOCK_WAIT, rec, heap_no, impl_trx)) {
ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP,
- rec, impl_trx));
+ rec, heap_no, impl_trx));
}
}
- lock = lock_rec_get_first(rec);
+ lock = lock_rec_get_first(rec, heap_no);
while (lock) {
ut_a(lock->trx->conc_state == TRX_ACTIVE
@@ -4477,15 +4532,15 @@
} else {
mode = LOCK_S;
}
- ut_a(!lock_rec_other_has_expl_req(mode,
- 0, 0, rec, lock->trx));
+ ut_a(!lock_rec_other_has_expl_req(mode, 0, 0,
+ rec, heap_no, lock->trx));
} else if (lock_get_wait(lock) && !lock_rec_get_gap(lock)) {
ut_a(lock_rec_has_to_wait_in_queue(lock));
}
- lock = lock_rec_get_next(rec, lock);
+ lock = lock_rec_get_next(heap_no, lock);
}
lock_mutex_exit_kernel();
@@ -4693,6 +4748,7 @@
trx_t* trx;
lock_t* lock;
ulint err;
+ ulint next_rec_heap_no;
if (flags & BTR_NO_LOCKING_FLAG) {
@@ -4704,15 +4760,16 @@
trx = thr_get_trx(thr);
next_rec = page_rec_get_next(rec);
- *inherit = FALSE;
-
lock_mutex_enter_kernel();
ut_ad(lock_table_has(thr_get_trx(thr), index->table, LOCK_IX));
- lock = lock_rec_get_first(next_rec);
+ next_rec_heap_no = rec_get_heap_no(next_rec,
+ page_rec_is_comp(next_rec));
- if (lock == NULL) {
+ lock = lock_rec_get_first(next_rec, next_rec_heap_no);
+
+ if (UNIV_LIKELY(lock == NULL)) {
/* We optimize CPU time usage in the simplest case */
lock_mutex_exit_kernel();
@@ -4724,6 +4781,8 @@
thr_get_trx(thr)->id);
}
+ *inherit = FALSE;
+
return(DB_SUCCESS);
}
@@ -4740,7 +4799,8 @@
on the successor, which produced an unnecessary deadlock. */
if (lock_rec_other_has_conflicting(LOCK_X | LOCK_GAP
- | LOCK_INSERT_INTENTION, next_rec, trx)) {
+ | LOCK_INSERT_INTENTION,
+ next_rec, next_rec_heap_no, trx)) {
/* Note that we may get DB_SUCCESS also here! */
err = lock_rec_enqueue_waiting(LOCK_X | LOCK_GAP
@@ -4810,12 +4870,14 @@
/* If the transaction has no explicit x-lock set on the
record, set one for it */
+ ulint heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
+
if (!lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, rec,
- impl_trx)) {
+ heap_no, impl_trx)) {
lock_rec_add_to_queue(LOCK_REC | LOCK_X
- | LOCK_REC_NOT_GAP, rec, index,
- impl_trx);
+ | LOCK_REC_NOT_GAP, rec, heap_no,
+ index, impl_trx);
}
}
}
| Thread |
|---|
| • bk commit into 5.0 tree (marko:1.1909) | Marko Mäkelä | 19 Jul |