List:Internals« Previous MessageNext Message »
From:Marko Mäkelä Date:July 19 2005 10:50am
Subject:bk commit into 5.0 tree (marko:1.1909)
View as plain text  
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