diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c
index 1744fc36f4d7de1ff778eff65d80ba813e67b6f4..2d84586216acc279108fbf58df7f90a4d96d447b 100644
--- a/innobase/btr/btr0btr.c
+++ b/innobase/btr/btr0btr.c
@@ -20,6 +20,7 @@ Created 6/2/1994 Heikki Tuuri
 #include "rem0cmp.h"
 #include "lock0lock.h"
 #include "ibuf0ibuf.h"
+#include "trx0trx.h"
 
 /*
 Latching strategy of the InnoDB B-tree
@@ -137,13 +138,13 @@ btr_root_get(
 	ulint	space;
 	ulint	root_page_no;
 	page_t*	root;
-	ibool	comp = UT_LIST_GET_FIRST(tree->tree_indexes)->table->comp;
 	
 	space = dict_tree_get_space(tree);
 	root_page_no = dict_tree_get_page(tree);
 
 	root = btr_page_get(space, root_page_no, RW_X_LATCH, mtr);
-	ut_a(page_is_comp(root) == comp);
+	ut_a(!!page_is_comp(root) ==
+			UT_LIST_GET_FIRST(tree->tree_indexes)->table->comp);
 	
 	return(root);
 }
@@ -163,21 +164,19 @@ btr_get_prev_user_rec(
 	page_t*	page;
 	page_t*	prev_page;
 	ulint	prev_page_no;
-	rec_t*	prev_rec;
 	ulint	space;
 
-	page = buf_frame_align(rec);
-	
-	if (page_get_infimum_rec(page) != rec) {
+	if (!page_rec_is_infimum(rec)) {
 
-		prev_rec = page_rec_get_prev(rec);
+		rec_t*	prev_rec = page_rec_get_prev(rec);
 
-		if (page_get_infimum_rec(page) != prev_rec) {
+		if (!page_rec_is_infimum(prev_rec)) {
 
 			return(prev_rec);
 		}
 	}
 	
+	page = buf_frame_align(rec);
 	prev_page_no = btr_page_get_prev(page, mtr);
 	space = buf_frame_get_space_id(page);
 	
@@ -192,9 +191,7 @@ btr_get_prev_user_rec(
 		      				MTR_MEMO_PAGE_X_FIX)));
 		ut_a(page_is_comp(prev_page) == page_is_comp(page));
 
-		prev_rec = page_rec_get_prev(page_get_supremum_rec(prev_page));
-
-		return(prev_rec);
+		return(page_rec_get_prev(page_get_supremum_rec(prev_page)));
 	}
 
 	return(NULL);
@@ -215,21 +212,19 @@ btr_get_next_user_rec(
 	page_t*	page;
 	page_t*	next_page;
 	ulint	next_page_no;
-	rec_t*	next_rec;
 	ulint	space;
 
-	page = buf_frame_align(rec);
-	
-	if (page_get_supremum_rec(page) != rec) {
+	if (!page_rec_is_supremum(rec)) {
 
-		next_rec = page_rec_get_next(rec);
+		rec_t*	next_rec = page_rec_get_next(rec);
 
-		if (page_get_supremum_rec(page) != next_rec) {
+		if (!page_rec_is_supremum(next_rec)) {
 
 			return(next_rec);
 		}
 	}
 	
+	page = buf_frame_align(rec);
 	next_page_no = btr_page_get_next(page, mtr);
 	space = buf_frame_get_space_id(page);
 	
@@ -244,9 +239,7 @@ btr_get_next_user_rec(
 		      				MTR_MEMO_PAGE_X_FIX)));
 
 		ut_a(page_is_comp(next_page) == page_is_comp(page));
-		next_rec = page_rec_get_next(page_get_infimum_rec(next_page));
-
-		return(next_rec);
+		return(page_rec_get_next(page_get_infimum_rec(next_page)));
 	}
 
 	return(NULL);
@@ -573,8 +566,7 @@ btr_page_get_father_for_rec(
 
 	ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
 							MTR_MEMO_X_LOCK));
-	ut_a(user_rec != page_get_supremum_rec(page));
-	ut_a(user_rec != page_get_infimum_rec(page));
+	ut_a(page_rec_is_user_rec(user_rec));
 	
 	ut_ad(dict_tree_get_page(tree) != buf_frame_get_page_no(page));
 
@@ -598,6 +590,7 @@ btr_page_get_father_for_rec(
 
 	if (btr_node_ptr_get_child_page_no(node_ptr, offsets) !=
                                                 buf_frame_get_page_no(page)) {
+		rec_t*	print_rec;
 		fputs("InnoDB: Dump of the child page:\n", stderr);
 		buf_page_print(buf_frame_align(page));
 		fputs("InnoDB: Dump of the parent page:\n", stderr);
@@ -612,11 +605,10 @@ btr_page_get_father_for_rec(
 			(ulong)
 			btr_node_ptr_get_child_page_no(node_ptr, offsets),
 			(ulong) buf_frame_get_page_no(page));
-		offsets = rec_get_offsets(page_rec_get_next(
-				page_get_infimum_rec(page)), index,
+		print_rec = page_rec_get_next(page_get_infimum_rec(page));
+		offsets = rec_get_offsets(print_rec, index,
 				offsets, ULINT_UNDEFINED, &heap);
-		page_rec_print(page_rec_get_next(page_get_infimum_rec(page)),
-					offsets);
+		page_rec_print(print_rec, offsets);
 		offsets = rec_get_offsets(node_ptr, index, offsets,
 					ULINT_UNDEFINED, &heap);
 		page_rec_print(node_ptr, offsets);
@@ -663,7 +655,7 @@ btr_create(
 	ulint	type,	/* in: type of the index */
 	ulint	space,	/* in: space where created */
 	dulint	index_id,/* in: index id */
-	ibool	comp,	/* in: TRUE=compact page format */
+	ulint	comp,	/* in: nonzero=compact page format */
 	mtr_t*	mtr)	/* in: mini-transaction handle */
 {
 	ulint		page_no;
@@ -854,11 +846,12 @@ btr_page_reorganize_low(
 
 	ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
 			      				MTR_MEMO_PAGE_X_FIX));
+	ut_ad(!!page_is_comp(page) == index->table->comp);
 	data_size1 = page_get_data_size(page);
 	max_ins_size1 = page_get_max_insert_size_after_reorganize(page, 1);
 
 	/* Write the log record */
-	mlog_open_and_write_index(mtr, page, index, index->table->comp
+	mlog_open_and_write_index(mtr, page, index, page_is_comp(page)
 			? MLOG_COMP_PAGE_REORGANIZE
 			: MLOG_PAGE_REORGANIZE, 0);
 
@@ -877,7 +870,7 @@ btr_page_reorganize_low(
 	/* Recreate the page: note that global data on page (possible
 	segment headers, next page-field, etc.) is preserved intact */
 
-	page_create(page, mtr, index->table->comp);
+	page_create(page, mtr, page_is_comp(page));
 	buf_block_align(page)->check_index_page_at_flush = TRUE;
 	
 	/* Copy the records from the temporary space to the recreated page;
@@ -1070,7 +1063,7 @@ btr_root_raise_and_insert(
 	as there is no lower alphabetical limit to records in the leftmost
 	node of a level: */
 
-	btr_set_min_rec_mark(node_ptr_rec, cursor->index->table->comp, mtr);
+	btr_set_min_rec_mark(node_ptr_rec, page_is_comp(root), mtr);
 		
 	/* Free the memory heap */
 	mem_heap_free(heap);
@@ -1151,7 +1144,6 @@ btr_page_get_split_rec_to_right(
 {
 	page_t*	page;
 	rec_t*	insert_point;
-	rec_t*	supremum;
 
 	page = btr_cur_get_page(cursor);
 	insert_point = btr_cur_get_rec(cursor);
@@ -1160,13 +1152,23 @@ btr_page_get_split_rec_to_right(
 	the previous insert on the same page, we assume that there is a
 	pattern of sequential inserts here. */
 
-	if (page_header_get_ptr(page, PAGE_LAST_INSERT) == insert_point) {
+	if (UNIV_LIKELY(page_header_get_ptr(page, PAGE_LAST_INSERT)
+				== insert_point)) {
+
+		rec_t*	next_rec;
+
+		next_rec = page_rec_get_next(insert_point);
 
-	     	supremum = page_get_supremum_rec(page);
-	     	 			
-		if (page_rec_get_next(insert_point) != supremum
-		    && page_rec_get_next(page_rec_get_next(insert_point))
-			!= supremum) {
+		if (page_rec_is_supremum(next_rec)) {
+split_at_new:
+			/* Split at the new record to insert */
+	     		*split_rec = NULL;
+		} else {
+			rec_t*	next_next_rec = page_rec_get_next(next_rec);
+			if (page_rec_is_supremum(next_next_rec)) {
+
+				goto split_at_new;
+			}
 
 			/* If there are >= 2 user records up from the insert
 			point, split all but 1 off. We want to keep one because
@@ -1175,12 +1177,8 @@ btr_page_get_split_rec_to_right(
 			search position just by looking at the records on this
 			page. */
 		
-			*split_rec = page_rec_get_next(
-					page_rec_get_next(insert_point));
-		} else {
-			/* Else split at the new record to insert */
-	     		*split_rec = NULL;
-	     	}
+			*split_rec = next_next_rec;
+		}
 
 		return(TRUE);
 	}
@@ -1220,7 +1218,7 @@ btr_page_get_sure_split_rec(
 	page = btr_cur_get_page(cursor);
 	
 	insert_size = rec_get_converted_size(cursor->index, tuple);
-	free_space  = page_get_free_space_of_empty(cursor->index->table->comp);
+	free_space  = page_get_free_space_of_empty(page_is_comp(page));
 
 	/* free_space is now the free space of a created new page */
 
@@ -1276,21 +1274,22 @@ btr_page_get_sure_split_rec(
                     	    	supremum record of page */
 
 				if (rec == ins_rec) {
-					next_rec = NULL;
+					rec = NULL;
+
+					goto func_exit;
 				} else if (rec == NULL) {
 					next_rec = page_rec_get_next(ins_rec);
 				} else {
 					next_rec = page_rec_get_next(rec);
 				}
-				if (next_rec != page_get_supremum_rec(page)) {
-					if (heap) {
-						mem_heap_free(heap);
-					}
-					return(next_rec);
+				ut_ad(next_rec);
+				if (!page_rec_is_supremum(next_rec)) {
+					rec = next_rec;
 				}
                     	}
 
-			if (heap) {
+func_exit:
+			if (UNIV_LIKELY_NULL(heap)) {
 				mem_heap_free(heap);
 			}
 			return(rec);
@@ -1329,13 +1328,12 @@ btr_page_insert_fits(
 
 	ut_ad(!split_rec == !offsets);
 	ut_ad(!offsets
-		|| cursor->index->table->comp == rec_offs_comp(offsets));
+		|| !page_is_comp(page) == !rec_offs_comp(offsets));
 	ut_ad(!offsets
 		|| rec_offs_validate(split_rec, cursor->index, offsets));
-	ut_ad(page_is_comp(page) == cursor->index->table->comp);
 
 	insert_size = rec_get_converted_size(cursor->index, tuple);
-	free_space  = page_get_free_space_of_empty(cursor->index->table->comp);
+	free_space  = page_get_free_space_of_empty(page_is_comp(page));
 
 	/* free_space is now the free space of a created new page */
 
@@ -1832,14 +1830,15 @@ void
 btr_set_min_rec_mark_log(
 /*=====================*/
 	rec_t*	rec,	/* in: record */
-	ibool	comp,	/* TRUE=compact record format */
+	ulint	comp,	/* nonzero=compact record format */
 	mtr_t*	mtr)	/* in: mtr */
 {
 	mlog_write_initial_log_record(rec,
 		comp ? MLOG_COMP_REC_MIN_MARK : MLOG_REC_MIN_MARK, mtr);
 
 	/* Write rec offset as a 2-byte ulint */
-	mlog_catenate_ulint(mtr, rec - buf_frame_align(rec), MLOG_2BYTES);
+	mlog_catenate_ulint(mtr, ut_align_offset(rec, UNIV_PAGE_SIZE),
+								MLOG_2BYTES);
 }
 
 /********************************************************************
@@ -1852,7 +1851,7 @@ btr_parse_set_min_rec_mark(
 			/* out: end of log record or NULL */
 	byte*	ptr,	/* in: buffer */
 	byte*	end_ptr,/* in: buffer end */
-	ibool	comp,	/* in: TRUE=compact page format */
+	ulint	comp,	/* in: nonzero=compact page format */
 	page_t*	page,	/* in: page or NULL */
 	mtr_t*	mtr)	/* in: mtr or NULL */
 {
@@ -1864,6 +1863,8 @@ btr_parse_set_min_rec_mark(
 	}
 
 	if (page) {
+		ut_a(!page_is_comp(page) == !comp);
+
 		rec = page + mach_read_from_2(ptr);
 
 		btr_set_min_rec_mark(rec, comp, mtr);
@@ -1879,7 +1880,7 @@ void
 btr_set_min_rec_mark(
 /*=================*/
 	rec_t*	rec,	/* in: record */
-	ibool	comp,	/* in: TRUE=compact page format */
+	ulint	comp,	/* in: nonzero=compact page format */
 	mtr_t*	mtr)	/* in: mtr */
 {
 	ulint	info_bits;
@@ -2008,11 +2009,12 @@ btr_compress(
 	ulint		max_ins_size;
 	ulint		max_ins_size_reorg;
 	ulint		level;
-	ibool		comp	= cursor->index->table->comp;
+	ulint		comp;
 
 	page = btr_cur_get_page(cursor);
 	tree = btr_cur_get_tree(cursor);
-	ut_a(comp == page_is_comp(page));
+	comp = page_is_comp(page);
+	ut_a(!!comp == cursor->index->table->comp);
 
 	ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
 							MTR_MEMO_X_LOCK));
@@ -2055,7 +2057,7 @@ btr_compress(
 	
 	n_recs = page_get_n_recs(page);
 	data_size = page_get_data_size(page);
-	ut_a(page_is_comp(merge_page) == page_is_comp(page));
+	ut_a(page_is_comp(merge_page) == comp);
 
 	max_ins_size_reorg = page_get_max_insert_size_after_reorganize(
 							merge_page, n_recs);
@@ -2108,7 +2110,7 @@ btr_compress(
 				rec_get_offsets(node_ptr, cursor->index,
 				offsets_, ULINT_UNDEFINED, &heap),
 				right_page_no, mtr);
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 		btr_node_ptr_delete(tree, merge_page, mtr);
@@ -2250,10 +2252,9 @@ btr_discard_page(
 
 		node_ptr = page_rec_get_next(page_get_infimum_rec(merge_page));
 
-		ut_ad(node_ptr != page_get_supremum_rec(merge_page));
+		ut_ad(page_rec_is_user_rec(node_ptr));
 
-		btr_set_min_rec_mark(node_ptr,
-					cursor->index->table->comp, mtr);
+		btr_set_min_rec_mark(node_ptr, page_is_comp(merge_page), mtr);
 	}	
 	
 	btr_node_ptr_delete(tree, page, mtr);
@@ -2274,6 +2275,7 @@ btr_discard_page(
 	ut_ad(btr_check_node_ptr(tree, merge_page, mtr));
 }	
 
+#ifdef UNIV_BTR_PRINT
 /*****************************************************************
 Prints size info of a B-tree. */
 
@@ -2401,14 +2403,15 @@ btr_print_tree(
 	root = btr_root_get(tree, &mtr);
 
 	btr_print_recursive(tree, root, width, &heap, &offsets, &mtr);
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 
 	mtr_commit(&mtr);
 
-	btr_validate_tree(tree);
+	btr_validate_tree(tree, NULL);
 }
+#endif /* UNIV_BTR_PRINT */
 
 /****************************************************************
 Checks that the node pointer to a page is appropriate. */
@@ -2496,8 +2499,8 @@ btr_index_rec_validate(
 	*offsets_ = (sizeof offsets_) / sizeof *offsets_;
 
 	page = buf_frame_align(rec);
-	
-	if (index->type & DICT_UNIVERSAL) {
+
+	if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
 	        /* The insert buffer index tree can contain records from any
 	        other index: we cannot check the number of fields or
 	        their length */
@@ -2505,9 +2508,18 @@ btr_index_rec_validate(
 	        return(TRUE);
 	}
 
+	if (UNIV_UNLIKELY(!!page_is_comp(page) != index->table->comp)) {
+		btr_index_rec_validate_report(page, rec, index);
+		fprintf(stderr, "InnoDB: compact flag=%lu, should be %lu\n",
+			(ulong) !!page_is_comp(page),
+			(ulong) index->table->comp);
+		return(FALSE);
+	}
+
 	n = dict_index_get_n_fields(index);
 
-	if (!index->table->comp && rec_get_n_fields_old(rec) != n) {
+	if (!page_is_comp(page)
+			&& UNIV_UNLIKELY(rec_get_n_fields_old(rec) != n)) {
 		btr_index_rec_validate_report(page, rec, index);
 		fprintf(stderr, "InnoDB: has %lu fields, should have %lu\n",
 			(ulong) rec_get_n_fields_old(rec), (ulong) n);
@@ -2554,14 +2566,14 @@ btr_index_rec_validate(
 				rec_print_new(stderr, rec, offsets);
 				putc('\n', stderr);
 			}
-			if (heap) {
+			if (UNIV_LIKELY_NULL(heap)) {
 				mem_heap_free(heap);
 			}
 			return(FALSE);
 		}
 	}
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	return(TRUE);			
@@ -2649,6 +2661,7 @@ btr_validate_level(
 /*===============*/
 				/* out: TRUE if ok */
 	dict_tree_t*	tree,	/* in: index tree */
+	trx_t*		trx,	/* in: transaction or NULL */
 	ulint		level)	/* in: level number */
 {
 	ulint		space;
@@ -2696,6 +2709,11 @@ btr_validate_level(
 	/* Now we are on the desired level. Loop through the pages on that
 	level. */
 loop:
+	if (trx_is_interrupted(trx)) {
+		mtr_commit(&mtr);
+		mem_heap_free(heap);
+		return(ret);
+	}
 	mem_heap_empty(heap);
 	offsets = offsets2 = NULL;
 	mtr_x_lock(dict_tree_get_lock(tree), &mtr);
@@ -2765,7 +2783,7 @@ loop:
 	if (level > 0 && left_page_no == FIL_NULL) {
 		ut_a(REC_INFO_MIN_REC_FLAG & rec_get_info_bits(
 			page_rec_get_next(page_get_infimum_rec(page)),
-				index->table->comp));
+				page_is_comp(page)));
 	}
 
 	if (buf_frame_get_page_no(page) != dict_tree_get_page(tree)) {
@@ -2921,7 +2939,7 @@ node_ptr_fails:
 	mtr_commit(&mtr);
 
 	if (right_page_no != FIL_NULL) {
-		ibool	comp = page_is_comp(page);
+		ulint	comp = page_is_comp(page);
 		mtr_start(&mtr);
 	
 		page = btr_page_get(space, right_page_no, RW_X_LATCH, &mtr);
@@ -2941,7 +2959,8 @@ ibool
 btr_validate_tree(
 /*==============*/
 				/* out: TRUE if ok */
-	dict_tree_t*	tree)	/* in: tree */
+	dict_tree_t*	tree,	/* in: tree */
+	trx_t*		trx)	/* in: transaction or NULL */
 {
 	mtr_t	mtr;
 	page_t*	root;
@@ -2954,9 +2973,8 @@ btr_validate_tree(
 	root = btr_root_get(tree, &mtr);
 	n = btr_page_get_level(root, &mtr);
 
-	for (i = 0; i <= n; i++) {
-		
-		if (!btr_validate_level(tree, n - i)) {
+	for (i = 0; i <= n && !trx_is_interrupted(trx); i++) {
+		if (!btr_validate_level(tree, trx, n - i)) {
 
 			mtr_commit(&mtr);
 
diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c
index e093c911f22b87ec143360ab8e9dbbe4149d66bf..98d90ecf18aa05982da24e35938eb15f5d9baef1 100644
--- a/innobase/btr/btr0cur.c
+++ b/innobase/btr/btr0cur.c
@@ -36,11 +36,11 @@ Created 10/16/1994 Heikki Tuuri
 #include "ibuf0ibuf.h"
 #include "lock0lock.h"
 
+#ifdef UNIV_DEBUG
 /* If the following is set to TRUE, this module prints a lot of
 trace information of individual record operations */
 ibool	btr_cur_print_record_ops = FALSE;
-
-ulint	btr_cur_rnd	= 0;
+#endif /* UNIV_DEBUG */
 
 ulint	btr_cur_n_non_sea	= 0;
 ulint	btr_cur_n_sea		= 0;
@@ -431,7 +431,7 @@ retry_page_get:
 							cursor->thr)) {
 				/* Insertion to the insert buffer succeeded */
 				cursor->flag = BTR_CUR_INSERT_TO_IBUF;
-				if (heap) {
+				if (UNIV_LIKELY_NULL(heap)) {
 					mem_heap_free(heap);
 				}
 				return;
@@ -505,8 +505,9 @@ retry_page_get:
 
 			if (level > 0) {
 				/* x-latch the page */
-				ut_a(page_is_comp(btr_page_get(space,
-						page_no, RW_X_LATCH, mtr))
+				page = btr_page_get(space,
+						page_no, RW_X_LATCH, mtr);
+				ut_a(!!page_is_comp(page)
 						== index->table->comp);
 			}
 
@@ -525,7 +526,7 @@ retry_page_get:
 		page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
 	}
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 
@@ -681,7 +682,7 @@ btr_cur_open_at_index_side(
 		page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
 	}
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 }
@@ -762,7 +763,7 @@ btr_cur_open_at_rnd_pos(
 		page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
 	}
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 }	
@@ -879,6 +880,7 @@ btr_cur_ins_lock_and_undo(
 	return(DB_SUCCESS);
 }
 
+#ifdef UNIV_DEBUG
 /*****************************************************************
 Report information about a transaction. */
 static
@@ -896,6 +898,7 @@ btr_cur_trx_report(
 	dict_index_name_print(stderr, trx, index);
 	putc('\n', stderr);
 }
+#endif /* UNIV_DEBUG */
 
 /*****************************************************************
 Tries to perform an insert to a page in an index tree, next to cursor.
@@ -945,12 +948,13 @@ btr_cur_optimistic_insert(
 		fputs("InnoDB: Error in a tuple to insert into ", stderr);
 		dict_index_name_print(stderr, thr_get_trx(thr), index);
 	}
-	
+#ifdef UNIV_DEBUG
 	if (btr_cur_print_record_ops && thr) {
 		btr_cur_trx_report(thr_get_trx(thr), index, "insert into ");
 		dtuple_print(stderr, entry);
 	}
-	
+#endif /* UNIV_DEBUG */
+
 	ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
 							MTR_MEMO_PAGE_X_FIX));
 	max_size = page_get_max_insert_size_after_reorganize(page, 1);
@@ -961,7 +965,7 @@ calculate_sizes_again:
 	rec_size = rec_get_converted_size(index, entry);
 
 	if (rec_size >=
-		ut_min(page_get_free_space_of_empty(index->table->comp) / 2,
+		ut_min(page_get_free_space_of_empty(page_is_comp(page)) / 2,
 		REC_MAX_DATA_SIZE)) {
 
 		/* The record is so big that we have to store some fields
@@ -1027,7 +1031,7 @@ calculate_sizes_again:
 
 	*rec = page_cur_insert_rec_low(page_cursor, entry, index,
 							NULL, NULL, mtr);
-	if (!(*rec)) {
+	if (UNIV_UNLIKELY(!(*rec))) {
 		/* If the record did not fit, reorganize */
 		btr_page_reorganize(page, index, mtr);
 
@@ -1039,7 +1043,7 @@ calculate_sizes_again:
 
 		*rec = page_cur_tuple_insert(page_cursor, entry, index, mtr);
 
-		if (!*rec) {
+		if (UNIV_UNLIKELY(!*rec)) {
 			fputs("InnoDB: Error: cannot insert tuple ", stderr);
 			dtuple_print(stderr, entry);
 			fputs(" into ", stderr);
@@ -1166,7 +1170,7 @@ btr_cur_pessimistic_insert(
 	}
 
 	if (rec_get_converted_size(index, entry) >=
-		ut_min(page_get_free_space_of_empty(index->table->comp) / 2,
+		ut_min(page_get_free_space_of_empty(page_is_comp(page)) / 2,
 		REC_MAX_DATA_SIZE)) {
 
 		/* The record is so big that we have to store some fields
@@ -1261,7 +1265,7 @@ btr_cur_upd_lock_and_undo(
 		err = lock_clust_rec_modify_check_and_lock(flags, rec, index,
 			rec_get_offsets(rec, index, offsets_,
 				ULINT_UNDEFINED, &heap), thr);
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 		if (err != DB_SUCCESS) {
@@ -1293,9 +1297,11 @@ btr_cur_update_in_place_log(
 	mtr_t*		mtr)		/* in: mtr */
 {
 	byte*	log_ptr;
+	page_t*	page	= ut_align_down(rec, UNIV_PAGE_SIZE);
 	ut_ad(flags < 256);
+	ut_ad(!!page_is_comp(page) == index->table->comp);
 
-	log_ptr = mlog_open_and_write_index(mtr, rec, index, index->table->comp
+	log_ptr = mlog_open_and_write_index(mtr, rec, index, page_is_comp(page)
 			? MLOG_COMP_REC_UPDATE_IN_PLACE
 			: MLOG_REC_UPDATE_IN_PLACE,
 			1 + DATA_ROLL_PTR_LEN + 14 + 2 + MLOG_BUF_MARGIN);
@@ -1317,7 +1323,7 @@ btr_cur_update_in_place_log(
 
 	log_ptr = row_upd_write_sys_vals_to_log(index, trx, roll_ptr, log_ptr,
 									mtr);
-	mach_write_to_2(log_ptr, rec - buf_frame_align(rec));
+	mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));
 	log_ptr += 2;
 
 	row_upd_index_write_log(update, log_ptr, mtr);
@@ -1374,18 +1380,12 @@ btr_cur_parse_update_in_place(
 	
 	ptr = row_upd_index_parse(ptr, end_ptr, heap, &update);
 
-	if (ptr == NULL) {
-		mem_heap_free(heap);
-		
-		return(NULL);
-	}
-
-	if (!page) {
-		mem_heap_free(heap);
+	if (!ptr || !page) {
 
-		return(ptr);
+		goto func_exit;
 	}
-	
+
+	ut_a(!!page_is_comp(page) == index->table->comp);
 	rec = page + rec_offset;
 	
 	/* We do not need to reserve btr_search_latch, as the page is only
@@ -1400,6 +1400,7 @@ btr_cur_parse_update_in_place(
 
 	row_upd_rec_in_place(rec, offsets, update);
 
+func_exit:
 	mem_heap_free(heap);
 
 	return(ptr);
@@ -1429,7 +1430,7 @@ btr_cur_update_in_place(
 	rec_t*		rec;
 	dulint		roll_ptr	= ut_dulint_zero;
 	trx_t*		trx;
-	ibool		was_delete_marked;
+	ulint		was_delete_marked;
 	mem_heap_t*	heap		= NULL;
 	ulint		offsets_[REC_OFFS_NORMAL_SIZE];
 	ulint*		offsets		= offsets_;
@@ -1437,27 +1438,30 @@ btr_cur_update_in_place(
 
 	rec = btr_cur_get_rec(cursor);
 	index = cursor->index;
+	ut_ad(!!page_rec_is_comp(rec) == index->table->comp);
 	trx = thr_get_trx(thr);
-	heap = mem_heap_create(100);
 	offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
-
+#ifdef UNIV_DEBUG
 	if (btr_cur_print_record_ops && thr) {
 		btr_cur_trx_report(trx, index, "update ");
 		rec_print_new(stderr, rec, offsets);
 	}
+#endif /* UNIV_DEBUG */
 
 	/* Do lock checking and undo logging */
 	err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
 							thr, &roll_ptr);
-	if (err != DB_SUCCESS) {
+	if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
 
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 		return(err);
 	}
 
 	block = buf_block_align(rec);
+	ut_ad(!!page_is_comp(buf_block_get_frame(block))
+				== index->table->comp);
 
 	if (block->is_hashed) {
 		/* The function row_upd_changes_ord_field_binary works only
@@ -1481,7 +1485,8 @@ btr_cur_update_in_place(
 	/* FIXME: in a mixed tree, all records may not have enough ordering
 	fields for btr search: */
 
-	was_delete_marked = rec_get_deleted_flag(rec, index->table->comp);
+	was_delete_marked = rec_get_deleted_flag(rec,
+				page_is_comp(buf_block_get_frame(block)));
 
 	row_upd_rec_in_place(rec, offsets, update);
 
@@ -1491,14 +1496,15 @@ btr_cur_update_in_place(
 
 	btr_cur_update_in_place_log(flags, rec, index, update, trx, roll_ptr,
 									mtr);
-	if (was_delete_marked && !rec_get_deleted_flag(rec, index->table->comp)) {
+	if (was_delete_marked && !rec_get_deleted_flag(rec,
+				page_is_comp(buf_block_get_frame(block)))) {
 		/* The new updated record owns its possible externally
 		stored fields */
 
 		btr_cur_unmark_extern_fields(rec, mtr, offsets);
 	}
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	return(DB_SUCCESS);
@@ -1547,14 +1553,17 @@ btr_cur_optimistic_update(
 	page = btr_cur_get_page(cursor);
 	rec = btr_cur_get_rec(cursor);
 	index = cursor->index;
+	ut_ad(!!page_rec_is_comp(rec) == index->table->comp);
 	
 	heap = mem_heap_create(1024);
 	offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
 
+#ifdef UNIV_DEBUG
 	if (btr_cur_print_record_ops && thr) {
 		btr_cur_trx_report(thr_get_trx(thr), index, "update ");
 		rec_print_new(stderr, rec, offsets);
 	}
+#endif /* UNIV_DEBUG */
 
 	ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
 							MTR_MEMO_PAGE_X_FIX));
@@ -1596,8 +1605,8 @@ btr_cur_optimistic_update(
 	old_rec_size = rec_offs_size(offsets);
 	new_rec_size = rec_get_converted_size(index, new_entry);
 	
-	if (new_rec_size >=
-			page_get_free_space_of_empty(index->table->comp) / 2) {
+	if (UNIV_UNLIKELY(new_rec_size >= page_get_free_space_of_empty(
+				page_is_comp(page)) / 2)) {
 
 		mem_heap_free(heap);		
 
@@ -1607,8 +1616,9 @@ btr_cur_optimistic_update(
 	max_size = old_rec_size
 			+ page_get_max_insert_size_after_reorganize(page, 1);
 
-	if (page_get_data_size(page) - old_rec_size + new_rec_size
-					< BTR_CUR_PAGE_COMPRESS_LIMIT) {
+	if (UNIV_UNLIKELY(page_get_data_size(page)
+					- old_rec_size + new_rec_size
+					< BTR_CUR_PAGE_COMPRESS_LIMIT)) {
 
 		/* The page would become too empty */
 
@@ -1644,7 +1654,7 @@ btr_cur_optimistic_update(
 	explicit locks on rec, before deleting rec (see the comment in
 	.._pessimistic_update). */
 
-	lock_rec_store_on_page_infimum(rec);
+	lock_rec_store_on_page_infimum(page, rec);
 
 	btr_search_update_hash_on_delete(cursor);
 
@@ -1665,7 +1675,7 @@ btr_cur_optimistic_update(
 
 	ut_a(rec); /* <- We calculated above the insert would fit */
 
-	if (!rec_get_deleted_flag(rec, index->table->comp)) {
+	if (!rec_get_deleted_flag(rec, page_is_comp(page))) {
 		/* The new inserted record owns its possible externally
 		stored fields */
 
@@ -1814,7 +1824,7 @@ btr_cur_pessimistic_update(
 		}
 		
 		success = fsp_reserve_free_extents(&n_reserved,
-						cursor->index->space,
+						index->space,
 						n_extents, reserve_flag, mtr);
 		if (!success) {
 			err = DB_OUT_OF_FILE_SPACE;
@@ -1858,14 +1868,14 @@ btr_cur_pessimistic_update(
 
 	ext_vect = mem_heap_alloc(heap, sizeof(ulint)
 					* dict_index_get_n_fields(index));
-	ut_ad(!cursor->index->table->comp || !rec_get_node_ptr_flag(rec));
+	ut_ad(!page_is_comp(page) || !rec_get_node_ptr_flag(rec));
 	offsets = rec_get_offsets(rec, index, offsets,
 					ULINT_UNDEFINED, &heap);
 	n_ext_vect = btr_push_update_extern_fields(ext_vect, offsets, update);
 
-	if (rec_get_converted_size(index, new_entry) >=
-		ut_min(page_get_free_space_of_empty(index->table->comp) / 2,
-		REC_MAX_DATA_SIZE)) {
+	if (UNIV_UNLIKELY(rec_get_converted_size(index, new_entry) >=
+		ut_min(page_get_free_space_of_empty(page_is_comp(page)) / 2,
+		REC_MAX_DATA_SIZE))) {
 
                 big_rec_vec = dtuple_convert_big_rec(index, new_entry,
                 					ext_vect, n_ext_vect);
@@ -1887,7 +1897,7 @@ btr_cur_pessimistic_update(
 	delete the lock structs set on the root page even if the root
 	page carries just node pointers. */
 
-	lock_rec_store_on_page_infimum(rec);
+	lock_rec_store_on_page_infimum(buf_frame_align(rec), rec);
 
 	btr_search_update_hash_on_delete(cursor);
 
@@ -1965,8 +1975,7 @@ return_after_reservations:
 	mem_heap_free(heap);
 
 	if (n_extents > 0) {
-		fil_space_release_free_extents(cursor->index->space,
-							n_reserved);
+		fil_space_release_free_extents(index->space, n_reserved);
 	}
 
 	*big_rec = big_rec_vec;
@@ -1995,7 +2004,10 @@ btr_cur_del_mark_set_clust_rec_log(
 	ut_ad(flags < 256);
 	ut_ad(val <= 1);
 
-	log_ptr = mlog_open_and_write_index(mtr, rec, index, index->table->comp
+	ut_ad(!!page_rec_is_comp(rec) == index->table->comp);
+
+	log_ptr = mlog_open_and_write_index(mtr, rec, index,
+			page_rec_is_comp(rec)
 			? MLOG_COMP_REC_CLUST_DELETE_MARK
 			: MLOG_REC_CLUST_DELETE_MARK,
 			1 + 1 + DATA_ROLL_PTR_LEN + 14 + 2);
@@ -2012,7 +2024,7 @@ btr_cur_del_mark_set_clust_rec_log(
 
 	log_ptr = row_upd_write_sys_vals_to_log(index, trx, roll_ptr, log_ptr,
 									mtr);
-	mach_write_to_2(log_ptr, rec - buf_frame_align(rec));
+	mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));
 	log_ptr += 2;
 
 	mlog_close(mtr, log_ptr);
@@ -2032,13 +2044,15 @@ btr_cur_parse_del_mark_set_clust_rec(
 	page_t*		page)	/* in: page or NULL */
 {
 	ulint	flags;
-	ibool	val;
+	ulint	val;
 	ulint	pos;
 	dulint	trx_id;
 	dulint	roll_ptr;
 	ulint	offset;
 	rec_t*	rec;
 
+	ut_ad(!page || !!page_is_comp(page) == index->table->comp);
+
 	if (end_ptr < ptr + 2) {
 
 		return(NULL);
@@ -2078,7 +2092,7 @@ btr_cur_parse_del_mark_set_clust_rec(
 					rec_get_offsets(rec, index, offsets_,
 					ULINT_UNDEFINED, &heap),
 					pos, trx_id, roll_ptr);
-			if (heap) {
+			if (UNIV_LIKELY_NULL(heap)) {
 				mem_heap_free(heap);
 			}
 		}
@@ -2087,7 +2101,7 @@ btr_cur_parse_del_mark_set_clust_rec(
 		is only being recovered, and there cannot be a hash index to
 		it. */
 
-		rec_set_deleted_flag(rec, index->table->comp, val);
+		rec_set_deleted_flag(rec, page_is_comp(page), val);
 	}
 	
 	return(ptr);
@@ -2123,22 +2137,25 @@ btr_cur_del_mark_set_clust_rec(
 
 	rec = btr_cur_get_rec(cursor);
 	index = cursor->index;
+	ut_ad(!!page_rec_is_comp(rec) == index->table->comp);
 	offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
 
+#ifdef UNIV_DEBUG
 	if (btr_cur_print_record_ops && thr) {
 		btr_cur_trx_report(thr_get_trx(thr), index, "del mark ");
 		rec_print_new(stderr, rec, offsets);
 	}
+#endif /* UNIV_DEBUG */
 
 	ut_ad(index->type & DICT_CLUSTERED);
-	ut_ad(rec_get_deleted_flag(rec, index->table->comp) == FALSE);
+	ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
 
 	err = lock_clust_rec_modify_check_and_lock(flags,
 						rec, index, offsets, thr);
 
 	if (err != DB_SUCCESS) {
 
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 		return(err);
@@ -2149,7 +2166,7 @@ btr_cur_del_mark_set_clust_rec(
 						&roll_ptr);
 	if (err != DB_SUCCESS) {
 
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 		return(err);
@@ -2161,7 +2178,7 @@ btr_cur_del_mark_set_clust_rec(
 		rw_lock_x_lock(&btr_search_latch);
 	}
 
-	rec_set_deleted_flag(rec, index->table->comp, val);
+	rec_set_deleted_flag(rec, rec_offs_comp(offsets), val);
 
 	trx = thr_get_trx(thr);
 	
@@ -2175,7 +2192,7 @@ btr_cur_del_mark_set_clust_rec(
 
 	btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx,
 							roll_ptr, mtr);
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	return(DB_SUCCESS);
@@ -2189,17 +2206,13 @@ void
 btr_cur_del_mark_set_sec_rec_log(
 /*=============================*/
 	rec_t*		rec,	/* in: record */
-	dict_index_t*	index,	/* in: record descriptor */
 	ibool		val,	/* in: value to set */
 	mtr_t*		mtr)	/* in: mtr */
 {
 	byte*	log_ptr;
 	ut_ad(val <= 1);
 
-	log_ptr = mlog_open_and_write_index(mtr, rec, index, index->table->comp
-			? MLOG_COMP_REC_SEC_DELETE_MARK
-			: MLOG_REC_SEC_DELETE_MARK,
-			1 + 2);
+	log_ptr = mlog_open(mtr, 11 + 1 + 2);
 
 	if (!log_ptr) {
 		/* Logging in mtr is switched off during crash recovery:
@@ -2207,10 +2220,12 @@ btr_cur_del_mark_set_sec_rec_log(
 		return;
 	}
 
+	log_ptr = mlog_write_initial_log_record_fast(
+			rec, MLOG_REC_SEC_DELETE_MARK, log_ptr, mtr);
 	mach_write_to_1(log_ptr, val);
 	log_ptr++;
 
-	mach_write_to_2(log_ptr, rec - buf_frame_align(rec));
+	mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));
 	log_ptr += 2;
 
 	mlog_close(mtr, log_ptr);
@@ -2226,10 +2241,9 @@ btr_cur_parse_del_mark_set_sec_rec(
 				/* out: end of log record or NULL */
 	byte*		ptr,	/* in: buffer */
 	byte*		end_ptr,/* in: buffer end */
-	dict_index_t*	index,	/* in: record descriptor */
 	page_t*		page)	/* in: page or NULL */
 {
-	ibool	val;
+	ulint	val;
 	ulint	offset;
 	rec_t*	rec;
 
@@ -2253,7 +2267,7 @@ btr_cur_parse_del_mark_set_sec_rec(
 		is only being recovered, and there cannot be a hash index to
 		it. */
 
-		rec_set_deleted_flag(rec, index->table->comp, val);
+		rec_set_deleted_flag(rec, page_is_comp(page), val);
 	}
 	
 	return(ptr);
@@ -2279,11 +2293,13 @@ btr_cur_del_mark_set_sec_rec(
 
 	rec = btr_cur_get_rec(cursor);
 
+#ifdef UNIV_DEBUG
 	if (btr_cur_print_record_ops && thr) {
 		btr_cur_trx_report(thr_get_trx(thr), cursor->index,
 				"del mark ");
 		rec_print(stderr, rec, cursor->index);
 	}
+#endif /* UNIV_DEBUG */
 
 	err = lock_sec_rec_modify_check_and_lock(flags, rec, cursor->index,
 									thr);
@@ -2293,18 +2309,21 @@ btr_cur_del_mark_set_sec_rec(
 	}
 
 	block = buf_block_align(rec);
+	ut_ad(!!page_is_comp(buf_block_get_frame(block))
+			== cursor->index->table->comp);
 	
 	if (block->is_hashed) {
 		rw_lock_x_lock(&btr_search_latch);
 	}
 
-	rec_set_deleted_flag(rec, cursor->index->table->comp, val);
+	rec_set_deleted_flag(rec, page_is_comp(buf_block_get_frame(block)),
+									val);
 
 	if (block->is_hashed) {
 		rw_lock_x_unlock(&btr_search_latch);
 	}
 
-	btr_cur_del_mark_set_sec_rec_log(rec, cursor->index, val, mtr);
+	btr_cur_del_mark_set_sec_rec_log(rec, val, mtr);
 
 	return(DB_SUCCESS);
 }
@@ -2317,15 +2336,14 @@ void
 btr_cur_del_unmark_for_ibuf(
 /*========================*/
 	rec_t*		rec,	/* in: record to delete unmark */
-	dict_index_t*	index,	/* in: record descriptor */
 	mtr_t*		mtr)	/* in: mtr */
 {
 	/* We do not need to reserve btr_search_latch, as the page has just
 	been read to the buffer pool and there cannot be a hash index to it. */
 
-	rec_set_deleted_flag(rec, index->table->comp, FALSE);
+	rec_set_deleted_flag(rec, page_is_comp(buf_frame_align(rec)), FALSE);
 
-	btr_cur_del_mark_set_sec_rec_log(rec, index, FALSE, mtr);
+	btr_cur_del_mark_set_sec_rec_log(rec, FALSE, mtr);
 }
 
 /*==================== B-TREE RECORD REMOVE =========================*/
@@ -2444,7 +2462,7 @@ btr_cur_optimistic_delete(
 									mtr);
 	}
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 
@@ -2487,6 +2505,7 @@ btr_cur_pessimistic_delete(
 	ulint		n_reserved;
 	ibool		success;
 	ibool		ret		= FALSE;
+	ulint		level;
 	mem_heap_t*	heap;
 	ulint*		offsets;
 	
@@ -2523,15 +2542,15 @@ btr_cur_pessimistic_delete(
 	/* Free externally stored fields if the record is neither
 	a node pointer nor in two-byte format.
 	This avoids an unnecessary loop. */
-	if (cursor->index->table->comp
+	if (page_is_comp(page)
 			? !rec_get_node_ptr_flag(rec)
 			: !rec_get_1byte_offs_flag(rec)) {
 		btr_rec_free_externally_stored_fields(cursor->index,
 					rec, offsets, in_rollback, mtr);
 	}
 
-	if ((page_get_n_recs(page) < 2)
-	    && (dict_tree_get_page(btr_cur_get_tree(cursor))
+	if (UNIV_UNLIKELY(page_get_n_recs(page) < 2)
+	    && UNIV_UNLIKELY(dict_tree_get_page(btr_cur_get_tree(cursor))
 					!= buf_frame_get_page_no(page))) {
 
 		/* If there is only one record, drop the whole page in
@@ -2546,9 +2565,13 @@ btr_cur_pessimistic_delete(
 	}
 
 	lock_update_delete(rec);
+	level = btr_page_get_level(page, mtr);
 
-	if ((btr_page_get_level(page, mtr) > 0)
-	    && (page_rec_get_next(page_get_infimum_rec(page)) == rec)) {
+	if (level > 0
+	    && UNIV_UNLIKELY(rec == page_rec_get_next(
+				page_get_infimum_rec(page)))) {
+
+		rec_t*	next_rec = page_rec_get_next(rec);
 
 		if (btr_page_get_prev(page, mtr) == FIL_NULL) {
 
@@ -2556,8 +2579,8 @@ btr_cur_pessimistic_delete(
 			non-leaf level, we must mark the new leftmost node
 			pointer as the predefined minimum record */
 
-			btr_set_min_rec_mark(page_rec_get_next(rec),
-					cursor->index->table->comp, mtr);
+			btr_set_min_rec_mark(next_rec, page_is_comp(page),
+						mtr);
 		} else {
 			/* Otherwise, if we delete the leftmost node pointer
 			on a page, we have to change the father node pointer
@@ -2567,13 +2590,12 @@ btr_cur_pessimistic_delete(
 			btr_node_ptr_delete(tree, page, mtr);
 
 			node_ptr = dict_tree_build_node_ptr(
-					tree, page_rec_get_next(rec),
+					tree, next_rec,
 					buf_frame_get_page_no(page),
-       					heap, btr_page_get_level(page, mtr));
+						heap, level);
 
 			btr_insert_on_non_leaf_level(tree,
-					btr_page_get_level(page, mtr) + 1,
-					node_ptr, mtr);
+					level + 1, node_ptr, mtr);
 		}
 	} 
 
@@ -2813,12 +2835,13 @@ btr_estimate_number_of_different_key_vals(
 	ulint		add_on;
 	mtr_t		mtr;
 	mem_heap_t*	heap		= NULL;
-	ulint		offsets1_[REC_OFFS_NORMAL_SIZE];
-	ulint		offsets2_[REC_OFFS_NORMAL_SIZE];
-	ulint*		offsets1	= offsets1_;
-	ulint*		offsets2	= offsets2_;
-	*offsets1_ = (sizeof offsets1_) / sizeof *offsets1_;
-	*offsets2_ = (sizeof offsets2_) / sizeof *offsets2_;
+	ulint		offsets_rec_[REC_OFFS_NORMAL_SIZE];
+	ulint		offsets_next_rec_[REC_OFFS_NORMAL_SIZE];
+	ulint*		offsets_rec	= offsets_rec_;
+	ulint*		offsets_next_rec= offsets_next_rec_;
+	*offsets_rec_ = (sizeof offsets_rec_) / sizeof *offsets_rec_;
+	*offsets_next_rec_ =
+			(sizeof offsets_next_rec_) / sizeof *offsets_next_rec_;
 
 	n_cols = dict_index_get_n_unique(index);
 
@@ -2831,6 +2854,7 @@ btr_estimate_number_of_different_key_vals(
 	/* We sample some pages in the index to get an estimate */
 	
 	for (i = 0; i < BTR_KEY_VAL_ESTIMATE_N_PAGES; i++) {
+		rec_t*	supremum;
 		mtr_start(&mtr);
 
 		btr_cur_open_at_rnd_pos(index, BTR_SEARCH_LEAF, &cursor, &mtr);
@@ -2843,26 +2867,29 @@ btr_estimate_number_of_different_key_vals(
 
 		page = btr_cur_get_page(&cursor);
 
-		rec = page_get_infimum_rec(page);
-		rec = page_rec_get_next(rec);
+		supremum = page_get_supremum_rec(page);
+		rec = page_rec_get_next(page_get_infimum_rec(page));
 
-		if (rec != page_get_supremum_rec(page)) {
+		if (rec != supremum) {
 			not_empty_flag = 1;
+			offsets_rec = rec_get_offsets(rec, index, offsets_rec,
+						ULINT_UNDEFINED, &heap);
 		}
-		
-		while (rec != page_get_supremum_rec(page)
-		       && page_rec_get_next(rec)
-					!= page_get_supremum_rec(page)) {
+
+		while (rec != supremum) {
 			rec_t*	next_rec = page_rec_get_next(rec);
+			if (next_rec == supremum) {
+				break;
+			}
+
 			matched_fields = 0;
 			matched_bytes = 0;
-			offsets1 = rec_get_offsets(rec, index, offsets1,
-						ULINT_UNDEFINED, &heap);
-			offsets2 = rec_get_offsets(next_rec, index, offsets2,
+			offsets_next_rec = rec_get_offsets(next_rec, index,
+						offsets_next_rec,
 						n_cols, &heap);
 
 			cmp_rec_rec_with_match(rec, next_rec,
-						offsets1, offsets2,
+						offsets_rec, offsets_next_rec,
 						index, &matched_fields,
 						&matched_bytes);
 
@@ -2875,9 +2902,17 @@ btr_estimate_number_of_different_key_vals(
 
 			total_external_size +=
 				btr_rec_get_externally_stored_len(
-								rec, offsets1);
+								rec, offsets_rec);
 			
-			rec = page_rec_get_next(rec);
+			rec = next_rec;
+			/* Initialize offsets_rec for the next round
+			and assign the old offsets_rec buffer to
+			offsets_next_rec. */
+			{
+				ulint*	offsets_tmp = offsets_rec;
+				offsets_rec = offsets_next_rec;
+				offsets_next_rec = offsets_tmp;
+			}
 		}
 		
 
@@ -2899,11 +2934,11 @@ btr_estimate_number_of_different_key_vals(
 			}
 		}
 
-		offsets1 = rec_get_offsets(rec, index, offsets1,
+		offsets_rec = rec_get_offsets(rec, index, offsets_rec,
 						ULINT_UNDEFINED, &heap);
 		total_external_size +=
 				btr_rec_get_externally_stored_len(rec,
-								offsets1);
+								offsets_rec);
 		mtr_commit(&mtr);
 	}
 
@@ -2944,7 +2979,7 @@ btr_estimate_number_of_different_key_vals(
 	}
 		
 	mem_free(n_diff);
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 }
@@ -3599,7 +3634,7 @@ btr_rec_free_externally_stored_fields(
 							MTR_MEMO_PAGE_X_FIX));
 	/* Free possible externally stored fields in the record */
 
-	ut_ad(index->table->comp == rec_offs_comp(offsets));
+	ut_ad(index->table->comp == !!rec_offs_comp(offsets));
 	n_fields = rec_offs_n_fields(offsets);
 
 	for (i = 0; i < n_fields; i++) {
diff --git a/innobase/btr/btr0pcur.c b/innobase/btr/btr0pcur.c
index 74feff8653cd079309aaa63562d654d6077b199c..cb398b4afab77c434e1f298fef3efaef73b8e3d2 100644
--- a/innobase/btr/btr0pcur.c
+++ b/innobase/btr/btr0pcur.c
@@ -78,6 +78,7 @@ btr_pcur_store_position(
 	rec_t*		rec;
 	dict_tree_t*	tree;
 	page_t*		page;
+	ulint		offs;
 	
 	ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
 	ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
@@ -87,7 +88,8 @@ btr_pcur_store_position(
 	page_cursor = btr_pcur_get_page_cur(cursor);
 
 	rec = page_cur_get_rec(page_cursor);
-	page = buf_frame_align(rec);
+	page = ut_align_down(rec, UNIV_PAGE_SIZE);
+	offs = ut_align_offset(rec, UNIV_PAGE_SIZE);
 
 	ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
 							MTR_MEMO_PAGE_S_FIX)
@@ -95,35 +97,33 @@ btr_pcur_store_position(
 							MTR_MEMO_PAGE_X_FIX));
 	ut_a(cursor->latch_mode != BTR_NO_LATCHES);
 
-	if (page_get_n_recs(page) == 0) {
+	if (UNIV_UNLIKELY(page_get_n_recs(page) == 0)) {
 		/* It must be an empty index tree; NOTE that in this case
 		we do not store the modify_clock, but always do a search
 		if we restore the cursor position */
 
-		ut_a(btr_page_get_next(page, mtr) == FIL_NULL
-		     && btr_page_get_prev(page, mtr) == FIL_NULL);
+		ut_a(btr_page_get_next(page, mtr) == FIL_NULL);
+		ut_a(btr_page_get_prev(page, mtr) == FIL_NULL);
 
-		if (rec == page_get_supremum_rec(page)) {
+		cursor->old_stored = BTR_PCUR_OLD_STORED;
 
-			cursor->rel_pos = BTR_PCUR_AFTER_LAST_IN_TREE;
-			cursor->old_stored = BTR_PCUR_OLD_STORED;
+		if (page_rec_is_supremum_low(offs)) {
 
-			return;
+			cursor->rel_pos = BTR_PCUR_AFTER_LAST_IN_TREE;
+		} else {
+			cursor->rel_pos = BTR_PCUR_BEFORE_FIRST_IN_TREE;
 		}
 
-		cursor->rel_pos = BTR_PCUR_BEFORE_FIRST_IN_TREE;
-		cursor->old_stored = BTR_PCUR_OLD_STORED;
-
 		return;
 	} 
 
-	if (rec == page_get_supremum_rec(page)) {
+	if (page_rec_is_supremum_low(offs)) {
 
 		rec = page_rec_get_prev(rec);
 
 		cursor->rel_pos = BTR_PCUR_AFTER;
 
-	} else if (rec == page_get_infimum_rec(page)) {
+	} else if (page_rec_is_infimum_low(offs)) {
 
 		rec = page_rec_get_next(rec);
 
@@ -139,7 +139,8 @@ btr_pcur_store_position(
 						&cursor->buf_size);
 
 	cursor->block_when_stored = buf_block_align(page);	
-	cursor->modify_clock = buf_frame_get_modify_clock(page);
+	cursor->modify_clock = buf_block_get_modify_clock(
+				cursor->block_when_stored);
 }
 
 /******************************************************************
@@ -202,33 +203,27 @@ btr_pcur_restore_position(
 	dtuple_t*	tuple;
 	ulint		mode;
 	ulint		old_mode;
-	ibool		from_left;
 	mem_heap_t*	heap;
 
-	ut_a(cursor->pos_state == BTR_PCUR_WAS_POSITIONED
-			|| cursor->pos_state == BTR_PCUR_IS_POSITIONED);
-	if (cursor->old_stored != BTR_PCUR_OLD_STORED) {
+	if (UNIV_UNLIKELY(cursor->old_stored != BTR_PCUR_OLD_STORED)
+	    || UNIV_UNLIKELY(cursor->pos_state != BTR_PCUR_WAS_POSITIONED
+			     && cursor->pos_state != BTR_PCUR_IS_POSITIONED)) {
 		ut_print_buf(stderr, (const byte*)cursor, sizeof(btr_pcur_t));
 		if (cursor->trx_if_known) {
 			trx_print(stderr, cursor->trx_if_known);
 		}
 		
-		ut_a(0);
+		ut_error;
 	}
 
-	if (cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
-	    || cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE) {
+	if (UNIV_UNLIKELY(cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
+			|| cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE)) {
 
 	    	/* In these cases we do not try an optimistic restoration,
 	    	but always do a search */
 
-	    	if (cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE) {
-	    		from_left = TRUE;
-	    	} else {
-	    		from_left = FALSE;
-	    	}
-
-		btr_cur_open_at_index_side(from_left,
+		btr_cur_open_at_index_side(
+			cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE,
 			btr_pcur_get_btr_cur(cursor)->index, latch_mode,
 					btr_pcur_get_btr_cur(cursor), mtr);
 
@@ -243,12 +238,13 @@ btr_pcur_restore_position(
 
 	page = btr_cur_get_page(btr_pcur_get_btr_cur(cursor));
 
-	if (latch_mode == BTR_SEARCH_LEAF || latch_mode == BTR_MODIFY_LEAF) {
+	if (UNIV_LIKELY(latch_mode == BTR_SEARCH_LEAF)
+			|| UNIV_LIKELY(latch_mode == BTR_MODIFY_LEAF)) {
 		/* Try optimistic restoration */
 	    
-		if (buf_page_optimistic_get(latch_mode,
+		if (UNIV_LIKELY(buf_page_optimistic_get(latch_mode,
 					    cursor->block_when_stored, page,
-					    cursor->modify_clock, mtr)) {
+					    cursor->modify_clock, mtr))) {
 			cursor->pos_state = BTR_PCUR_IS_POSITIONED;
 #ifdef UNIV_SYNC_DEBUG
 			buf_page_dbg_add_level(page, SYNC_TREE_NODE);
@@ -297,7 +293,7 @@ btr_pcur_restore_position(
 	/* Save the old search mode of the cursor */
 	old_mode = cursor->search_mode;
 	
-	if (cursor->rel_pos == BTR_PCUR_ON) {
+	if (UNIV_LIKELY(cursor->rel_pos == BTR_PCUR_ON)) {
 		mode = PAGE_CUR_LE;
 	} else if (cursor->rel_pos == BTR_PCUR_AFTER) {
 		mode = PAGE_CUR_G;
@@ -323,12 +319,10 @@ btr_pcur_restore_position(
 		the cursor can now be on a different page! But we can retain
 		the value of old_rec */
 
-		cursor->modify_clock =
-			buf_frame_get_modify_clock(btr_pcur_get_page(cursor));
-
 		cursor->block_when_stored =
 			buf_block_align(btr_pcur_get_page(cursor));
-
+		cursor->modify_clock =
+			buf_block_get_modify_clock(cursor->block_when_stored);
 		cursor->old_stored = BTR_PCUR_OLD_STORED;
 
 		mem_heap_free(heap);
diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c
index 97fdce2df7549ac953089e56ca91c7dde044c022..f705fee4275e9569300c701285ba15c859479404 100644
--- a/innobase/btr/btr0sea.c
+++ b/innobase/btr/btr0sea.c
@@ -435,7 +435,7 @@ btr_search_update_hash_ref(
 				offsets_, ULINT_UNDEFINED, &heap),
 				block->curr_n_fields,
 				block->curr_n_bytes, tree_id);
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 #ifdef UNIV_SYNC_DEBUG
@@ -544,10 +544,7 @@ btr_search_check_guess(
 				or PAGE_CUR_GE */
 	mtr_t*		mtr)	/* in: mtr */
 {
-	page_t*		page;
 	rec_t*		rec;
-	rec_t*		prev_rec;
-	rec_t*		next_rec;
 	ulint		n_unique;
 	ulint		match;
 	ulint		bytes;
@@ -561,7 +558,6 @@ btr_search_check_guess(
 	n_unique = dict_index_get_n_unique_in_tree(cursor->index);
 	
 	rec = btr_cur_get_rec(cursor);
-	page = buf_frame_align(rec);
 
 	ut_ad(page_rec_is_user_rec(rec));
 
@@ -611,13 +607,16 @@ btr_search_check_guess(
 	bytes = 0;
 
 	if ((mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE)) {
+		rec_t*	prev_rec;
 
-		ut_ad(rec != page_get_infimum_rec(page));
+		ut_ad(!page_rec_is_infimum(rec));
 		
 		prev_rec = page_rec_get_prev(rec);
 
-		if (prev_rec == page_get_infimum_rec(page)) {
-			success = btr_page_get_prev(page, mtr) == FIL_NULL;
+		if (page_rec_is_infimum(prev_rec)) {
+			success = btr_page_get_prev(
+				buf_frame_align(prev_rec), mtr) == FIL_NULL;
+
 			goto exit_func;
 		}
 
@@ -632,34 +631,37 @@ btr_search_check_guess(
 		}
 
 		goto exit_func;
-	}
-		
-	ut_ad(rec != page_get_supremum_rec(page));
+	} else {
+		rec_t*	next_rec;
+
+		ut_ad(!page_rec_is_supremum(rec));
 	
-	next_rec = page_rec_get_next(rec);
+		next_rec = page_rec_get_next(rec);
 
-	if (next_rec == page_get_supremum_rec(page)) {
-    		if (btr_page_get_next(page, mtr) == FIL_NULL) {
+		if (page_rec_is_supremum(next_rec)) {
+			if (btr_page_get_next(
+				buf_frame_align(next_rec), mtr) == FIL_NULL) {
 
-			cursor->up_match = 0;
-			success = TRUE;
-		}
+				cursor->up_match = 0;
+				success = TRUE;
+			}
 
-		goto exit_func;
-	}
+			goto exit_func;
+		}
 
-	offsets = rec_get_offsets(next_rec, cursor->index, offsets,
+		offsets = rec_get_offsets(next_rec, cursor->index, offsets,
 						n_unique, &heap);
-	cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec,
-					offsets, &match, &bytes);
-	if (mode == PAGE_CUR_LE) {
-		success = cmp == -1;
-		cursor->up_match = match;
-	} else {
-		success = cmp != 1;
+		cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec,
+						offsets, &match, &bytes);
+		if (mode == PAGE_CUR_LE) {
+			success = cmp == -1;
+			cursor->up_match = match;
+		} else {
+			success = cmp != 1;
+		}
 	}
 exit_func:
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	return(success);
@@ -694,7 +696,6 @@ btr_search_guess_on_hash(
 	buf_block_t*	block;
 	rec_t*		rec;
 	page_t*		page;
-	ibool		success;
 	ulint		fold;
 	ulint		tuple_n_fields;
 	dulint		tree_id;
@@ -710,7 +711,7 @@ btr_search_guess_on_hash(
 	/* Note that, for efficiency, the struct info may not be protected by
 	any latch here! */
 
-	if (info->n_hash_potential == 0) {
+	if (UNIV_UNLIKELY(info->n_hash_potential == 0)) {
 
 		return(FALSE);
 	}
@@ -720,12 +721,13 @@ btr_search_guess_on_hash(
 
 	tuple_n_fields = dtuple_get_n_fields(tuple);
 
-	if (tuple_n_fields < cursor->n_fields) {
+	if (UNIV_UNLIKELY(tuple_n_fields < cursor->n_fields)) {
 
 		return(FALSE);
 	}
 
-	if ((cursor->n_bytes > 0) && (tuple_n_fields <= cursor->n_fields)) {
+	if (UNIV_UNLIKELY(tuple_n_fields == cursor->n_fields)
+			&& (cursor->n_bytes > 0)) {
 
 	    	return(FALSE);
 	}
@@ -740,39 +742,31 @@ btr_search_guess_on_hash(
 	cursor->fold = fold;
 	cursor->flag = BTR_CUR_HASH;
 	
-	if (!has_search_latch) {
+	if (UNIV_LIKELY(!has_search_latch)) {
 		rw_lock_s_lock(&btr_search_latch);
 	}
 
-	ut_a(btr_search_latch.writer != RW_LOCK_EX);
-	ut_a(btr_search_latch.reader_count > 0);
+	ut_ad(btr_search_latch.writer != RW_LOCK_EX);
+	ut_ad(btr_search_latch.reader_count > 0);
 
 	rec = ha_search_and_get_data(btr_search_sys->hash_index, fold);
 
-	if (!rec) {
-		if (!has_search_latch) {
-			rw_lock_s_unlock(&btr_search_latch);
-		}
-		
-		goto failure;
+	if (UNIV_UNLIKELY(!rec)) {
+		goto failure_unlock;
 	}
 
 	page = buf_frame_align(rec);
 
-	if (!has_search_latch) {
+	if (UNIV_LIKELY(!has_search_latch)) {
 
-		success = buf_page_get_known_nowait(latch_mode, page,
+		if (UNIV_UNLIKELY(!buf_page_get_known_nowait(latch_mode, page,
 						BUF_MAKE_YOUNG,
 						__FILE__, __LINE__,
-						mtr);
-
-		rw_lock_s_unlock(&btr_search_latch);
-
-		if (!success) {
-
-			goto failure;
+						mtr))) {
+			goto failure_unlock;
 		}
 
+		rw_lock_s_unlock(&btr_search_latch);
 		can_only_compare_to_cursor_rec = FALSE;
 
 #ifdef UNIV_SYNC_DEBUG
@@ -782,8 +776,8 @@ btr_search_guess_on_hash(
 
 	block = buf_block_align(page);
 
-	if (block->state == BUF_BLOCK_REMOVE_HASH) {
-		if (!has_search_latch) {
+	if (UNIV_UNLIKELY(block->state == BUF_BLOCK_REMOVE_HASH)) {
+		if (UNIV_LIKELY(!has_search_latch)) {
 	
 			btr_leaf_page_release(page, latch_mode, mtr);
 		}
@@ -791,51 +785,33 @@ btr_search_guess_on_hash(
 		goto failure;
 	}
 
-	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
-	ut_a(page_rec_is_user_rec(rec));	
+	ut_ad(block->state == BUF_BLOCK_FILE_PAGE);
+	ut_ad(page_rec_is_user_rec(rec));
 
 	btr_cur_position(index, rec, cursor);
 
 	/* Check the validity of the guess within the page */
 
-	if (0 != ut_dulint_cmp(tree_id, btr_page_get_index_id(page))) {
-
-		success = FALSE;
-/*
-		fprintf(stderr, "Tree id %lu, page index id %lu fold %lu\n",
-				ut_dulint_get_low(tree_id),
-				ut_dulint_get_low(btr_page_get_index_id(page)),
-				fold);
-*/				
-	} else {
-	        /* If we only have the latch on btr_search_latch, not on the
-		page, it only protects the columns of the record the cursor
-		is positioned on. We cannot look at the next of the previous
-		record to determine if our guess for the cursor position is
-		right. */
-
-		success = btr_search_check_guess(cursor,
-				               can_only_compare_to_cursor_rec,
-					       tuple, mode, mtr);
-	}
-	
-	if (!success) {
-		if (!has_search_latch) {
+	/* If we only have the latch on btr_search_latch, not on the
+	page, it only protects the columns of the record the cursor
+	is positioned on. We cannot look at the next of the previous
+	record to determine if our guess for the cursor position is
+	right. */
+	if (UNIV_EXPECT(ut_dulint_cmp(tree_id, btr_page_get_index_id(page)), 0)
+	    || !btr_search_check_guess(cursor, can_only_compare_to_cursor_rec,
+					       tuple, mode, mtr)) {
+		if (UNIV_LIKELY(!has_search_latch)) {
 		          btr_leaf_page_release(page, latch_mode, mtr);
 		}
 
 		goto failure;
 	}
 
-	if (info->n_hash_potential < BTR_SEARCH_BUILD_LIMIT + 5) {
+	if (UNIV_LIKELY(info->n_hash_potential < BTR_SEARCH_BUILD_LIMIT + 5)) {
 	
 		info->n_hash_potential++;
 	}
 
-	if (info->last_hash_succ != TRUE) {
-		info->last_hash_succ = TRUE;
-	}
-	
 #ifdef notdefined
 	/* These lines of code can be used in a debug version to check
 	the correctness of the searched cursor position: */
@@ -843,15 +819,14 @@ btr_search_guess_on_hash(
 	info->last_hash_succ = FALSE;
 
 	/* Currently, does not work if the following fails: */
-	ut_a(!has_search_latch);
+	ut_ad(!has_search_latch);
 	
 	btr_leaf_page_release(page, latch_mode, mtr);
 
 	btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode,
 							&cursor2, 0, mtr);
 	if (mode == PAGE_CUR_GE
-		&& btr_cur_get_rec(&cursor2) == page_get_supremum_rec(
-			buf_frame_align(btr_cur_get_rec(&cursor2)))) {
+		&& page_rec_is_supremum(btr_cur_get_rec(&cursor2))) {
 
 		/* If mode is PAGE_CUR_GE, then the binary search
 		in the index tree may actually take us to the supremum
@@ -861,22 +836,22 @@ btr_search_guess_on_hash(
 
 		btr_pcur_open_on_user_rec(index, tuple, mode, latch_mode,
 				&pcur, mtr);
-		ut_a(btr_pcur_get_rec(&pcur) == btr_cur_get_rec(cursor));
+		ut_ad(btr_pcur_get_rec(&pcur) == btr_cur_get_rec(cursor));
 	} else {
-		ut_a(btr_cur_get_rec(&cursor2) == btr_cur_get_rec(cursor));
+		ut_ad(btr_cur_get_rec(&cursor2) == btr_cur_get_rec(cursor));
 	}
 
 	/* NOTE that it is theoretically possible that the above assertions
 	fail if the page of the cursor gets removed from the buffer pool
 	meanwhile! Thus it might not be a bug. */
-
-	info->last_hash_succ = TRUE;
 #endif
+	info->last_hash_succ = TRUE;
 
 #ifdef UNIV_SEARCH_PERF_STAT
 	btr_search_n_succ++;
 #endif
-	if (!has_search_latch && buf_block_peek_if_too_old(block)) {
+	if (UNIV_LIKELY(!has_search_latch)
+			&& buf_block_peek_if_too_old(block)) {
 
 		buf_page_make_young(page);
 	}	
@@ -889,6 +864,10 @@ btr_search_guess_on_hash(
 	return(TRUE);	
 
 	/*-------------------------------------------*/
+failure_unlock:
+	if (UNIV_LIKELY(!has_search_latch)) {
+		rw_lock_s_unlock(&btr_search_latch);
+	}
 failure:
 	info->n_hash_fail++;
 
@@ -917,7 +896,6 @@ btr_search_drop_page_hash_index(
 	ulint		n_fields;
 	ulint		n_bytes;
 	rec_t*		rec;
-	rec_t*		sup;
 	ulint		fold;
 	ulint		prev_fold;
 	dulint		tree_id;
@@ -968,12 +946,10 @@ btr_search_drop_page_hash_index(
 
 	n_cached = 0;
 
-	sup = page_get_supremum_rec(page);
-
 	rec = page_get_infimum_rec(page);
 	rec = page_rec_get_next(rec);
 
-	if (rec != sup) {
+	if (!page_rec_is_supremum(rec)) {
 		ut_a(n_fields <= rec_get_n_fields(rec, block->index));
 
 		if (n_bytes > 0) {
@@ -988,7 +964,7 @@ btr_search_drop_page_hash_index(
 	heap = NULL;
 	offsets = NULL;
 
-	while (rec != sup) {
+	while (!page_rec_is_supremum(rec)) {
 		/* FIXME: in a mixed tree, not all records may have enough
 		ordering fields: */
 		offsets = rec_get_offsets(rec, block->index,
@@ -1010,7 +986,7 @@ next_rec:
 		prev_fold = fold;
 	}
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 
@@ -1090,7 +1066,6 @@ btr_search_build_page_hash_index(
 	buf_block_t*	block;
 	rec_t*		rec;
 	rec_t*		next_rec;
-	rec_t*		sup;
 	ulint		fold;
 	ulint		next_fold;
 	dulint		tree_id;
@@ -1158,15 +1133,13 @@ btr_search_build_page_hash_index(
 
 	tree_id = btr_page_get_index_id(page);
 
-	sup = page_get_supremum_rec(page);
-
 	rec = page_get_infimum_rec(page);
 	rec = page_rec_get_next(rec);
 
 	offsets = rec_get_offsets(rec, index, offsets,
 					n_fields + (n_bytes > 0), &heap);
 
-	if (rec != sup) {
+	if (!page_rec_is_supremum(rec)) {
 		ut_a(n_fields <= rec_offs_n_fields(offsets));
 
 		if (n_bytes > 0) {
@@ -1188,7 +1161,7 @@ btr_search_build_page_hash_index(
 	for (;;) {
 		next_rec = page_rec_get_next(rec);
 
-		if (next_rec == sup) {
+		if (page_rec_is_supremum(next_rec)) {
 
 			if (side == BTR_SEARCH_RIGHT_SIDE) {
 	
@@ -1252,7 +1225,7 @@ exit_func:
 
 	mem_free(folds);
 	mem_free(recs);
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 }
@@ -1370,7 +1343,7 @@ btr_search_update_hash_on_delete(
 	fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, offsets_,
 				ULINT_UNDEFINED, &heap), block->curr_n_fields,
 				block->curr_n_bytes, tree_id);
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	rw_lock_x_lock(&btr_search_latch);
@@ -1443,7 +1416,6 @@ btr_search_update_hash_on_insert(
 {
 	hash_table_t*	table; 
 	buf_block_t*	block;
-	page_t*		page;
 	rec_t*		rec;
 	rec_t*		ins_rec;
 	rec_t*		next_rec;
@@ -1488,19 +1460,18 @@ btr_search_update_hash_on_insert(
 	ins_rec = page_rec_get_next(rec);
 	next_rec = page_rec_get_next(ins_rec);
 
-	page = buf_frame_align(rec);
 	offsets = rec_get_offsets(ins_rec, cursor->index, offsets,
 					ULINT_UNDEFINED, &heap);
 	ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, tree_id);
 
-	if (next_rec != page_get_supremum_rec(page)) {
+	if (!page_rec_is_supremum(next_rec)) {
 		offsets = rec_get_offsets(next_rec, cursor->index, offsets,
 					n_fields + (n_bytes > 0), &heap);
 		next_fold = rec_fold(next_rec, offsets, n_fields,
 							n_bytes, tree_id);
 	}
 
-	if (rec != page_get_infimum_rec(page)) {
+	if (!page_rec_is_infimum(rec)) {
 		offsets = rec_get_offsets(rec, cursor->index, offsets,
 					n_fields + (n_bytes > 0), &heap);
 		fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
@@ -1534,7 +1505,7 @@ btr_search_update_hash_on_insert(
 	}
 
 check_next_rec:
-	if (next_rec == page_get_supremum_rec(page)) {
+	if (page_rec_is_supremum(next_rec)) {
 
 		if (side == BTR_SEARCH_RIGHT_SIDE) {
 
@@ -1573,7 +1544,7 @@ check_next_rec:
 	}	
 		
 function_exit:
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	if (locked) {
@@ -1662,7 +1633,7 @@ btr_search_validate(void)
 	}
 
 	rw_lock_x_unlock(&btr_search_latch);
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 
diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c
index 89f851709dbb37eef6cb69e6b30ec2cb486d4b2c..78189617aabb346f8d54d731b32e70f8ae8280bd 100644
--- a/innobase/buf/buf0buf.c
+++ b/innobase/buf/buf0buf.c
@@ -223,13 +223,14 @@ in the free list to the frames.
 
 buf_pool_t*	buf_pool = NULL; /* The buffer buf_pool of the database */
 
+#ifdef UNIV_DEBUG
 ulint		buf_dbg_counter	= 0; /* This is used to insert validation
 					operations in excution in the
 					debug version */
 ibool		buf_debug_prints = FALSE; /* If this is set TRUE,
 					the program prints info whenever
 					read-ahead or flush occurs */
-
+#endif /* UNIV_DEBUG */
 /************************************************************************
 Calculates a page checksum which is stored to the page when it is written
 to a file. Note that we must be careful to calculate the same value on
@@ -1286,8 +1287,9 @@ buf_page_optimistic_get_func(
 
 	/* If AWE is used, block may have a different frame now, e.g., NULL */
 	
-	if (block->state != BUF_BLOCK_FILE_PAGE || block->frame != guess) {
-
+	if (UNIV_UNLIKELY(block->state != BUF_BLOCK_FILE_PAGE)
+			|| UNIV_UNLIKELY(block->frame != guess)) {
+	exit_func:
 		mutex_exit(&(buf_pool->mutex));
 
 		return(FALSE);
@@ -1320,19 +1322,17 @@ buf_page_optimistic_get_func(
 		fix_type = MTR_MEMO_PAGE_X_FIX;
 	}
 
-	if (!success) {
+	if (UNIV_UNLIKELY(!success)) {
 		mutex_enter(&(buf_pool->mutex));
 		
 		block->buf_fix_count--;
 #ifdef UNIV_SYNC_DEBUG
 		rw_lock_s_unlock(&(block->debug_latch));
-#endif			
-		mutex_exit(&(buf_pool->mutex));
-
-		return(FALSE);
+#endif
+		goto exit_func;
 	}
 
-	if (!UT_DULINT_EQ(modify_clock, block->modify_clock)) {
+	if (UNIV_UNLIKELY(!UT_DULINT_EQ(modify_clock, block->modify_clock))) {
 #ifdef UNIV_SYNC_DEBUG
 		buf_page_dbg_add_level(block->frame, SYNC_NO_ORDER_CHECK);
 #endif /* UNIV_SYNC_DEBUG */
@@ -1347,10 +1347,8 @@ buf_page_optimistic_get_func(
 		block->buf_fix_count--;
 #ifdef UNIV_SYNC_DEBUG
 		rw_lock_s_unlock(&(block->debug_latch));
-#endif			
-		mutex_exit(&(buf_pool->mutex));
-		
-		return(FALSE);
+#endif
+		goto exit_func;
 	}
 
 	mtr_memo_push(mtr, block, fix_type);
@@ -1368,7 +1366,7 @@ buf_page_optimistic_get_func(
 #ifdef UNIV_DEBUG_FILE_ACCESSES
 	ut_a(block->file_page_was_freed == FALSE);
 #endif
-	if (!accessed) {
+	if (UNIV_UNLIKELY(!accessed)) {
 		/* In the case of a first access, try to apply linear
 		read-ahead */
 
@@ -1742,10 +1740,12 @@ buf_page_create(
 
 	/* If we get here, the page was not in buf_pool: init it there */
 
+#ifdef UNIV_DEBUG
 	if (buf_debug_prints) {
 		fprintf(stderr, "Creating space %lu page %lu to buffer\n",
 			(ulong) space, (ulong) offset);
 	}
+#endif /* UNIV_DEBUG */
 
 	block = free_block;
 	
@@ -1896,9 +1896,11 @@ buf_page_io_complete(
 
 		rw_lock_x_unlock_gen(&(block->lock), BUF_IO_READ);
 
+#ifdef UNIV_DEBUG
 		if (buf_debug_prints) {
 			fputs("Has read ", stderr);
 		}
+#endif /* UNIV_DEBUG */
 	} else {
 		ut_ad(io_type == BUF_IO_WRITE);
 
@@ -1911,17 +1913,21 @@ buf_page_io_complete(
 
 		buf_pool->n_pages_written++;
 
+#ifdef UNIV_DEBUG
 		if (buf_debug_prints) {
 			fputs("Has written ", stderr);
 		}
+#endif /* UNIV_DEBUG */
 	}
 	
 	mutex_exit(&(buf_pool->mutex));
 
+#ifdef UNIV_DEBUG
 	if (buf_debug_prints) {
 		fprintf(stderr, "page space %lu page no %lu\n",
 			(ulong) block->space, (ulong) block->offset);
 	}
+#endif /* UNIV_DEBUG */
 }
 
 /*************************************************************************
@@ -1950,6 +1956,7 @@ buf_pool_invalidate(void)
 	mutex_exit(&(buf_pool->mutex));
 }
 
+#ifdef UNIV_DEBUG
 /*************************************************************************
 Validates the buffer buf_pool data structure. */
 
@@ -2149,6 +2156,7 @@ buf_print(void)
 
 	ut_a(buf_validate());
 }	
+#endif /* UNIV_DEBUG */
 
 /*************************************************************************
 Returns the number of latched pages in the buffer pool. */
diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c
index 592ed972376cf462b5e9b6259575a6614183e33f..ffb16790b2d9f7df5933901aca37aa664b750388 100644
--- a/innobase/buf/buf0flu.c
+++ b/innobase/buf/buf0flu.c
@@ -586,11 +586,13 @@ buf_flush_try_page(
 			rw_lock_s_lock_gen(&(block->lock), BUF_IO_WRITE);
 		}
 
+#ifdef UNIV_DEBUG
 		if (buf_debug_prints) {
 			fprintf(stderr,
 				"Flushing page space %lu, page no %lu \n",
 				(ulong) block->space, (ulong) block->offset);
 		}
+#endif /* UNIV_DEBUG */
 
 		buf_flush_write_block_low(block);
 		
@@ -674,12 +676,14 @@ buf_flush_try_page(
 
 		rw_lock_s_lock_gen(&(block->lock), BUF_IO_WRITE);
 
+#ifdef UNIV_DEBUG
 		if (buf_debug_prints) {
 			fprintf(stderr,
 			"Flushing single page space %lu, page no %lu \n",
 						(ulong) block->space,
 			                        (ulong) block->offset);
 		}
+#endif /* UNIV_DEBUG */
 
 		buf_flush_write_block_low(block);
 		
@@ -906,6 +910,7 @@ buf_flush_batch(
 
 	buf_flush_buffered_writes();
 
+#ifdef UNIV_DEBUG
 	if (buf_debug_prints && page_count > 0) {
 		ut_a(flush_type == BUF_FLUSH_LRU
 			|| flush_type == BUF_FLUSH_LIST);
@@ -914,6 +919,7 @@ buf_flush_batch(
 			: "Flushed %lu pages in flush list flush\n",
 			(ulong) page_count);
 	}
+#endif /* UNIV_DEBUG */
 	
         if (page_count != ULINT_UNDEFINED)
           srv_buf_pool_flushed+= page_count;
diff --git a/innobase/buf/buf0lru.c b/innobase/buf/buf0lru.c
index 18c4f8c10fba5879fc9bd06d38e3983e6dc36461..a0157da2d4206660cec6da9f6e68c2bf557d7700 100644
--- a/innobase/buf/buf0lru.c
+++ b/innobase/buf/buf0lru.c
@@ -213,12 +213,14 @@ buf_LRU_search_and_free_block(
 	        ut_a(block->in_LRU_list);
 		if (buf_flush_ready_for_replace(block)) {
 
+#ifdef UNIV_DEBUG
 			if (buf_debug_prints) {
 				fprintf(stderr,
 				"Putting space %lu page %lu to free list\n",
 					(ulong) block->space,
 				        (ulong) block->offset);
 			}
+#endif /* UNIV_DEBUG */
 
 			buf_LRU_block_remove_hashed_page(block);
 
@@ -919,7 +921,8 @@ buf_LRU_block_free_hashed_page(
 
 	buf_LRU_block_free_non_file_page(block);
 }
-				
+
+#ifdef UNIV_DEBUG
 /**************************************************************************
 Validates the LRU list. */
 
@@ -1050,3 +1053,4 @@ buf_LRU_print(void)
 
 	mutex_exit(&(buf_pool->mutex));
 }
+#endif /* UNIV_DEBUG */
diff --git a/innobase/buf/buf0rea.c b/innobase/buf/buf0rea.c
index d9dc2ca93f536239a3905461ade1eccf0928a2ef..813ca589907beb513b8f30044d509b39872c8aeb 100644
--- a/innobase/buf/buf0rea.c
+++ b/innobase/buf/buf0rea.c
@@ -288,12 +288,14 @@ buf_read_ahead_random(
 	
 	os_aio_simulated_wake_handler_threads();
 
+#ifdef UNIV_DEBUG
 	if (buf_debug_prints && (count > 0)) {
 		fprintf(stderr,
 			"Random read-ahead space %lu offset %lu pages %lu\n",
 						(ulong) space, (ulong) offset,
 		       				(ulong) count);
 	}
+#endif /* UNIV_DEBUG */
 
         ++srv_read_ahead_rnd;
 	return(count);
@@ -575,11 +577,13 @@ buf_read_ahead_linear(
 	/* Flush pages from the end of the LRU list if necessary */
 	buf_flush_free_margin();
 
+#ifdef UNIV_DEBUG
 	if (buf_debug_prints && (count > 0)) {
 		fprintf(stderr,
 		"LINEAR read-ahead space %lu offset %lu pages %lu\n",
 		(ulong) space, (ulong) offset, (ulong) count);
 	}
+#endif /* UNIV_DEBUG */
 
         ++srv_read_ahead_seq;
 	return(count);
@@ -641,11 +645,13 @@ buf_read_ibuf_merge_pages(
 	/* Flush pages from the end of the LRU list if necessary */
 	buf_flush_free_margin();
 
+#ifdef UNIV_DEBUG
 	if (buf_debug_prints) {
 		fprintf(stderr,
 			"Ibuf merge read-ahead space %lu pages %lu\n",
 				(ulong) space_ids[0], (ulong) n_stored);
 	}
+#endif /* UNIV_DEBUG */
 }
 
 /************************************************************************
@@ -711,8 +717,10 @@ buf_read_recv_pages(
 	/* Flush pages from the end of the LRU list if necessary */
 	buf_flush_free_margin();
 
+#ifdef UNIV_DEBUG
 	if (buf_debug_prints) {
 		fprintf(stderr,
 			"Recovery applies read-ahead pages %lu\n", (ulong) n_stored);
 	}
+#endif /* UNIV_DEBUG */
 }
diff --git a/innobase/data/data0data.c b/innobase/data/data0data.c
index 5f74dde8710c022d576d91d7140aacce7ff03363..194213a04e11a3533cd2695e9cf786145dd1e8ab 100644
--- a/innobase/data/data0data.c
+++ b/innobase/data/data0data.c
@@ -502,7 +502,7 @@ dtuple_convert_big_rec(
 
 	size = rec_get_converted_size(index, entry);
 
-	if (size > 1000000000) {
+	if (UNIV_UNLIKELY(size > 1000000000)) {
 		fprintf(stderr,
 "InnoDB: Warning: tuple size very big: %lu\n", (ulong) size);
 		fputs("InnoDB: Tuple contents: ", stderr);
diff --git a/innobase/data/data0type.c b/innobase/data/data0type.c
index 3fcd666b5a5f58592e057a611c667af364484298..d4264ad29261d47ec653c64763da39ac23653e61 100644
--- a/innobase/data/data0type.c
+++ b/innobase/data/data0type.c
@@ -39,7 +39,6 @@ column definitions, or records in the insert buffer, we use this
 charset-collation code for them. */
 
 ulint	data_mysql_default_charset_coll		= 99999999;
-ulint	data_mysql_latin1_swedish_charset_coll	= 99999999;
 
 dtype_t		dtype_binary_val = {DATA_BINARY, 0, 0, 0, 0, 0};
 dtype_t* 	dtype_binary 	= &dtype_binary_val;
@@ -64,9 +63,10 @@ dtype_get_at_most_n_mbchars(
 {
 #ifndef UNIV_HOTBACKUP
 	ut_a(data_len != UNIV_SQL_NULL);
-	ut_a(!(prefix_len % dtype->mbmaxlen));
+	ut_ad(!dtype->mbmaxlen || !(prefix_len % dtype->mbmaxlen));
 
 	if (dtype->mbminlen != dtype->mbmaxlen) {
+		ut_a(!(prefix_len % dtype->mbmaxlen));
 		return(innobase_get_at_most_n_mbchars(
 				dtype_get_charset_coll(dtype->prtype),
 				prefix_len, data_len, str));
diff --git a/innobase/dict/dict0boot.c b/innobase/dict/dict0boot.c
index 0f6d55c93418962187d73f0550e094708ab81301..18a707a1b9301e3172209355075ab0f39271a35c 100644
--- a/innobase/dict/dict0boot.c
+++ b/innobase/dict/dict0boot.c
@@ -66,15 +66,6 @@ dict_hdr_get_new_id(
 	dict_hdr = dict_hdr_get(&mtr);
 
 	id = mtr_read_dulint(dict_hdr + type, &mtr); 
-
-	/* Add some dummy code here because otherwise pgcc seems to
-	compile wrong */
-
-	if (0 == ut_dulint_cmp(id, ut_dulint_max)) {
-		/* TO DO: remove this code, or make it conditional */
-		ut_dbg_null_ptr = 0;
-	}
-
 	id = ut_dulint_add(id, 1);
 	
 	mlog_write_dulint(dict_hdr + type, id, &mtr); 
diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c
index 1f12386e4134d0e8f972a435d01608a500a9e33e..c7d6ffd2c226a89300f79950a61c929404e29328 100644
--- a/innobase/dict/dict0crea.c
+++ b/innobase/dict/dict0crea.c
@@ -736,7 +736,7 @@ dict_truncate_index_tree(
 	dulint		index_id;
 	byte*		ptr;
 	ulint		len;
-	ibool		comp;
+	ulint		comp;
 	dict_index_t*	index;
 
 #ifdef UNIV_SYNC_DEBUG
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index 0c39defeadac0361adfba8d92ad22d426e3eff1b..9580a80e7e76fefab0acf752006852da13a643da 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -1453,7 +1453,7 @@ dict_index_add_to_cache(
 
 	/* Increment the ord_part counts in columns which are ordering */
 
-	if (index->type & DICT_UNIVERSAL) {
+	if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
 		n_ord = new_index->n_fields;
 	} else {
 		n_ord = dict_index_get_n_unique(new_index);
@@ -1482,7 +1482,7 @@ dict_index_add_to_cache(
 		new_index->tree = tree;
 	}
 
-	if (!(new_index->type & DICT_UNIVERSAL)) {
+	if (!UNIV_UNLIKELY(new_index->type & DICT_UNIVERSAL)) {
 
 		new_index->stat_n_diff_key_vals =
 			mem_heap_alloc(new_index->heap,
@@ -1683,7 +1683,7 @@ dict_index_copy_types(
 	dtype_t*	type;
 	ulint		i;
 
-	if (index->type & DICT_UNIVERSAL) {
+	if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
 		dtuple_set_types_binary(tuple, n_fields);
 
 		return;
@@ -1779,7 +1779,7 @@ dict_index_build_internal_clust(
 		dict_index_copy(new_index, index, 0, index->n_fields);
 	}
 
-	if (index->type & DICT_UNIVERSAL) {
+	if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
 		/* No fixed number of fields determines an entry uniquely */
 
 		new_index->n_uniq = ULINT_MAX;
@@ -3682,7 +3682,7 @@ dict_tree_find_index_low(
 	table = index->table;
 	
 	if ((index->type & DICT_CLUSTERED)
-				&& (table->type != DICT_TABLE_ORDINARY)) {
+			&& UNIV_UNLIKELY(table->type != DICT_TABLE_ORDINARY)) {
 
 		/* Get the mix id of the record */
 		ut_a(!table->comp);
@@ -3838,7 +3838,7 @@ dict_tree_build_node_ptr(
 
 	ind = dict_tree_find_index_low(tree, rec);
 	
-	if (tree->type & DICT_UNIVERSAL) {
+	if (UNIV_UNLIKELY(tree->type & DICT_UNIVERSAL)) {
 		/* In a universal index tree, we take the whole record as
 		the node pointer if the reord is on the leaf level,
 		on non-leaf levels we remove the last field, which
@@ -3903,9 +3903,10 @@ dict_tree_copy_rec_order_prefix(
 	dict_index_t*	index;
 	ulint		n;
 
+	UNIV_PREFETCH_R(rec);
 	index = dict_tree_find_index_low(tree, rec);
 
-	if (tree->type & DICT_UNIVERSAL) {
+	if (UNIV_UNLIKELY(tree->type & DICT_UNIVERSAL)) {
 		ut_a(!index->table->comp);
 		n = rec_get_n_fields_old(rec);
 	} else {
@@ -3957,7 +3958,7 @@ dict_index_calc_min_rec_len(
 	ulint	sum	= 0;
 	ulint	i;
 
-	if (index->table->comp) {
+	if (UNIV_LIKELY(index->table->comp)) {
 		ulint nullable = 0;
 		sum = REC_N_NEW_EXTRA_BYTES;
 		for (i = 0; i < dict_index_get_n_fields(index); i++) {
@@ -4277,9 +4278,11 @@ dict_index_print_low(
 
 	putc('\n', stderr);
 
-/*	btr_print_size(tree); */
+#ifdef UNIV_BTR_PRINT
+	btr_print_size(tree);
 
-/*	btr_print_tree(tree, 7); */
+	btr_print_tree(tree, 7);
+#endif /* UNIV_BTR_PRINT */
 }
 
 /**************************************************************************
diff --git a/innobase/dict/dict0mem.c b/innobase/dict/dict0mem.c
index 48b9f28d29251f53e92cca1d79f47aa87f62d690..eec35310039b329efd0aef5d9e866c080192838f 100644
--- a/innobase/dict/dict0mem.c
+++ b/innobase/dict/dict0mem.c
@@ -42,6 +42,7 @@ dict_mem_table_create(
 	mem_heap_t*	heap;
 	
 	ut_ad(name);
+	ut_ad(comp == FALSE || comp == TRUE);
 
 	heap = mem_heap_create(DICT_HEAP_SIZE);
 
diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c
index 8600f583dbd6687b32a1fc8f2d4a000ec1429eb4..299b55f3d2b9bcfe4bc871828ffe13a0181d1b21 100644
--- a/innobase/fil/fil0fil.c
+++ b/innobase/fil/fil0fil.c
@@ -99,7 +99,6 @@ ulint	fil_n_pending_tablespace_flushes	= 0;
 fil_addr_t	fil_addr_null = {FIL_NULL, 0};
 
 /* File node of a tablespace or the log data space */
-typedef	struct fil_node_struct	fil_node_t;
 struct fil_node_struct {
 	fil_space_t*	space;	/* backpointer to the space where this node
 				belongs */
@@ -4046,7 +4045,7 @@ fil_aio_wait(
 	} else {
 		srv_set_io_thread_op_info(segment, "simulated aio handle");
 
-		ret = os_aio_simulated_handle(segment, (void**) &fil_node,
+		ret = os_aio_simulated_handle(segment, &fil_node,
 	                                               &message, &type);
 	}
 	
diff --git a/innobase/fsp/fsp0fsp.c b/innobase/fsp/fsp0fsp.c
index ef8e70646c62d9f7722e4e9497c434a37d76a06f..ad4228f6797007b74da40ff4bf7bce7e008cf02f 100644
--- a/innobase/fsp/fsp0fsp.c
+++ b/innobase/fsp/fsp0fsp.c
@@ -2325,7 +2325,6 @@ fseg_alloc_free_page_low(
 	dulint		seg_id;
 	ulint		used;
 	ulint		reserved;
-	fil_addr_t	first;
 	xdes_t*		descr;		/* extent of the hinted page */
 	ulint		ret_page;	/* the allocated page offset, FIL_NULL
 					if could not be allocated */
@@ -2428,6 +2427,8 @@ fseg_alloc_free_page_low(
 	} else if (reserved - used > 0) {
 		/* 5. We take any unused page from the segment
 		==============================================*/
+		fil_addr_t	first;
+
 		if (flst_get_len(seg_inode + FSEG_NOT_FULL, mtr) > 0) {
 			first = flst_get_first(seg_inode + FSEG_NOT_FULL,
 									mtr);
@@ -2435,6 +2436,7 @@ fseg_alloc_free_page_low(
 			first = flst_get_first(seg_inode + FSEG_FREE, mtr);
 		} else {
 			ut_error;
+			return(FIL_NULL);
 		}
 
 		ret_descr = xdes_lst_get_descriptor(space, first, mtr);
diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c
index 5ad61e2590fc53f71c4fc6b65e870eb16ec21f5f..712d43f916cd280bdb9c3044d0877a1a4f1a73ab 100644
--- a/innobase/ibuf/ibuf0ibuf.c
+++ b/innobase/ibuf/ibuf0ibuf.c
@@ -1889,7 +1889,7 @@ ibuf_get_merge_page_nos(
 				contract the tree, FALSE if this is called
 				when a single page becomes full and we look
 				if it pays to read also nearby pages */
-	rec_t*		first_rec,/* in: record from which we read up and down
+	rec_t*		rec,	/* in: record from which we read up and down
 				in the chain of records */
 	ulint*		space_ids,/* in/out: space id's of the pages */
 	ib_longlong*	space_versions,/* in/out: tablespace version
@@ -1907,47 +1907,42 @@ ibuf_get_merge_page_nos(
 	ulint	first_space_id;
 	ulint	rec_page_no;
 	ulint	rec_space_id;
-	rec_t*	rec;
 	ulint	sum_volumes;
 	ulint	volume_for_page;
 	ulint	rec_volume;
 	ulint	limit;
-	page_t*	page;
 	ulint	n_pages;
 
 	*n_stored = 0;
 
 	limit = ut_min(IBUF_MAX_N_PAGES_MERGED, buf_pool->curr_size / 4);
 
-	page = buf_frame_align(first_rec);
-	
-	if (first_rec == page_get_supremum_rec(page)) {
+	if (page_rec_is_supremum(rec)) {
 
-		first_rec = page_rec_get_prev(first_rec);
+		rec = page_rec_get_prev(rec);
 	}
 
-	if (first_rec == page_get_infimum_rec(page)) {
+	if (page_rec_is_infimum(rec)) {
 
-		first_rec = page_rec_get_next(first_rec);
+		rec = page_rec_get_next(rec);
 	}
 
-	if (first_rec == page_get_supremum_rec(page)) {
+	if (page_rec_is_supremum(rec)) {
 
 		return(0);
 	}
 
-	rec = first_rec;
-	first_page_no = ibuf_rec_get_page_no(first_rec);
-	first_space_id = ibuf_rec_get_space(first_rec);
+	first_page_no = ibuf_rec_get_page_no(rec);
+	first_space_id = ibuf_rec_get_space(rec);
 	n_pages = 0;
 	prev_page_no = 0;
 	prev_space_id = 0;
 	
-	/* Go backwards from the first_rec until we reach the border of the
+	/* Go backwards from the first rec until we reach the border of the
 	'merge area', or the page start or the limit of storeable pages is
 	reached */
 
-	while ((rec != page_get_infimum_rec(page)) && (n_pages < limit)) {
+	while (!page_rec_is_infimum(rec) && UNIV_LIKELY(n_pages < limit)) {
 
 		rec_page_no = ibuf_rec_get_page_no(rec);
 		rec_space_id = ibuf_rec_get_space(rec);
@@ -1982,7 +1977,7 @@ ibuf_get_merge_page_nos(
 	volume_for_page = 0;
 	
 	while (*n_stored < limit) {
-		if (rec == page_get_supremum_rec(page)) {
+		if (page_rec_is_supremum(rec)) {
 			/* When no more records available, mark this with
 			another 'impossible' pair of space id, page no */
 			rec_page_no = 1;
@@ -2311,12 +2306,12 @@ ibuf_get_volume_buffered(
 
 	page = buf_frame_align(rec);
 
-	if (rec == page_get_supremum_rec(page)) {
+	if (page_rec_is_supremum(rec)) {
 		rec = page_rec_get_prev(rec);
 	}
 
 	for (;;) {
-		if (rec == page_get_infimum_rec(page)) {
+		if (page_rec_is_infimum(rec)) {
 
 			break;
 		}
@@ -2351,7 +2346,7 @@ ibuf_get_volume_buffered(
 	rec = page_rec_get_prev(rec);
 	
 	for (;;) {
-		if (rec == page_get_infimum_rec(prev_page)) {
+		if (page_rec_is_infimum(rec)) {
 
 			/* We cannot go to yet a previous page, because we
 			do not have the x-latch on it, and cannot acquire one
@@ -2374,12 +2369,12 @@ ibuf_get_volume_buffered(
 count_later:
 	rec = btr_pcur_get_rec(pcur);
 
-	if (rec != page_get_supremum_rec(page)) {
+	if (!page_rec_is_supremum(rec)) {
 		rec = page_rec_get_next(rec);
 	}
 
 	for (;;) {
-		if (rec == page_get_supremum_rec(page)) {
+		if (page_rec_is_supremum(rec)) {
 
 			break;
 		}
@@ -2414,7 +2409,7 @@ count_later:
 	rec = page_rec_get_next(rec);
 
 	for (;;) {
-		if (rec == page_get_supremum_rec(next_page)) {
+		if (page_rec_is_supremum(rec)) {
 
 			/* We give up */
 		
@@ -2815,7 +2810,7 @@ ibuf_insert_to_index_page(
 	ut_ad(ibuf_inside());
 	ut_ad(dtuple_check_typed(entry));
 
-	if (index->table->comp != page_is_comp(page)) {
+	if (UNIV_UNLIKELY(index->table->comp != !!page_is_comp(page))) {
 		fputs(
 "InnoDB: Trying to insert a record from the insert buffer to an index page\n"
 "InnoDB: but the 'compact' flag does not match!\n", stderr);
@@ -2824,7 +2819,8 @@ ibuf_insert_to_index_page(
 
 	rec = page_rec_get_next(page_get_infimum_rec(page));
 
-	if (rec_get_n_fields(rec, index) != dtuple_get_n_fields(entry)) {
+	if (UNIV_UNLIKELY(rec_get_n_fields(rec, index)
+			!= dtuple_get_n_fields(entry))) {
 		fputs(
 "InnoDB: Trying to insert a record from the insert buffer to an index page\n"
 "InnoDB: but the number of fields does not match!\n", stderr);
@@ -2848,7 +2844,7 @@ ibuf_insert_to_index_page(
 	if (low_match == dtuple_get_n_fields(entry)) {
 		rec = page_cur_get_rec(&page_cur);
 		
-		btr_cur_del_unmark_for_ibuf(rec, index, mtr);
+		btr_cur_del_unmark_for_ibuf(rec, mtr);
 	} else {
 		rec = page_cur_tuple_insert(&page_cur, entry, index, mtr);
 		
@@ -2861,8 +2857,8 @@ ibuf_insert_to_index_page(
 						PAGE_CUR_LE, &page_cur);
 
 			/* This time the record must fit */
-			if (!page_cur_tuple_insert(&page_cur, entry,
-								index, mtr)) {
+			if (UNIV_UNLIKELY(!page_cur_tuple_insert(
+					&page_cur, entry, index, mtr))) {
 
 				ut_print_timestamp(stderr);
 
@@ -2969,7 +2965,9 @@ ibuf_delete_rec(
 		btr_pcur_commit_specify_mtr(pcur, mtr);
 
 		fputs("InnoDB: Validating insert buffer tree:\n", stderr);
-		ut_a(btr_validate_tree(ibuf_data->index->tree));
+		if (!btr_validate_tree(ibuf_data->index->tree, NULL)) {
+			ut_error;
+		}
 
 		fprintf(stderr, "InnoDB: ibuf tree ok\n");
 		fflush(stderr);
diff --git a/innobase/include/btr0btr.h b/innobase/include/btr0btr.h
index 0b19e64d4e06a65f17ef20a12a8a5602e7d6c253..1f3a32fa70c6323b7fb3da07dd5a61b96bf0527b 100644
--- a/innobase/include/btr0btr.h
+++ b/innobase/include/btr0btr.h
@@ -168,7 +168,7 @@ btr_create(
 	ulint	type,	/* in: type of the index */
 	ulint	space,	/* in: space where created */
 	dulint	index_id,/* in: index id */
-	ibool	comp,	/* in: TRUE=compact page format */
+	ulint	comp,	/* in: nonzero=compact page format */
 	mtr_t*	mtr);	/* in: mini-transaction handle */
 /****************************************************************
 Frees a B-tree except the root page, which MUST be freed after this
@@ -276,7 +276,7 @@ void
 btr_set_min_rec_mark(
 /*=================*/
 	rec_t*	rec,	/* in: record */
-	ibool	comp,	/* in: TRUE=compact page format */
+	ulint	comp,	/* in: nonzero=compact page format */
 	mtr_t*	mtr);	/* in: mtr */
 /*****************************************************************
 Deletes on the upper level the node pointer to a page. */
@@ -336,7 +336,7 @@ btr_parse_set_min_rec_mark(
 			/* out: end of log record or NULL */
 	byte*	ptr,	/* in: buffer */
 	byte*	end_ptr,/* in: buffer end */
-	ibool	comp,	/* in: TRUE=compact page format */
+	ulint	comp,	/* in: nonzero=compact page format */
 	page_t*	page,	/* in: page or NULL */
 	mtr_t*	mtr);	/* in: mtr or NULL */
 /***************************************************************
@@ -398,6 +398,7 @@ btr_page_free_low(
 	page_t*		page,	/* in: page to be freed, x-latched */	
 	ulint		level,	/* in: page level */
 	mtr_t*		mtr);	/* in: mtr */
+#ifdef UNIV_BTR_PRINT
 /*****************************************************************
 Prints size info of a B-tree. */
 
@@ -414,6 +415,7 @@ btr_print_tree(
 	dict_tree_t*	tree,	/* in: tree */
 	ulint		width);	/* in: print this many entries from start
 				and end */
+#endif /* UNIV_BTR_PRINT */
 /****************************************************************
 Checks the size and number of fields in a record based on the definition of
 the index. */
@@ -434,7 +436,8 @@ ibool
 btr_validate_tree(
 /*==============*/
 				/* out: TRUE if ok */
-	dict_tree_t*	tree);	/* in: tree */
+	dict_tree_t*	tree,	/* in: tree */
+	trx_t*		trx);	/* in: transaction or NULL */
 
 #define BTR_N_LEAF_PAGES 	1
 #define BTR_TOTAL_SIZE		2
diff --git a/innobase/include/btr0btr.ic b/innobase/include/btr0btr.ic
index 1d1f97d3668fa70ebe6194bddeb09c11c977222f..a0860b1c3a769ea85d8f8b6c161bd85f864048a7 100644
--- a/innobase/include/btr0btr.ic
+++ b/innobase/include/btr0btr.ic
@@ -200,10 +200,10 @@ btr_node_ptr_get_child_page_no(
 	
 	page_no = mach_read_from_4(field);
 
-	if (page_no == 0) {
+	if (UNIV_UNLIKELY(page_no == 0)) {
 		fprintf(stderr,
 "InnoDB: a nonsensical page number 0 in a node ptr record at offset %lu\n",
-		       (unsigned long)(rec - buf_frame_align(rec)));
+			(ulong) ut_align_offset(rec, UNIV_PAGE_SIZE));
 		buf_page_print(buf_frame_align(rec));
 	}
 
diff --git a/innobase/include/btr0cur.h b/innobase/include/btr0cur.h
index 0a8d8ceaeb70a09ff7570faeabdb082c9f164453..352d1739b6a10acfecf638ad161d2d5d2bd4a609 100644
--- a/innobase/include/btr0cur.h
+++ b/innobase/include/btr0cur.h
@@ -284,7 +284,6 @@ void
 btr_cur_del_unmark_for_ibuf(
 /*========================*/
 	rec_t*		rec,	/* in: record to delete unmark */
-	dict_index_t*	index,	/* in: record descriptor */
 	mtr_t*		mtr);	/* in: mtr */
 /*****************************************************************
 Tries to compress a page of the tree on the leaf level. It is assumed
@@ -389,7 +388,6 @@ btr_cur_parse_del_mark_set_sec_rec(
 				/* out: end of log record or NULL */
 	byte*		ptr,	/* in: buffer */
 	byte*		end_ptr,/* in: buffer end */
-	dict_index_t*	index,	/* in: index corresponding to page */
 	page_t*		page);	/* in: page or NULL */
 /***********************************************************************
 Estimates the number of rows in a given index range. */
diff --git a/innobase/include/btr0cur.ic b/innobase/include/btr0cur.ic
index dcad3e9e14dc92de785d4e9e6c5e73ff7e9f430f..bf8a6efb68ddd95ef09e5c86e767657b496b98de 100644
--- a/innobase/include/btr0cur.ic
+++ b/innobase/include/btr0cur.ic
@@ -52,7 +52,9 @@ btr_cur_get_page(
 				/* out: pointer to page */
 	btr_cur_t*	cursor)	/* in: tree cursor */
 {
-	return(buf_frame_align(page_cur_get_rec(&(cursor->page_cur))));
+	page_t*	page = buf_frame_align(page_cur_get_rec(&(cursor->page_cur)));
+	ut_ad(!!page_is_comp(page) == cursor->index->table->comp);
+	return(page);
 }
 
 /*************************************************************
diff --git a/innobase/include/buf0buf.h b/innobase/include/buf0buf.h
index 5ee323f1b1eed3c6ffc1a1f21f32101373d02dd2..ae8d0411c127b0969aa86adcb44e3b490be549f9 100644
--- a/innobase/include/buf0buf.h
+++ b/innobase/include/buf0buf.h
@@ -56,9 +56,11 @@ Created 11/5/1995 Heikki Tuuri
 #define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL
 
 extern buf_pool_t* 	buf_pool; 	/* The buffer pool of the database */
+#ifdef UNIV_DEBUG
 extern ibool		buf_debug_prints;/* If this is set TRUE, the program
 					prints info whenever read or flush
 					occurs */
+#endif /* UNIV_DEBUG */
 extern ulint srv_buf_pool_write_requests; /* variable to count write request
                                           issued */
 
@@ -382,10 +384,10 @@ Returns the value of the modify clock. The caller must have an s-lock
 or x-lock on the block. */
 UNIV_INLINE
 dulint
-buf_frame_get_modify_clock(
+buf_block_get_modify_clock(
 /*=======================*/
 				/* out: value */
-	buf_frame_t*	frame);	/* in: pointer to a frame */
+	buf_block_t*	block);	/* in: block */
 /************************************************************************
 Calculates a page checksum which is stored to the page when it is written
 to a file. Note that we must be careful to calculate the same value
@@ -480,12 +482,20 @@ buf_pool_is_block(
 /*==============*/
 			/* out: TRUE if pointer to block */
 	void*	ptr);	/* in: pointer to memory */
+#ifdef UNIV_DEBUG
 /*************************************************************************
 Validates the buffer pool data structure. */
 
 ibool
 buf_validate(void);
 /*==============*/
+/*************************************************************************
+Prints info of the buffer pool data structure. */
+
+void
+buf_print(void);
+/*============*/
+#endif /* UNIV_DEBUG */
 /************************************************************************
 Prints a page to stderr. */
 
@@ -494,12 +504,6 @@ buf_page_print(
 /*===========*/
 	byte*	read_buf);	/* in: a database page */
 /*************************************************************************
-Prints info of the buffer pool data structure. */
-
-void
-buf_print(void);
-/*============*/
-/*************************************************************************
 Returns the number of latched pages in the buffer pool. */
 
 ulint
diff --git a/innobase/include/buf0buf.ic b/innobase/include/buf0buf.ic
index 681a0ef000a736be8c70a4f7ee2cda9b657b577e..d949254d47d14b066f7cd4bc6f50a05f700d114e 100644
--- a/innobase/include/buf0buf.ic
+++ b/innobase/include/buf0buf.ic
@@ -11,10 +11,11 @@ Created 11/5/1995 Heikki Tuuri
 #include "buf0rea.h"
 #include "mtr0mtr.h"
 
+#ifdef UNIV_DEBUG
 extern ulint		buf_dbg_counter; /* This is used to insert validation
 					operations in execution in the
 					debug version */
-					
+#endif /* UNIV_DEBUG */
 /************************************************************************
 Recommends a move of a block to the start of the LRU list if there is danger
 of dropping from the buffer pool. NOTE: does not reserve the buffer pool
@@ -26,12 +27,8 @@ buf_block_peek_if_too_old(
 				/* out: TRUE if should be made younger */
 	buf_block_t*	block)	/* in: block to make younger */
 {
-	if (buf_pool->freed_page_clock >= block->freed_page_clock 
-				+ 1 + (buf_pool->curr_size / 1024)) {
-		return(TRUE);
-	}
-
-	return(FALSE);
+	return(buf_pool->freed_page_clock >= block->freed_page_clock
+				+ 1 + (buf_pool->curr_size / 1024));
 }
 
 /*************************************************************************
@@ -210,8 +207,8 @@ buf_block_align(
 
 	frame_zero = buf_pool->frame_zero;
 
-	if ((ulint)ptr < (ulint)frame_zero
-	    || (ulint)ptr > (ulint)(buf_pool->high_end)) {
+	if (UNIV_UNLIKELY((ulint)ptr < (ulint)frame_zero)
+	    || UNIV_UNLIKELY((ulint)ptr > (ulint)(buf_pool->high_end))) {
 
 		ut_print_timestamp(stderr);	
 		fprintf(stderr,
@@ -246,8 +243,8 @@ buf_frame_align(
 
 	frame = ut_align_down(ptr, UNIV_PAGE_SIZE);
 
-	if (((ulint)frame < (ulint)(buf_pool->frame_zero))
-	    || (ulint)frame >= (ulint)(buf_pool->high_end)) {
+	if (UNIV_UNLIKELY((ulint)frame < (ulint)(buf_pool->frame_zero))
+	    || UNIV_UNLIKELY((ulint)frame >= (ulint)(buf_pool->high_end))) {
 
 		ut_print_timestamp(stderr);	
 		fprintf(stderr,
@@ -485,17 +482,11 @@ Returns the value of the modify clock. The caller must have an s-lock
 or x-lock on the block. */
 UNIV_INLINE
 dulint
-buf_frame_get_modify_clock(
+buf_block_get_modify_clock(
 /*=======================*/
 				/* out: value */
-	buf_frame_t*	frame)	/* in: pointer to a frame */
+	buf_block_t*	block)	/* in: block */
 {
-	buf_block_t*	block;
-
-	ut_ad(frame);
-
-	block = buf_block_align(frame);
-
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
 	      || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
diff --git a/innobase/include/buf0lru.h b/innobase/include/buf0lru.h
index 45164dd561e06ef3915b201ccabe1aa98543a121..fb29b44ba98c91f87bf6588f505ee63d987e5fe8 100644
--- a/innobase/include/buf0lru.h
+++ b/innobase/include/buf0lru.h
@@ -122,6 +122,7 @@ void
 buf_LRU_make_block_old(
 /*===================*/
 	buf_block_t*	block);	/* in: control block */
+#ifdef UNIV_DEBUG
 /**************************************************************************
 Validates the LRU list. */
 
@@ -134,6 +135,7 @@ Prints the LRU list. */
 void
 buf_LRU_print(void);
 /*===============*/
+#endif /* UNIV_DEBUG */
 
 #ifndef UNIV_NONINL
 #include "buf0lru.ic"
diff --git a/innobase/include/data0type.h b/innobase/include/data0type.h
index a4d2c1a2e1d578e25eaf487ebcbe6f1bd8dac1b4..7e9692eca5a1c7a18e960adaa08b4eaaeea6cada 100644
--- a/innobase/include/data0type.h
+++ b/innobase/include/data0type.h
@@ -12,7 +12,7 @@ Created 1/16/1996 Heikki Tuuri
 #include "univ.i"
 
 extern ulint	data_mysql_default_charset_coll;
-extern ulint	data_mysql_latin1_swedish_charset_coll;
+#define DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL 8
 
 /* SQL data type struct */
 typedef struct dtype_struct		dtype_t;
diff --git a/innobase/include/data0type.ic b/innobase/include/data0type.ic
index a87a08ca5823aa54b66d5428cbc76218b82e0649..06d45dd5501056dd4ee4289965d016fc5e3718e4 100644
--- a/innobase/include/data0type.ic
+++ b/innobase/include/data0type.ic
@@ -388,8 +388,8 @@ dtype_get_fixed_size(
 					dtype_get_charset_coll(type->prtype),
 					&mbminlen, &mbmaxlen);
 
-				if (type->mbminlen != mbminlen
-					|| type->mbmaxlen != mbmaxlen) {
+				if (UNIV_UNLIKELY(type->mbminlen != mbminlen)
+				|| UNIV_UNLIKELY(type->mbmaxlen != mbmaxlen)) {
 
 					ut_print_timestamp(stderr);
 					fprintf(stderr, "  InnoDB: "
diff --git a/innobase/include/dyn0dyn.h b/innobase/include/dyn0dyn.h
index abee62300e33c03167eb25549332f3e7e6f45e24..1df976a530129f757e60c1bc10c07395bdf48d33 100644
--- a/innobase/include/dyn0dyn.h
+++ b/innobase/include/dyn0dyn.h
@@ -132,7 +132,7 @@ void
 dyn_push_string(
 /*============*/
 	dyn_array_t*	arr,	/* in: dyn array */
-	byte*		str,	/* in: string to write */
+	const byte*	str,	/* in: string to write */
 	ulint		len);	/* in: string length */
 
 /*#################################################################*/
diff --git a/innobase/include/dyn0dyn.ic b/innobase/include/dyn0dyn.ic
index b6c4808398bb7f8693c43168c712c0965514cb39..c1b8f2cb8ce45628937da2a936b6ed6a3382bfed 100644
--- a/innobase/include/dyn0dyn.ic
+++ b/innobase/include/dyn0dyn.ic
@@ -324,10 +324,9 @@ void
 dyn_push_string(
 /*============*/
 	dyn_array_t*	arr,	/* in: dyn array */
-	byte*		str,	/* in: string to write */
+	const byte*	str,	/* in: string to write */
 	ulint		len)	/* in: string length */
 {
-	byte*	ptr;
 	ulint	n_copied;
 
 	while (len > 0) {
@@ -337,9 +336,7 @@ dyn_push_string(
 			n_copied = len;
 		}			
 
-		ptr = (byte*) dyn_array_push(arr, n_copied);
-
-		ut_memcpy(ptr, str, n_copied);
+		memcpy(dyn_array_push(arr, n_copied), str, n_copied);
 		
 		str += n_copied;
 		len -= n_copied;
diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h
index 45a81a4ac77bcaa4335ba21afbf78f278b795e9d..20b1f1d7145dfbd7fccbfe7766f1716997bce0c1 100644
--- a/innobase/include/lock0lock.h
+++ b/innobase/include/lock0lock.h
@@ -19,7 +19,9 @@ Created 5/7/1996 Heikki Tuuri
 #include "read0types.h"
 #include "hash0hash.h"
 
+#ifdef UNIV_DEBUG
 extern ibool	lock_print_waits;
+#endif /* UNIV_DEBUG */
 /* Buffer for storing information about the most recent deadlock error */
 extern FILE*	lock_latest_err_file;
 
@@ -216,6 +218,7 @@ actual record is being moved. */
 void
 lock_rec_store_on_page_infimum(
 /*===========================*/
+	page_t*	page,	/* in: page containing the record */
 	rec_t*	rec);	/* in: record whose lock state is stored
 			on the infimum record of the same page; lock
 			bits are reset on the record */
@@ -412,9 +415,7 @@ lock_table(
 				/* out: DB_SUCCESS, DB_LOCK_WAIT,
 				DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
 	ulint		flags,	/* in: if BTR_NO_LOCKING_FLAG bit is set,
-				does nothing;
-				if LOCK_TABLE_EXP bits are set,
-				creates an explicit table lock */
+				does nothing */
 	dict_table_t*	table,	/* in: database table in dictionary cache */
 	ulint		mode,	/* in: lock mode */
 	que_thr_t*	thr);	/* in: query thread */
@@ -451,15 +452,6 @@ lock_release_off_kernel(
 /*====================*/
 	trx_t*	trx);	/* in: transaction */
 /*************************************************************************
-Releases table locks explicitly requested with LOCK TABLES (indicated by
-lock type LOCK_TABLE_EXP), and releases possible other transactions waiting
-because of these locks. */
-
-void
-lock_release_tables_off_kernel(
-/*===========================*/
-	trx_t*	trx);	/* in: transaction */
-/*************************************************************************
 Cancels a waiting lock request and releases possible other transactions
 waiting behind it. */
 
@@ -618,9 +610,6 @@ extern lock_sys_t*	lock_sys;
 /* Lock types */
 #define LOCK_TABLE	16	/* these type values should be so high that */
 #define	LOCK_REC	32	/* they can be ORed to the lock mode */
-#define LOCK_TABLE_EXP	80	/* explicit table lock (80 = 16 + 64) */
-#define	LOCK_TABLE_TRANSACTIONAL	144
-				/* transactional table lock (144 = 16 + 128)*/
 #define LOCK_TYPE_MASK	0xF0UL	/* mask used to extract lock type from the
 				type_mode field in a lock */
 /* Waiting lock flag */
diff --git a/innobase/include/log0log.h b/innobase/include/log0log.h
index d14a116072d5f3c13c562796ab2fe1c476fd1fad..7f3f10438b4181c8ad3feee62ae44746dae59399 100644
--- a/innobase/include/log0log.h
+++ b/innobase/include/log0log.h
@@ -17,8 +17,12 @@ Created 12/9/1995 Heikki Tuuri
 typedef struct log_struct	log_t;
 typedef struct log_group_struct	log_group_t;
 
+#ifdef UNIV_DEBUG
 extern	ibool	log_do_write;
 extern 	ibool	log_debug_writes;
+#else /* UNIV_DEBUG */
+# define log_do_write TRUE
+#endif /* UNIV_DEBUG */
 
 /* Wait modes for log_write_up_to */
 #define LOG_NO_WAIT		91
diff --git a/innobase/include/mach0data.h b/innobase/include/mach0data.h
index 7ad760cd60f5e9241a1d189f1df8ebe0d07cda15..f9a3ff521d52be72accbf0a038f1b6ca78402856 100644
--- a/innobase/include/mach0data.h
+++ b/innobase/include/mach0data.h
@@ -52,6 +52,27 @@ mach_read_from_2(
 /*=============*/
 			/* out: ulint integer, >= 0, < 64k */
 	byte*   b);      /* in: pointer to two bytes */
+
+/************************************************************
+The following function is used to convert a 16-bit data item
+to the canonical format, for fast bytewise equality test
+against memory. */
+UNIV_INLINE
+uint16
+mach_encode_2(
+/*==========*/
+			/* out: 16-bit integer in canonical format */
+	ulint	n);	/* in: integer in machine-dependent format */
+/************************************************************
+The following function is used to convert a 16-bit data item
+from the canonical format, for fast bytewise equality test
+against memory. */
+UNIV_INLINE
+ulint
+mach_decode_2(
+/*==========*/
+			/* out: integer in machine-dependent format */
+	uint16	n);	/* in: 16-bit integer in canonical format */
 /***********************************************************
 The following function is used to store data in 3 consecutive
 bytes. We store the most significant byte to the lowest address. */
diff --git a/innobase/include/mach0data.ic b/innobase/include/mach0data.ic
index 3ffb9baa3445f9cad97ad809624b7e23dfeba27d..888f3f743e491c529f6fb6cc859f0721f3d04a47 100644
--- a/innobase/include/mach0data.ic
+++ b/innobase/include/mach0data.ic
@@ -68,6 +68,37 @@ mach_read_from_2(
 	      );
 }
 
+/************************************************************
+The following function is used to convert a 16-bit data item
+to the canonical format, for fast bytewise equality test
+against memory. */
+UNIV_INLINE
+uint16
+mach_encode_2(
+/*==========*/
+			/* out: 16-bit integer in canonical format */
+	ulint	n)	/* in: integer in machine-dependent format */
+{
+	uint16	ret;
+	ut_ad(2 == sizeof ret);
+	mach_write_to_2((byte*) &ret, n);
+	return(ret);
+}
+/************************************************************
+The following function is used to convert a 16-bit data item
+from the canonical format, for fast bytewise equality test
+against memory. */
+UNIV_INLINE
+ulint
+mach_decode_2(
+/*==========*/
+			/* out: integer in machine-dependent format */
+	uint16	n)	/* in: 16-bit integer in canonical format */
+{
+	ut_ad(2 == sizeof n);
+	return(mach_read_from_2((byte*) &n));
+}
+
 /***********************************************************
 The following function is used to store data in 3 consecutive
 bytes. We store the most significant byte to the lowest address. */
diff --git a/innobase/include/mem0mem.ic b/innobase/include/mem0mem.ic
index 82d88099c3fb2ea7d3aee57c9312bc724bedf23f..8c87c884d78087a721bbafaf6b9a9073a6c11131 100644
--- a/innobase/include/mem0mem.ic
+++ b/innobase/include/mem0mem.ic
@@ -623,7 +623,7 @@ mem_strdupq(
 	}
 	*d++ = q;
 	*d++ = '\0';
-	ut_ad(len == d - dst);
+	ut_ad((ssize_t) len == d - dst);
 	return(dst);
 }
 
diff --git a/innobase/include/mtr0log.h b/innobase/include/mtr0log.h
index c0636ea1e1edcaa229813e7b54b585d3893d4f54..6a3920aa8a163a3d1bbcbd355ec51eb22e251069 100644
--- a/innobase/include/mtr0log.h
+++ b/innobase/include/mtr0log.h
@@ -41,10 +41,10 @@ corresponding log record to the mini-transaction log. */
 void
 mlog_write_string(
 /*==============*/
-	byte*	ptr,	/* in: pointer where to write */
-	byte*	str,	/* in: string to write */
-	ulint	len,	/* in: string length */
-	mtr_t*	mtr);	/* in: mini-transaction handle */
+	byte*		ptr,	/* in: pointer where to write */
+	const byte*	str,	/* in: string to write */
+	ulint		len,	/* in: string length */
+	mtr_t*		mtr);	/* in: mini-transaction handle */
 /************************************************************
 Writes initial part of a log record consisting of one-byte item
 type and four-byte space and page numbers. */
@@ -85,9 +85,9 @@ Catenates n bytes to the mtr log. */
 void
 mlog_catenate_string(
 /*=================*/
-	mtr_t*	mtr,	/* in: mtr */
-	byte*	str,	/* in: string to write */
-	ulint	len);	/* in: string length */
+	mtr_t*		mtr,	/* in: mtr */
+	const byte*	str,	/* in: string to write */
+	ulint		len);	/* in: string length */
 /************************************************************
 Catenates a compressed ulint to mlog. */
 UNIV_INLINE
diff --git a/innobase/include/mtr0mtr.h b/innobase/include/mtr0mtr.h
index 071279d525970b6112a19a24a2343bcd6b2efffc..f44e813cf6bb294beb166e88d24b27f6e527a3c9 100644
--- a/innobase/include/mtr0mtr.h
+++ b/innobase/include/mtr0mtr.h
@@ -112,7 +112,11 @@ flag value must give the length also! */
 						/* mark compact clustered index
 						record deleted */
 #define MLOG_COMP_REC_SEC_DELETE_MARK ((byte)40)/* mark compact secondary index
-						record deleted */
+						record deleted; this log
+						record type is redundant, as
+						MLOG_REC_SEC_DELETE_MARK is
+						independent of the record
+						format. */
 #define MLOG_COMP_REC_UPDATE_IN_PLACE ((byte)41)/* update of a compact record,
 						preserves record field sizes */
 #define MLOG_COMP_REC_DELETE	((byte)42)	/* delete a compact record
diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h
index f55c345537e99dea6f411281bb89be4d7369ccb9..e75281dd93c0f9e90b293e78fdba24902b2b04f2 100644
--- a/innobase/include/os0file.h
+++ b/innobase/include/os0file.h
@@ -17,6 +17,8 @@ Created 10/21/1995 Heikki Tuuri
 #include <time.h>
 #endif
 
+typedef	struct fil_node_struct	fil_node_t;
+
 extern ibool	os_do_not_call_flush_at_each_write;
 extern ibool	os_has_said_disk_full;
 extern ibool	os_aio_print_debug;
@@ -563,7 +565,7 @@ os_aio(
 	ulint		offset_high, /* in: most significant 32 bits of
 				offset */
 	ulint		n,	/* in: number of bytes to read or write */	
-	void*		message1,/* in: messages for the aio handler (these
+	fil_node_t*	message1,/* in: messages for the aio handler (these
 				can be used to identify a completed aio
 				operation); if mode is OS_AIO_SYNC, these
 				are ignored */
@@ -621,7 +623,7 @@ os_aio_windows_handle(
 				ignored */
 	ulint	pos,		/* this parameter is used only in sync aio:
 				wait for the aio slot at this position */  
-	void**	message1,	/* out: the messages passed with the aio
+	fil_node_t**message1,	/* out: the messages passed with the aio
 				request; note that also in the case where
 				the aio operation failed, these output
 				parameters are valid and can be used to
@@ -641,7 +643,7 @@ os_aio_posix_handle(
 /*================*/
 				/* out: TRUE if the aio operation succeeded */
 	ulint	array_no,	/* in: array number 0 - 3 */
-	void**	message1,	/* out: the messages passed with the aio
+	fil_node_t**message1,	/* out: the messages passed with the aio
 				request; note that also in the case where
 				the aio operation failed, these output
 				parameters are valid and can be used to
@@ -661,7 +663,7 @@ os_aio_simulated_handle(
 				i/o thread, segment 1 the log i/o thread,
 				then follow the non-ibuf read threads, and as
 				the last are the non-ibuf write threads */
-	void**	message1,	/* out: the messages passed with the aio
+	fil_node_t**message1,	/* out: the messages passed with the aio
 				request; note that also in the case where
 				the aio operation failed, these output
 				parameters are valid and can be used to
@@ -688,6 +690,8 @@ Refreshes the statistics used to print per-second averages. */
 void
 os_aio_refresh_stats(void);
 /*======================*/
+
+#ifdef UNIV_DEBUG
 /**************************************************************************
 Checks that all slots in the system have been freed, that is, there are
 no pending io operations. */
@@ -695,6 +699,7 @@ no pending io operations. */
 ibool
 os_aio_all_slots_free(void);
 /*=======================*/
+#endif /* UNIV_DEBUG */
 
 /***********************************************************************
 This function returns information about the specified file */
diff --git a/innobase/include/page0cur.h b/innobase/include/page0cur.h
index 4fc62f37db7bfe3d6cbcd9b24544a7ccbe72de51..e89e740e77547fad7f4bbf39b90bf12165af6820 100644
--- a/innobase/include/page0cur.h
+++ b/innobase/include/page0cur.h
@@ -78,16 +78,16 @@ UNIV_INLINE
 ibool
 page_cur_is_before_first(
 /*=====================*/
-				/* out: TRUE if at start */
-	page_cur_t*	cur);	/* in: cursor */
+					/* out: TRUE if at start */
+	const page_cur_t*	cur);	/* in: cursor */
 /*************************************************************
 Returns TRUE if the cursor is after last user record. */
 UNIV_INLINE
 ibool
 page_cur_is_after_last(
 /*===================*/
-				/* out: TRUE if at end */
-	page_cur_t*	cur);	/* in: cursor */
+					/* out: TRUE if at end */
+	const page_cur_t*	cur);	/* in: cursor */
 /**************************************************************
 Positions the cursor on the given record. */
 UNIV_INLINE
diff --git a/innobase/include/page0cur.ic b/innobase/include/page0cur.ic
index e99d799b372d49f10847480af83015a9878cd5fc..f8346819e849228a9504bcd3f4dce56fbff66e43 100644
--- a/innobase/include/page0cur.ic
+++ b/innobase/include/page0cur.ic
@@ -69,15 +69,10 @@ UNIV_INLINE
 ibool
 page_cur_is_before_first(
 /*=====================*/
-				/* out: TRUE if at start */
-	page_cur_t*	cur)	/* in: cursor */
+					/* out: TRUE if at start */
+	const page_cur_t*	cur)	/* in: cursor */
 {
-	if (page_get_infimum_rec(page_cur_get_page(cur)) == cur->rec) {
-
-		return(TRUE);
-	}
-
-	return(FALSE);
+	return(page_rec_is_infimum(cur->rec));
 }
 
 /*************************************************************
@@ -86,15 +81,10 @@ UNIV_INLINE
 ibool
 page_cur_is_after_last(
 /*===================*/
-				/* out: TRUE if at end */
-	page_cur_t*	cur)	/* in: cursor */
+					/* out: TRUE if at end */
+	const page_cur_t*	cur)	/* in: cursor */
 {
-	if (page_get_supremum_rec(page_cur_get_page(cur)) == cur->rec) {
-
-		return(TRUE);
-	}
-
-	return(FALSE);
+	return(page_rec_is_supremum(cur->rec));
 }
 
 /**************************************************************
diff --git a/innobase/include/page0page.h b/innobase/include/page0page.h
index 144c297b811461b09d682b1daf0feaf18587218c..c4ffa39d3aca9f3bd56dfde31716104739f4cc97 100644
--- a/innobase/include/page0page.h
+++ b/innobase/include/page0page.h
@@ -373,13 +373,21 @@ page_dir_find_owner_slot(
 /****************************************************************
 Determine whether the page is in new-style compact format. */
 UNIV_INLINE
-ibool
+ulint
 page_is_comp(
 /*=========*/
-			/* out: TRUE if the page is in compact format
-			FALSE if it is in old-style format */
+			/* out: nonzero if the page is in compact
+			format, zero if it is in old-style format */
 	page_t*	page);	/* in: index page */
 /****************************************************************
+TRUE if the record is on a page in compact format. */
+UNIV_INLINE
+ulint
+page_rec_is_comp(
+/*=============*/
+				/* out: nonzero if in compact format */
+	const rec_t*	rec);	/* in: record */
+/****************************************************************
 Gets the pointer to the next record on the page. */
 UNIV_INLINE
 rec_t*
@@ -407,47 +415,55 @@ page_rec_get_prev(
 				/* out: pointer to previous record */
 	rec_t*		rec);	/* in: pointer to record,
 				must not be page infimum */
-
 /****************************************************************
 TRUE if the record is a user record on the page. */
 UNIV_INLINE
 ibool
-page_rec_is_user_rec(
-/*=================*/
+page_rec_is_user_rec_low(
+/*=====================*/
 			/* out: TRUE if a user record */
-	rec_t*	rec);	/* in: record */
+	ulint	offset);/* in: record offset on page */
 /****************************************************************
 TRUE if the record is the supremum record on a page. */
 UNIV_INLINE
 ibool
-page_rec_is_supremum(
-/*=================*/
+page_rec_is_supremum_low(
+/*=====================*/
 			/* out: TRUE if the supremum record */
-	rec_t*	rec);	/* in: record */
+	ulint	offset);/* in: record offset on page */
 /****************************************************************
 TRUE if the record is the infimum record on a page. */
 UNIV_INLINE
 ibool
-page_rec_is_infimum(
-/*================*/
+page_rec_is_infimum_low(
+/*=====================*/
 			/* out: TRUE if the infimum record */
-	rec_t*	rec);	/* in: record */
+	ulint	offset);/* in: record offset on page */
+
 /****************************************************************
-TRUE if the record is the first user record on the page. */
+TRUE if the record is a user record on the page. */
 UNIV_INLINE
 ibool
-page_rec_is_first_user_rec(
-/*=======================*/
-			/* out: TRUE if first user record */
-	rec_t*	rec);	/* in: record */
+page_rec_is_user_rec(
+/*=================*/
+				/* out: TRUE if a user record */
+	const rec_t*	rec);	/* in: record */
 /****************************************************************
-TRUE if the record is the last user record on the page. */
+TRUE if the record is the supremum record on a page. */
 UNIV_INLINE
 ibool
-page_rec_is_last_user_rec(
-/*======================*/
-			/* out: TRUE if last user record */
-	rec_t*	rec);	/* in: record */
+page_rec_is_supremum(
+/*=================*/
+				/* out: TRUE if the supremum record */
+	const rec_t*	rec);	/* in: record */
+/****************************************************************
+TRUE if the record is the infimum record on a page. */
+UNIV_INLINE
+ibool
+page_rec_is_infimum(
+/*================*/
+				/* out: TRUE if the infimum record */
+	const rec_t*	rec);	/* in: record */
 /*******************************************************************
 Looks for the record which owns the given record. */
 UNIV_INLINE
@@ -495,7 +511,7 @@ ulint
 page_get_free_space_of_empty(
 /*=========================*/
 			/* out: free space */
-	ibool	comp)	/* in: TRUE=compact page format */
+	ulint	comp)	/* in: nonzero=compact page format */
 		__attribute__((const));
 /****************************************************************
 Returns the sum of the sizes of the records in the record list
@@ -539,7 +555,7 @@ page_create(
 	buf_frame_t*	frame,		/* in: a buffer frame where the page is
 					created */
 	mtr_t*		mtr,		/* in: mini-transaction handle */
-	ibool		comp);		/* in: TRUE=compact page format */
+	ulint		comp);		/* in: nonzero=compact page format */
 /*****************************************************************
 Differs from page_copy_rec_list_end, because this function does not
 touch the lock table and max trx id on page. */
@@ -673,7 +689,7 @@ page_parse_create(
 			/* out: end of log record or NULL */
 	byte*	ptr,	/* in: buffer */
 	byte*	end_ptr,/* in: buffer end */
-	ibool	comp,	/* in: TRUE=compact page format */
+	ulint	comp,	/* in: nonzero=compact page format */
 	page_t*	page,	/* in: page or NULL */
 	mtr_t*	mtr);	/* in: mtr or NULL */
 /****************************************************************
diff --git a/innobase/include/page0page.ic b/innobase/include/page0page.ic
index bc0805ca30cc228dba8a069a963d7be4e5ef10a0..fd5281fdbece3b1ce18498c3b4c716488341423f 100644
--- a/innobase/include/page0page.ic
+++ b/innobase/include/page0page.ic
@@ -155,14 +155,27 @@ page_header_reset_last_insert(
 /****************************************************************
 Determine whether the page is in new-style compact format. */
 UNIV_INLINE
-ibool
+ulint
 page_is_comp(
 /*=========*/
-			/* out: TRUE if the page is in compact format
-			FALSE if it is in old-style format */
-	page_t* page)	/* in: index page */
+			/* out: nonzero if the page is in compact
+			format, zero if it is in old-style format */
+	page_t*	page)	/* in: index page */
+{
+	return(UNIV_EXPECT(page_header_get_field(page, PAGE_N_HEAP) & 0x8000,
+		0x8000));
+}
+
+/****************************************************************
+TRUE if the record is on a page in compact format. */
+UNIV_INLINE
+ulint
+page_rec_is_comp(
+/*=============*/
+				/* out: nonzero if in compact format */
+	const rec_t*	rec)	/* in: record */
 {
-	return(!!(page_header_get_field(page, PAGE_N_HEAP) & 0x8000));
+	return(page_is_comp(ut_align_down((rec_t*) rec, UNIV_PAGE_SIZE)));
 }
 
 /****************************************************************
@@ -205,112 +218,107 @@ page_get_supremum_rec(
 TRUE if the record is a user record on the page. */
 UNIV_INLINE
 ibool
-page_rec_is_user_rec(
-/*=================*/
+page_rec_is_user_rec_low(
+/*=====================*/
 			/* out: TRUE if a user record */
-	rec_t*	rec)	/* in: record */
+	ulint	offset)	/* in: record offset on page */
 {
-	ut_ad(rec);
-
-	if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
-
-		return(FALSE);
-	}
-
-	if (rec == page_get_infimum_rec(buf_frame_align(rec))) {
-
-	     	return(FALSE);
-	}
+	ut_ad(offset >= PAGE_NEW_INFIMUM);
+#if PAGE_OLD_INFIMUM < PAGE_NEW_INFIMUM
+# error "PAGE_OLD_INFIMUM < PAGE_NEW_INFIMUM"
+#endif
+#if PAGE_OLD_SUPREMUM < PAGE_NEW_SUPREMUM
+# error "PAGE_OLD_SUPREMUM < PAGE_NEW_SUPREMUM"
+#endif
+#if PAGE_NEW_INFIMUM > PAGE_OLD_SUPREMUM
+# error "PAGE_NEW_INFIMUM > PAGE_OLD_SUPREMUM"
+#endif
+#if PAGE_OLD_INFIMUM > PAGE_NEW_SUPREMUM
+# error "PAGE_OLD_INFIMUM > PAGE_NEW_SUPREMUM"
+#endif
+#if PAGE_NEW_SUPREMUM > PAGE_OLD_SUPREMUM_END
+# error "PAGE_NEW_SUPREMUM > PAGE_OLD_SUPREMUM_END"
+#endif
+#if PAGE_OLD_SUPREMUM > PAGE_NEW_SUPREMUM_END
+# error "PAGE_OLD_SUPREMUM > PAGE_NEW_SUPREMUM_END"
+#endif
+	ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
 
-	return(TRUE);
+	return(UNIV_LIKELY(offset != PAGE_NEW_SUPREMUM)
+		&& UNIV_LIKELY(offset != PAGE_NEW_INFIMUM)
+		&& UNIV_LIKELY(offset != PAGE_OLD_INFIMUM)
+		&& UNIV_LIKELY(offset != PAGE_OLD_SUPREMUM));
 }
 
 /****************************************************************
 TRUE if the record is the supremum record on a page. */
 UNIV_INLINE
 ibool
-page_rec_is_supremum(
-/*=================*/
+page_rec_is_supremum_low(
+/*=====================*/
 			/* out: TRUE if the supremum record */
-	rec_t*	rec)	/* in: record */
+	ulint	offset)	/* in: record offset on page */
 {
-	ut_ad(rec);
+	ut_ad(offset >= PAGE_NEW_INFIMUM);
+	ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
 
-	if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
-
-		return(TRUE);
-	}
-
-	return(FALSE);
+	return(UNIV_UNLIKELY(offset == PAGE_NEW_SUPREMUM)
+		|| UNIV_UNLIKELY(offset == PAGE_OLD_SUPREMUM));
 }
 
 /****************************************************************
 TRUE if the record is the infimum record on a page. */
 UNIV_INLINE
 ibool
-page_rec_is_infimum(
-/*================*/
+page_rec_is_infimum_low(
+/*=====================*/
 			/* out: TRUE if the infimum record */
-	rec_t*	rec)	/* in: record */
+	ulint	offset)	/* in: record offset on page */
 {
-	ut_ad(rec);
-
-	if (rec == page_get_infimum_rec(buf_frame_align(rec))) {
-
-		return(TRUE);
-	}
+	ut_ad(offset >= PAGE_NEW_INFIMUM);
+	ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
 
-	return(FALSE);
+	return(UNIV_UNLIKELY(offset == PAGE_NEW_INFIMUM)
+		|| UNIV_UNLIKELY(offset == PAGE_OLD_INFIMUM));
 }
 
 /****************************************************************
-TRUE if the record is the first user record on the page. */
+TRUE if the record is a user record on the page. */
 UNIV_INLINE
 ibool
-page_rec_is_first_user_rec(
-/*=======================*/
-			/* out: TRUE if first user record */
-	rec_t*	rec)	/* in: record */
+page_rec_is_user_rec(
+/*=================*/
+				/* out: TRUE if a user record */
+	const rec_t*	rec)	/* in: record */
 {
-	ut_ad(rec);
-
-	if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
-
-		return(FALSE);
-	}
-
-	if (rec == page_rec_get_next(
-	     		page_get_infimum_rec(buf_frame_align(rec)))) {
-
-	     	return(TRUE);
-	}
-
-	return(FALSE);
+	return(page_rec_is_user_rec_low(
+			ut_align_offset(rec, UNIV_PAGE_SIZE)));
 }
 
 /****************************************************************
-TRUE if the record is the last user record on the page. */
+TRUE if the record is the supremum record on a page. */
 UNIV_INLINE
 ibool
-page_rec_is_last_user_rec(
-/*======================*/
-			/* out: TRUE if last user record */
-	rec_t*	rec)	/* in: record */
+page_rec_is_supremum(
+/*=================*/
+				/* out: TRUE if the supremum record */
+	const rec_t*	rec)	/* in: record */
 {
-	ut_ad(rec);
-
-	if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
-
-		return(FALSE);
-	}
-
-	if (page_rec_get_next(rec)
-			== page_get_supremum_rec(buf_frame_align(rec))) {
-
-	     	return(TRUE);
-	}
+	return(page_rec_is_supremum_low(
+			ut_align_offset(rec, UNIV_PAGE_SIZE)));
+}
 
-	return(FALSE);
+/****************************************************************
+TRUE if the record is the infimum record on a page. */
+UNIV_INLINE
+ibool
+page_rec_is_infimum(
+/*================*/
+				/* out: TRUE if the infimum record */
+	const rec_t*	rec)	/* in: record */
+{
+	return(page_rec_is_infimum_low(
+			ut_align_offset(rec, UNIV_PAGE_SIZE)));
 }
 
 /*****************************************************************
@@ -340,22 +348,26 @@ page_cmp_dtuple_rec_with_match(
 				matched; when function returns contains the
 				value for current comparison */
 {
-	page_t*	page;
+	ulint	rec_offset;
 
 	ut_ad(dtuple_check_typed(dtuple));
 	ut_ad(rec_offs_validate(rec, NULL, offsets));
+	ut_ad(!rec_offs_comp(offsets) == !page_rec_is_comp(rec));
 
-	page = buf_frame_align(rec);	
+	rec_offset = ut_align_offset(rec, UNIV_PAGE_SIZE);
 
-	if (rec == page_get_infimum_rec(page)) {
+	if (UNIV_UNLIKELY(rec_offset == PAGE_NEW_INFIMUM)
+			|| UNIV_UNLIKELY(rec_offset == PAGE_OLD_INFIMUM)) {
 		return(1);
-	} else if (rec == page_get_supremum_rec(page)) {
+	}
+	if (UNIV_UNLIKELY(rec_offset == PAGE_NEW_SUPREMUM)
+			|| UNIV_UNLIKELY(rec_offset == PAGE_OLD_SUPREMUM)) {
 		return(-1);
-	} else {
-		return(cmp_dtuple_rec_with_match(dtuple, rec, offsets,
+	}
+
+	return(cmp_dtuple_rec_with_match(dtuple, rec, offsets,
 						matched_fields,
 						matched_bytes));
-	}
 }
 
 /*****************************************************************
@@ -482,7 +494,7 @@ page_dir_slot_set_rec(
 {
 	ut_ad(page_rec_check(rec));
 
-	mach_write_to_2(slot, rec - buf_frame_align(rec));
+	mach_write_to_2(slot, ut_align_offset(rec, UNIV_PAGE_SIZE));
 }
 
 /*******************************************************************
@@ -494,8 +506,8 @@ page_dir_slot_get_n_owned(
 					/* out: number of records */
 	page_dir_slot_t* 	slot)	/* in: page directory slot */
 {
-	return(rec_get_n_owned(page_dir_slot_get_rec(slot),
-		page_is_comp(buf_frame_align(slot))));
+	rec_t*	rec	= page_dir_slot_get_rec(slot);
+	return(rec_get_n_owned(rec, page_rec_is_comp(rec)));
 }
 
 /*******************************************************************
@@ -508,8 +520,8 @@ page_dir_slot_set_n_owned(
 	ulint			n)	/* in: number of records owned 
 					by the slot */
 {
-	rec_set_n_owned(page_dir_slot_get_rec(slot),
-		page_is_comp(buf_frame_align(slot)), n);
+	rec_t*	rec	= page_dir_slot_get_rec(slot);
+	rec_set_n_owned(rec, page_rec_is_comp(rec), n);
 }
 
 /****************************************************************
@@ -540,26 +552,25 @@ page_rec_get_next(
 
 	ut_ad(page_rec_check(rec));	
 
-	page = buf_frame_align(rec);
+	page = ut_align_down(rec, UNIV_PAGE_SIZE);
 
 	offs = rec_get_next_offs(rec, page_is_comp(page));
 
-	if (offs >= UNIV_PAGE_SIZE) {
-		fprintf(stderr,
-"InnoDB: Next record offset is nonsensical %lu in record at offset %lu\n",
-		(ulong)offs, (ulong)(rec - page));
+	if (UNIV_UNLIKELY(offs >= UNIV_PAGE_SIZE)) {
 		fprintf(stderr,
-"\nInnoDB: rec address %p, first buffer frame %p\n"
+"InnoDB: Next record offset is nonsensical %lu in record at offset %lu\n"
+"InnoDB: rec address %p, first buffer frame %p\n"
 "InnoDB: buffer pool high end %p, buf fix count %lu\n",
+				(ulong)offs, (ulong)(rec - page),
 				rec, buf_pool->frame_zero,
 				buf_pool->high_end,
 				(ulong)buf_block_align(rec)->buf_fix_count);
 		buf_page_print(page);
 
-		ut_a(0);
+		ut_error;
 	}
 
-	if (offs == 0) {
+	if (UNIV_UNLIKELY(offs == 0)) {
 		
 		return(NULL);
 	}
@@ -581,15 +592,12 @@ page_rec_set_next(
 	ulint	offs;
 
 	ut_ad(page_rec_check(rec));	
-	ut_a((next == NULL)
-	      || (buf_frame_align(rec) == buf_frame_align(next)));
-
-	page = buf_frame_align(rec);
-
-	ut_ad(rec != page_get_supremum_rec(page));
-	ut_ad(next != page_get_infimum_rec(page));
+	ut_ad(!page_rec_is_supremum(rec));
+	page = ut_align_down(rec, UNIV_PAGE_SIZE);
 
 	if (next) {
+		ut_ad(!page_rec_is_infimum(next));
+		ut_ad(page == ut_align_down(next, UNIV_PAGE_SIZE));
 		offs = (ulint) (next - page);
 	} else {
 		offs = 0;
@@ -613,13 +621,12 @@ page_rec_get_prev(
 	rec_t*			rec2;
 	rec_t*			prev_rec = NULL;
 	page_t*			page;
-	ibool			comp;
 
 	ut_ad(page_rec_check(rec));	
 
-	page = buf_frame_align(rec);
+	page = ut_align_down(rec, UNIV_PAGE_SIZE);
 
-	ut_ad(rec != page_get_infimum_rec(page));
+	ut_ad(!page_rec_is_infimum(rec));
 
 	slot_no = page_dir_find_owner_slot(rec);
 
@@ -628,7 +635,6 @@ page_rec_get_prev(
 	slot = page_dir_get_nth_slot(page, slot_no - 1);
 	
 	rec2 = page_dir_slot_get_rec(slot);
-	comp = page_is_comp(page);
 	
 	while (rec != rec2) {
 		prev_rec = rec2;
@@ -649,13 +655,16 @@ page_rec_find_owner_rec(
 			/* out: the owner record */
 	rec_t*	rec)	/* in: the physical record */
 {
-	ibool	comp;
-
 	ut_ad(page_rec_check(rec));
-	comp = page_is_comp(buf_frame_align(rec));
 
-	while (rec_get_n_owned(rec, comp) == 0) {
-		rec = page_rec_get_next(rec);
+	if (page_rec_is_comp(rec)) {
+		while (rec_get_n_owned(rec, TRUE) == 0) {
+			rec = page_rec_get_next(rec);
+		}
+	} else {
+		while (rec_get_n_owned(rec, FALSE) == 0) {
+			rec = page_rec_get_next(rec);
+		}
 	}
 
 	return(rec);
@@ -691,10 +700,17 @@ ulint
 page_get_free_space_of_empty(
 /*=========================*/
 				/* out: free space */
-	ibool comp)		/* in: TRUE=compact page layout */
+	ulint	comp)		/* in: nonzero=compact page layout */
 {
+	if (UNIV_LIKELY(comp)) {
+		return((ulint)(UNIV_PAGE_SIZE
+		- PAGE_NEW_SUPREMUM_END
+		- PAGE_DIR
+		- 2 * PAGE_DIR_SLOT_SIZE));
+	}
+
 	return((ulint)(UNIV_PAGE_SIZE
-		- (comp ? PAGE_NEW_SUPREMUM_END : PAGE_OLD_SUPREMUM_END)
+		- PAGE_OLD_SUPREMUM_END
 		- PAGE_DIR
 		- 2 * PAGE_DIR_SLOT_SIZE));
 }
@@ -716,17 +732,21 @@ page_get_max_insert_size(
 {
 	ulint	occupied;
 	ulint	free_space;
-	ibool	comp;
 
-	comp = page_is_comp(page);
+	if (page_is_comp(page)) {
+		occupied = page_header_get_field(page, PAGE_HEAP_TOP)
+		- PAGE_NEW_SUPREMUM_END + page_dir_calc_reserved_space(
+			n_recs + page_dir_get_n_heap(page) - 2);
 
-	occupied = page_header_get_field(page, PAGE_HEAP_TOP)
-		- (comp ? PAGE_NEW_SUPREMUM_END : PAGE_OLD_SUPREMUM_END)
-		+ page_dir_calc_reserved_space(
+		free_space = page_get_free_space_of_empty(TRUE);
+	} else {
+		occupied = page_header_get_field(page, PAGE_HEAP_TOP)
+		- PAGE_OLD_SUPREMUM_END + page_dir_calc_reserved_space(
 			n_recs + page_dir_get_n_heap(page) - 2);
 
-	free_space = page_get_free_space_of_empty(comp);
-		     
+		free_space = page_get_free_space_of_empty(FALSE);
+	}
+
 	/* Above the 'n_recs +' part reserves directory space for the new
 	inserted records; the '- 2' excludes page infimum and supremum
 	records */
@@ -752,14 +772,11 @@ page_get_max_insert_size_after_reorganize(
 {
 	ulint	occupied;
 	ulint	free_space;
-	ibool	comp;
 
-	comp = page_is_comp(page);
-	
 	occupied = page_get_data_size(page)
 		+ page_dir_calc_reserved_space(n_recs + page_get_n_recs(page));
 
-	free_space = page_get_free_space_of_empty(comp);
+	free_space = page_get_free_space_of_empty(page_is_comp(page));
 
 	if (occupied > free_space) {
 
@@ -783,6 +800,7 @@ page_mem_free(
 	ulint		garbage;
 
 	ut_ad(rec_offs_validate(rec, NULL, offsets));
+	ut_ad(!rec_offs_comp(offsets) == !page_rec_is_comp(rec));
 	free = page_header_get_ptr(page, PAGE_FREE);
 
 	page_rec_set_next(rec, free);
diff --git a/innobase/include/read0read.ic b/innobase/include/read0read.ic
index 03d84ee0c510591d298591bad8b4a1fccf85ba89..ec9ef5814bb385c63c71a4e58a41cee935af9771 100644
--- a/innobase/include/read0read.ic
+++ b/innobase/include/read0read.ic
@@ -71,13 +71,8 @@ read_view_sees_trx_id(
 
 		cmp = ut_dulint_cmp(trx_id,
 				read_view_get_nth_trx_id(view, n_ids - i - 1));
-		if (0 == cmp) {
-
-			return(FALSE);
-
-		} else if (cmp < 0) {
-
-			return(TRUE);
+		if (cmp <= 0) {
+			return(cmp < 0);
 		}
 	}
 	
diff --git a/innobase/include/rem0rec.h b/innobase/include/rem0rec.h
index 134c37c8030972edce98f1a3d59b89305b8ea008..c068f4cb73cba67dc2a05ea2e969f661d010d284 100644
--- a/innobase/include/rem0rec.h
+++ b/innobase/include/rem0rec.h
@@ -51,7 +51,7 @@ rec_get_next_offs(
 			/* out: the page offset of the next 
 			chained record */
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp);	/* in: TRUE=compact page format */
+	ulint	comp);	/* in: nonzero=compact page format */
 /**********************************************************
 The following function is used to set the next record offset field
 of the record. */
@@ -60,7 +60,7 @@ void
 rec_set_next_offs(
 /*==============*/
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp,	/* in: TRUE=compact page format */
+	ulint	comp,	/* in: nonzero=compact page format */
 	ulint	next);	/* in: offset of the next record */
 /**********************************************************
 The following function is used to get the number of fields
@@ -90,7 +90,7 @@ rec_get_n_owned(
 /*============*/
 			/* out: number of owned records */
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp);	/* in: TRUE=compact page format */
+	ulint	comp);	/* in: nonzero=compact page format */
 /**********************************************************
 The following function is used to set the number of owned
 records. */
@@ -99,7 +99,7 @@ void
 rec_set_n_owned(
 /*============*/
 	rec_t*	rec,		/* in: physical record */
-	ibool	comp,		/* in: TRUE=compact page format */
+	ulint	comp,		/* in: nonzero=compact page format */
 	ulint	n_owned);	/* in: the number of owned */
 /**********************************************************
 The following function is used to retrieve the info bits of
@@ -110,7 +110,7 @@ rec_get_info_bits(
 /*==============*/
 			/* out: info bits */
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp);	/* in: TRUE=compact page format */
+	ulint	comp);	/* in: nonzero=compact page format */
 /**********************************************************
 The following function is used to set the info bits of a record. */
 UNIV_INLINE
@@ -118,7 +118,7 @@ void
 rec_set_info_bits(
 /*==============*/
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp,	/* in: TRUE=compact page format */
+	ulint	comp,	/* in: nonzero=compact page format */
 	ulint	bits);	/* in: info bits */
 /**********************************************************
 The following function retrieves the status bits of a new-style record. */
@@ -147,7 +147,7 @@ rec_get_info_and_status_bits(
 /*=========================*/
 			/* out: info bits */
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp);	/* in: TRUE=compact page format */
+	ulint	comp);	/* in: nonzero=compact page format */
 /**********************************************************
 The following function is used to set the info and status
 bits of a record.  (Only compact records have status bits.) */
@@ -156,18 +156,18 @@ void
 rec_set_info_and_status_bits(
 /*=========================*/
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp,	/* in: TRUE=compact page format */
+	ulint	comp,	/* in: nonzero=compact page format */
 	ulint	bits);	/* in: info bits */
 
 /**********************************************************
 The following function tells if record is delete marked. */
 UNIV_INLINE
-ibool
+ulint
 rec_get_deleted_flag(
 /*=================*/
-			/* out: TRUE if delete marked */
+			/* out: nonzero if delete marked */
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp);	/* in: TRUE=compact page format */
+	ulint	comp);	/* in: nonzero=compact page format */
 /**********************************************************
 The following function is used to set the deleted bit. */
 UNIV_INLINE
@@ -175,8 +175,8 @@ void
 rec_set_deleted_flag(
 /*=================*/
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp,	/* in: TRUE=compact page format */
-	ibool	flag);	/* in: TRUE if delete marked */
+	ulint	comp,	/* in: nonzero=compact page format */
+	ulint	flag);	/* in: nonzero if delete marked */
 /**********************************************************
 The following function tells if a new-style record is a node pointer. */
 UNIV_INLINE
@@ -186,14 +186,6 @@ rec_get_node_ptr_flag(
 			/* out: TRUE if node pointer */
 	rec_t*	rec);	/* in: physical record */
 /**********************************************************
-The following function is used to flag a record as a node pointer. */
-UNIV_INLINE
-void
-rec_set_node_ptr_flag(
-/*=================*/
-	rec_t*	rec,	/* in: physical record */
-	ibool	flag);	/* in: TRUE if the record is a node pointer */
-/**********************************************************
 The following function is used to get the order number
 of the record in the heap of the index page. */
 UNIV_INLINE
@@ -202,7 +194,7 @@ rec_get_heap_no(
 /*=============*/
 			/* out: heap order number */
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp);	/* in: TRUE=compact page format */
+	ulint	comp);	/* in: nonzero=compact page format */
 /**********************************************************
 The following function is used to set the heap number
 field in the record. */
@@ -211,7 +203,7 @@ void
 rec_set_heap_no(
 /*=============*/
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp,	/* in: TRUE=compact page format */
+	ulint	comp,	/* in: nonzero=compact page format */
 	ulint	heap_no);/* in: the heap number */
 /**********************************************************
 The following function is used to test whether the data offsets
@@ -305,27 +297,18 @@ rec_get_nth_field(
 Determine if the offsets are for a record in the new
 compact format. */
 UNIV_INLINE
-ibool
+ulint
 rec_offs_comp(
 /*==========*/
-				/* out: TRUE if compact format */
+				/* out: nonzero if compact format */
 	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
 /**********************************************************
-Returns TRUE if the nth field of rec is SQL NULL. */
+Returns nonzero if the extern bit is set in nth field of rec. */
 UNIV_INLINE
-ibool
-rec_offs_nth_null(
-/*==============*/
-				/* out: TRUE if SQL NULL */
-	const ulint*	offsets,/* in: array returned by rec_get_offsets() */
-	ulint		n);	/* in: nth field */
-/**********************************************************
-Returns TRUE if the extern bit is set in nth field of rec. */
-UNIV_INLINE
-ibool
+ulint
 rec_offs_nth_extern(
 /*================*/
-				/* out: TRUE if externally stored */
+				/* out: nonzero if externally stored */
 	const ulint*	offsets,/* in: array returned by rec_get_offsets() */
 	ulint		n);	/* in: nth field */
 /**********************************************************
diff --git a/innobase/include/rem0rec.ic b/innobase/include/rem0rec.ic
index 2593fb8edeb619d654326e31f068b82790ab16c8..d60fb3b9eda2950ed05fd69dcbac7e795d984fa6 100644
--- a/innobase/include/rem0rec.ic
+++ b/innobase/include/rem0rec.ic
@@ -265,7 +265,7 @@ rec_get_next_offs(
 			/* out: the page offset of the next chained record, or
 			0 if none */
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp)	/* in: TRUE=compact page format */
+	ulint	comp)	/* in: nonzero=compact page format */
 {	
 	ulint	field_value;
 		
@@ -312,7 +312,7 @@ void
 rec_set_next_offs(
 /*==============*/
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp,	/* in: TRUE=compact page format */
+	ulint	comp,	/* in: nonzero=compact page format */
 	ulint	next)	/* in: offset of the next record, or 0 if none */
 {
 	ut_ad(rec);
@@ -414,7 +414,7 @@ rec_get_n_fields(
 {
 	ut_ad(rec);
 	ut_ad(index);
-	if (!index->table->comp) {
+	if (UNIV_UNLIKELY(!index->table->comp)) {
 		return(rec_get_n_fields_old(rec));
 	}
 	switch (rec_get_status(rec)) {
@@ -440,7 +440,7 @@ rec_get_n_owned(
 /*============*/
 			/* out: number of owned records */
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp)	/* in: TRUE=compact page format */
+	ulint	comp)	/* in: nonzero=compact page format */
 {
 	ulint	ret;
 
@@ -461,7 +461,7 @@ void
 rec_set_n_owned(
 /*============*/
 	rec_t*	rec,		/* in: physical record */
-	ibool	comp,		/* in: TRUE=compact page format */
+	ulint	comp,		/* in: nonzero=compact page format */
 	ulint	n_owned)	/* in: the number of owned */
 {
 	ut_ad(rec);
@@ -480,7 +480,7 @@ rec_get_info_bits(
 /*==============*/
 			/* out: info bits */
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp)	/* in: TRUE=compact page format */
+	ulint	comp)	/* in: nonzero=compact page format */
 {
 	ulint	ret;
 
@@ -501,7 +501,7 @@ void
 rec_set_info_bits(
 /*==============*/
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp,	/* in: TRUE=compact page format */
+	ulint	comp,	/* in: nonzero=compact page format */
 	ulint	bits)	/* in: info bits */
 {
 	ut_ad(rec);
@@ -537,14 +537,14 @@ rec_get_info_and_status_bits(
 /*=========================*/
 			/* out: info bits */
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp)	/* in: TRUE=compact page format */
+	ulint	comp)	/* in: nonzero=compact page format */
 {
 	ulint	bits;
 #if (REC_NEW_STATUS_MASK >> REC_NEW_STATUS_SHIFT) \
 & (REC_INFO_BITS_MASK >> REC_INFO_BITS_SHIFT)
 # error "REC_NEW_STATUS_MASK and REC_INFO_BITS_MASK overlap"
 #endif
-	if (comp) {
+	if (UNIV_EXPECT(comp, REC_OFFS_COMPACT)) {
 		bits = rec_get_info_bits(rec, TRUE) | rec_get_status(rec);
 	} else {
 		bits = rec_get_info_bits(rec, FALSE);
@@ -560,7 +560,7 @@ void
 rec_set_info_and_status_bits(
 /*=========================*/
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp,	/* in: TRUE=compact page format */
+	ulint	comp,	/* in: nonzero=compact page format */
 	ulint	bits)	/* in: info bits */
 {
 #if (REC_NEW_STATUS_MASK >> REC_NEW_STATUS_SHIFT) \
@@ -578,19 +578,22 @@ rec_set_info_and_status_bits(
 /**********************************************************
 The following function tells if record is delete marked. */
 UNIV_INLINE
-ibool
+ulint
 rec_get_deleted_flag(
 /*=================*/
-			/* out: TRUE if delete marked */
+			/* out: nonzero if delete marked */
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp)	/* in: TRUE=compact page format */
+	ulint	comp)	/* in: nonzero=compact page format */
 {
-	if (REC_INFO_DELETED_FLAG & rec_get_info_bits(rec, comp)) {
-
-		return(TRUE);
+	if (UNIV_EXPECT(comp, REC_OFFS_COMPACT)) {
+		return(UNIV_UNLIKELY(rec_get_bit_field_1(rec,
+				REC_NEW_INFO_BITS, REC_INFO_DELETED_FLAG,
+				REC_INFO_BITS_SHIFT)));
+	} else {
+		return(UNIV_UNLIKELY(rec_get_bit_field_1(rec,
+				REC_OLD_INFO_BITS, REC_INFO_DELETED_FLAG,
+				REC_INFO_BITS_SHIFT)));
 	}
-
-	return(FALSE);
 }
 
 /**********************************************************
@@ -600,24 +603,20 @@ void
 rec_set_deleted_flag(
 /*=================*/
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp,	/* in: TRUE=compact page format */
-	ibool	flag)	/* in: TRUE if delete marked */
+	ulint	comp,	/* in: nonzero=compact page format */
+	ulint	flag)	/* in: nonzero if delete marked */
 {
-	ulint	old_val;
-	ulint	new_val;
-
-	ut_ad(TRUE == 1);
-	ut_ad(flag <= TRUE);
+	ulint	val;
 
-	old_val = rec_get_info_bits(rec, comp);
+	val = rec_get_info_bits(rec, comp);
 	
 	if (flag) {
-		new_val = REC_INFO_DELETED_FLAG | old_val;
+		val |= REC_INFO_DELETED_FLAG;
 	} else {
-		new_val = ~REC_INFO_DELETED_FLAG & old_val;
+		val &= ~REC_INFO_DELETED_FLAG;
 	}
 
-	rec_set_info_bits(rec, comp, new_val);
+	rec_set_info_bits(rec, comp, val);
 }
 
 /**********************************************************
@@ -632,26 +631,6 @@ rec_get_node_ptr_flag(
 	return(REC_STATUS_NODE_PTR == rec_get_status(rec));
 }
 
-/**********************************************************
-The following function is used to flag a record as a node pointer. */
-UNIV_INLINE
-void
-rec_set_node_ptr_flag(
-/*=================*/
-	rec_t*	rec,	/* in: physical record */
-	ibool	flag)	/* in: TRUE if the record is a node pointer */
-{
-	ulint	status;
-	ut_ad(flag <= TRUE);
-	ut_ad(REC_STATUS_NODE_PTR >= rec_get_status(rec));
-	if (flag) {
-		status = REC_STATUS_NODE_PTR;
-	} else {
-		status = REC_STATUS_ORDINARY;
-	}
-	rec_set_status(rec, status);
-}
-
 /**********************************************************
 The following function is used to get the order number of the record in the
 heap of the index page. */
@@ -661,7 +640,7 @@ rec_get_heap_no(
 /*=============*/
 			/* out: heap order number */
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp)	/* in: TRUE=compact page format */
+	ulint	comp)	/* in: nonzero=compact page format */
 {
 	ulint	ret;
 
@@ -682,7 +661,7 @@ void
 rec_set_heap_no(
 /*=============*/
 	rec_t*	rec,	/* in: physical record */
-	ibool	comp,	/* in: TRUE=compact page format */
+	ulint	comp,	/* in: nonzero=compact page format */
 	ulint	heap_no)/* in: the heap number */
 {
 	ut_ad(heap_no <= REC_MAX_HEAP_NO);
@@ -843,7 +822,7 @@ rec_offs_validate(
 {
 	ulint	i	= rec_offs_n_fields(offsets);
 	ulint	last	= ULINT_MAX;
-	ibool	comp	= (*rec_offs_base(offsets) & REC_OFFS_COMPACT) != 0;
+	ulint	comp	= *rec_offs_base(offsets) & REC_OFFS_COMPACT;
 
 	if (rec) {
 		ut_ad((ulint) rec == offsets[2]);
@@ -926,7 +905,7 @@ rec_get_nth_field(
 	ut_ad(n < rec_offs_n_fields(offsets));
 	ut_ad(len);
 
-	if (n == 0) {
+	if (UNIV_UNLIKELY(n == 0)) {
 		field = rec;
 	} else {
 		field = rec + (rec_offs_base(offsets)[n] & REC_OFFS_MASK);
@@ -949,43 +928,30 @@ rec_get_nth_field(
 Determine if the offsets are for a record in the new
 compact format. */
 UNIV_INLINE
-ibool
+ulint
 rec_offs_comp(
 /*==========*/
-				/* out: TRUE if compact format */
+				/* out: nonzero if compact format */
 	const ulint*	offsets)/* in: array returned by rec_get_offsets() */
 {
 	ut_ad(rec_offs_validate(NULL, NULL, offsets));
-	return((*rec_offs_base(offsets) & REC_OFFS_COMPACT) != 0);
+	return(*rec_offs_base(offsets) & REC_OFFS_COMPACT);
 }
 
 /**********************************************************
-Returns TRUE if the nth field of rec is SQL NULL. */
-UNIV_INLINE
-ibool
-rec_offs_nth_null(
-/*==============*/
-				/* out: TRUE if SQL NULL */
-	const ulint*	offsets,/* in: array returned by rec_get_offsets() */
-	ulint		n)	/* in: nth field */
-{
-	ut_ad(rec_offs_validate(NULL, NULL, offsets));
-	ut_ad(n < rec_offs_n_fields(offsets));
-	return((rec_offs_base(offsets)[1 + n] & REC_OFFS_SQL_NULL) != 0);
-}
-/**********************************************************
-Returns TRUE if the extern bit is set in nth field of rec. */
+Returns nonzero if the extern bit is set in nth field of rec. */
 UNIV_INLINE
-ibool
+ulint
 rec_offs_nth_extern(
 /*================*/
-				/* out: TRUE if externally stored */
+				/* out: nonzero if externally stored */
 	const ulint*	offsets,/* in: array returned by rec_get_offsets() */
 	ulint		n)	/* in: nth field */
 {
 	ut_ad(rec_offs_validate(NULL, NULL, offsets));
 	ut_ad(n < rec_offs_n_fields(offsets));
-	return((rec_offs_base(offsets)[1 + n] & REC_OFFS_EXTERNAL) != 0);
+	return(UNIV_UNLIKELY(rec_offs_base(offsets)[1 + n]
+				& REC_OFFS_EXTERNAL));
 }
 
 /**********************************************************
@@ -1037,7 +1003,7 @@ rec_set_nth_field_extern_bit(
 				where rec is, or NULL; in the NULL case
 				we do not write to log about the change */
 {
-	if (index->table->comp) {
+	if (UNIV_LIKELY(index->table->comp)) {
 		rec_set_nth_field_extern_bit_new(rec, index, i, val, mtr);
 	} else {
 		rec_set_nth_field_extern_bit_old(rec, i, val, mtr);
@@ -1048,7 +1014,7 @@ rec_set_nth_field_extern_bit(
 Returns the offset of n - 1th field end if the record is stored in the 1-byte
 offsets form. If the field is SQL null, the flag is ORed in the returned
 value. This function and the 2-byte counterpart are defined here because the
-C-compilerwas not able to sum negative and positive constant offsets, and
+C-compiler was not able to sum negative and positive constant offsets, and
 warned of constant arithmetic overflow within the compiler. */
 UNIV_INLINE
 ulint
@@ -1452,7 +1418,7 @@ rec_get_converted_size(
 				? dict_index_get_n_unique_in_tree(index) + 1
 				: dict_index_get_n_fields(index)));
 
-	if (index->table->comp) {
+	if (UNIV_LIKELY(index->table->comp)) {
 		return(rec_get_converted_size_new(index, dtuple));
 	}
 
diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h
index e44d689b88b7915a5576f990dcc24f7575e0ca27..4bb9fa63cd15bd7e811db0fdd86423d7e6b73ab3 100644
--- a/innobase/include/row0mysql.h
+++ b/innobase/include/row0mysql.h
@@ -110,7 +110,7 @@ row_mysql_store_col_in_innobase_format(
 					necessarily the length of the actual
 					payload data; if the column is a true
 					VARCHAR then this is irrelevant */
-	ibool		comp);		/* in: TRUE = compact format */
+	ulint		comp);		/* in: nonzero=compact format */
 /********************************************************************
 Handles user errors and lock waits detected by the database engine. */
 
@@ -172,14 +172,6 @@ row_lock_table_autoinc_for_mysql(
 	row_prebuilt_t*	prebuilt);	/* in: prebuilt struct in the MySQL
 					table handle */
 /*************************************************************************
-Unlocks all table locks explicitly requested by trx (with LOCK TABLES,
-lock type LOCK_TABLE_EXP). */
-
-void		  	
-row_unlock_tables_for_mysql(
-/*========================*/
-	trx_t*	trx);	/* in: transaction */
-/*************************************************************************
 Sets a table lock on the table mentioned in prebuilt. */
 
 int
@@ -190,9 +182,10 @@ row_lock_table_for_mysql(
 					table handle */
 	dict_table_t*	table,		/* in: table to lock, or NULL
 					if prebuilt->table should be
-					locked as LOCK_TABLE_EXP |
+					locked as
 					prebuilt->select_lock_type */
-	ulint		mode);		/* in: lock mode of table */
+	ulint		mode);		/* in: lock mode of table
+					(ignored if table==NULL) */
 					   
 /*************************************************************************
 Does an insert for MySQL. */
@@ -599,6 +592,8 @@ struct row_prebuilt_struct {
 					that was decided in ha_innodb.cc,
 					::store_lock(), ::external_lock(),
 					etc. */
+	ulint		mysql_prefix_len;/* byte offset of the end of
+					the last requested column */
 	ulint		mysql_row_len;	/* length in bytes of a row in the
 					MySQL format */
 	ulint		n_rows_fetched;	/* number of rows fetched after
diff --git a/innobase/include/row0sel.ic b/innobase/include/row0sel.ic
index 595cea1138b3f9d9fd5f43d2e0269f948fae34e7..600c620457164370203f53ab2c8fa892e142ffb5 100644
--- a/innobase/include/row0sel.ic
+++ b/innobase/include/row0sel.ic
@@ -75,7 +75,7 @@ open_step(
 		}
 	}
 			
-	if (err != DB_SUCCESS) {
+	if (UNIV_EXPECT(err, DB_SUCCESS) != DB_SUCCESS) {
 		/* SQL error detected */
 		fprintf(stderr, "SQL error %lu\n", (ulong) err);
 
diff --git a/innobase/include/row0upd.ic b/innobase/include/row0upd.ic
index e2d81a39cfa19ef92e5efb47397bfe8b2e866585..acbb11aa1c701c74f9770b172f5de8de5d5a7921 100644
--- a/innobase/include/row0upd.ic
+++ b/innobase/include/row0upd.ic
@@ -83,7 +83,7 @@ upd_field_set_field_no(
 {	
 	upd_field->field_no = field_no;
 
-	if (field_no >= dict_index_get_n_fields(index)) {
+	if (UNIV_UNLIKELY(field_no >= dict_index_get_n_fields(index))) {
 		fprintf(stderr,
 			"InnoDB: Error: trying to access field %lu in ",
 			(ulong) field_no);
diff --git a/innobase/include/sync0rw.ic b/innobase/include/sync0rw.ic
index 3a92100ba014f4271ba1f24d74dde0f544a2e72d..b1ae636010a0d7537ad38dd0ad00c405c8cfe24c 100644
--- a/innobase/include/sync0rw.ic
+++ b/innobase/include/sync0rw.ic
@@ -138,7 +138,7 @@ rw_lock_s_lock_low(
 #endif /* UNIV_SYNC_DEBUG */
 	/* Check if the writer field is free */
 
-	if (lock->writer == RW_LOCK_NOT_LOCKED) {
+	if (UNIV_LIKELY(lock->writer == RW_LOCK_NOT_LOCKED)) {
 		/* Set the shared lock by incrementing the reader count */
 		lock->reader_count++;
 
@@ -243,7 +243,7 @@ rw_lock_s_lock_func(
 
 	mutex_enter(rw_lock_get_mutex(lock));
 
-	if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) {
+	if (UNIV_LIKELY(rw_lock_s_lock_low(lock, pass, file_name, line))) {
 		mutex_exit(rw_lock_get_mutex(lock));
 
 		return; /* Success */
@@ -307,21 +307,18 @@ rw_lock_x_lock_func_nowait(
 	const char*	file_name,/* in: file name where lock requested */
 	ulint		line)	/* in: line where requested */
 {
-	ibool	success	= FALSE;
-	
+	ibool		success		= FALSE;
+	os_thread_id_t	curr_thread	= os_thread_get_curr_id();
 	mutex_enter(rw_lock_get_mutex(lock));
 
-	if ((rw_lock_get_reader_count(lock) == 0)
-	     && ((rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED)
-	     	 || ((rw_lock_get_writer(lock) == RW_LOCK_EX)
-	     	     && (lock->pass == 0)
-	     	     && os_thread_eq(lock->writer_thread,
-					os_thread_get_curr_id())))) {
-
+	if (UNIV_UNLIKELY(rw_lock_get_reader_count(lock) != 0)) {
+	} else if (UNIV_LIKELY(rw_lock_get_writer(lock)
+			       == RW_LOCK_NOT_LOCKED)) {
 		rw_lock_set_writer(lock, RW_LOCK_EX);
-		lock->writer_thread = os_thread_get_curr_id();
-		lock->writer_count++;
+		lock->writer_thread = curr_thread;
 		lock->pass = 0;
+	relock:
+		lock->writer_count++;
 			
 #ifdef UNIV_SYNC_DEBUG
 		rw_lock_add_debug_info(lock, 0, RW_LOCK_EX, file_name, line);
@@ -331,6 +328,10 @@ rw_lock_x_lock_func_nowait(
 		lock->last_x_line = line;
 
 		success = TRUE;
+	} else if (rw_lock_get_writer(lock) == RW_LOCK_EX
+			&& lock->pass == 0
+			&& os_thread_eq(lock->writer_thread, curr_thread)) {
+		goto relock;
 	}
 
 	mutex_exit(rw_lock_get_mutex(lock));
@@ -361,7 +362,7 @@ rw_lock_s_unlock_func(
 
 	/* Reset the shared lock by decrementing the reader count */
 
-	ut_a(lock->reader_count > 0);
+	ut_ad(lock->reader_count > 0);
 	lock->reader_count--;
 
 #ifdef UNIV_SYNC_DEBUG
@@ -371,7 +372,8 @@ rw_lock_s_unlock_func(
 	/* If there may be waiters and this was the last s-lock,
 	signal the object */
 
-	if (lock->waiters && (lock->reader_count == 0)) {
+	if (UNIV_UNLIKELY(lock->waiters)
+			&& lock->reader_count == 0) {
 	       	sg = TRUE;
 
 		rw_lock_set_waiters(lock, 0);
@@ -379,7 +381,7 @@ rw_lock_s_unlock_func(
 	
 	mutex_exit(mutex);
 
-	if (sg == TRUE) {
+	if (UNIV_UNLIKELY(sg)) {
 		sync_array_signal_object(sync_primary_wait_array, lock);
 	}
 
@@ -450,7 +452,8 @@ rw_lock_x_unlock_func(
 #endif
 	
 	/* If there may be waiters, signal the lock */
-	if (lock->waiters && (lock->writer_count == 0)) {
+	if (UNIV_UNLIKELY(lock->waiters)
+			&& lock->writer_count == 0) {
 
 	       	sg = TRUE;
 		rw_lock_set_waiters(lock, 0);
@@ -458,7 +461,7 @@ rw_lock_x_unlock_func(
 	
 	mutex_exit(&(lock->mutex));
 
-	if (sg == TRUE) {
+	if (UNIV_UNLIKELY(sg)) {
 		sync_array_signal_object(sync_primary_wait_array, lock);
 	}
 
diff --git a/innobase/include/trx0rseg.ic b/innobase/include/trx0rseg.ic
index 35e927f5e793f9ac50ecb02b09345cb3826004ab..c9ac50ebf16324c5d23291c3510c179c4b490775 100644
--- a/innobase/include/trx0rseg.ic
+++ b/innobase/include/trx0rseg.ic
@@ -65,7 +65,7 @@ trx_rsegf_get_nth_undo(
 	ulint		n,	/* in: index of slot */
 	mtr_t*		mtr)	/* in: mtr */
 {
-	if (n >= TRX_RSEG_N_SLOTS) {
+	if (UNIV_UNLIKELY(n >= TRX_RSEG_N_SLOTS)) {
 		fprintf(stderr,
 		"InnoDB: Error: trying to get slot %lu of rseg\n", (unsigned long) n);
 		ut_error;
@@ -86,7 +86,7 @@ trx_rsegf_set_nth_undo(
 	ulint		page_no,/* in: page number of the undo log segment */
 	mtr_t*		mtr)	/* in: mtr */
 {
-	if (n >= TRX_RSEG_N_SLOTS) {
+	if (UNIV_UNLIKELY(n >= TRX_RSEG_N_SLOTS)) {
 		fprintf(stderr,
 		"InnoDB: Error: trying to set slot %lu of rseg\n", (unsigned long) n);
 		ut_error;
diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h
index d46613c3a681f5cedb181db86856356874a0a8ef..8df50d6703d903ef1522999d22c5057b65205b50 100644
--- a/innobase/include/trx0trx.h
+++ b/innobase/include/trx0trx.h
@@ -312,6 +312,19 @@ trx_print(
 	FILE*	f,	/* in: output stream */
 	trx_t*	trx);	/* in: transaction */
 
+#ifndef UNIV_HOTBACKUP
+/**************************************************************************
+Determines if the currently running transaction has been interrupted. */
+
+ibool
+trx_is_interrupted(
+/*===============*/
+			/* out: TRUE if interrupted */
+	trx_t*	trx);	/* in: transaction */
+#else /* !UNIV_HOTBACKUP */
+#define trx_is_interrupted(trx) FALSE
+#endif /* !UNIV_HOTBACKUP */
+
 
 /* Signal to a transaction */
 struct trx_sig_struct{
@@ -484,13 +497,6 @@ struct trx_struct{
 					in the lock list trx_locks */
 	ibool		trx_create_lock;/* this is TRUE if we have created a
 					new lock for a record accessed */
-	ulint		n_lock_table_exp;/* number of explicit table locks
-					(LOCK TABLES) reserved by the
-					transaction, stored in trx_locks */
-	ulint		n_lock_table_transactional;
-					/* number of transactional table locks
-					(LOCK TABLES..WHERE ENGINE) reserved by
-					the transaction, stored in trx_locks */
 	UT_LIST_NODE_T(trx_t)
 			trx_list;	/* list of transactions */
 	UT_LIST_NODE_T(trx_t)
diff --git a/innobase/include/univ.i b/innobase/include/univ.i
index 8158c198e2198934cbcf7b53c18ed11daacd456f..132ac9e18c5cdcb0304efb05d76c4baa404359c0 100644
--- a/innobase/include/univ.i
+++ b/innobase/include/univ.i
@@ -181,7 +181,7 @@ management to ensure correct alignment for doubles etc. */
 /* Another basic type we use is unsigned long integer which should be equal to
 the word size of the machine, that is on a 32-bit platform 32 bits, and on a
 64-bit platform 64 bits. We also give the printf format for the type as a
-macro PRULINT. */
+macro ULINTPF. */
 
 #ifdef _WIN64
 typedef unsigned __int64	ulint;
@@ -243,6 +243,30 @@ contains the sum of the following flag and the locally stored len. */
 
 #define UNIV_EXTERN_STORAGE_FIELD (UNIV_SQL_NULL - UNIV_PAGE_SIZE)
 
+/* Some macros to improve branch prediction and reduce cache misses */
+#if defined(__GNUC__) && (__GNUC__ > 2)
+/* Tell the compiler that 'expr' probably evaluates to 'constant'. */
+# define UNIV_EXPECT(expr,constant) __builtin_expect(expr, constant)
+/* Tell the compiler that a pointer is likely to be NULL */
+# define UNIV_LIKELY_NULL(ptr) __builtin_expect((ulint) ptr, 0)
+/* Minimize cache-miss latency by moving data at addr into a cache before
+it is read. */
+# define UNIV_PREFETCH_R(addr) __builtin_prefetch(addr, 0, 3)
+/* Minimize cache-miss latency by moving data at addr into a cache before
+it is read or written. */
+# define UNIV_PREFETCH_RW(addr) __builtin_prefetch(addr, 1, 3)
+#else
+/* Dummy versions of the macros */
+# define UNIV_EXPECT(expr,value) (expr)
+# define UNIV_LIKELY_NULL(expr) (expr)
+# define UNIV_PREFETCH_R(addr) ((void) 0)
+# define UNIV_PREFETCH_RW(addr) ((void) 0)
+#endif
+/* Tell the compiler that cond is likely to hold */
+#define UNIV_LIKELY(cond) UNIV_EXPECT(cond, TRUE)
+/* Tell the compiler that cond is unlikely to hold */
+#define UNIV_UNLIKELY(cond) UNIV_EXPECT(cond, FALSE)
+
 #include <stdio.h>
 #include "ut0dbg.h"
 #include "ut0ut.h"
diff --git a/innobase/include/ut0dbg.h b/innobase/include/ut0dbg.h
index 5f30a89487478330b427dc2689cca6725d4dbb50..bc3f852626a9593b04d5207dc5d78e2ca1e97a4b 100644
--- a/innobase/include/ut0dbg.h
+++ b/innobase/include/ut0dbg.h
@@ -13,74 +13,75 @@ Created 1/30/1994 Heikki Tuuri
 #include <stdlib.h>
 #include "os0thread.h"
 
+#if defined(__GNUC__) && (__GNUC__ > 2)
+# define UT_DBG_FAIL(EXPR) UNIV_UNLIKELY(!((ulint)(EXPR)))
+#else
 extern ulint	ut_dbg_zero; /* This is used to eliminate
 				compiler warnings */
+# define UT_DBG_FAIL(EXPR) !((ulint)(EXPR) + ut_dbg_zero)
+#endif
+
+/*****************************************************************
+Report a failed assertion. */
+
+void
+ut_dbg_assertion_failed(
+/*====================*/
+	const char* expr,	/* in: the failed assertion */
+	const char* file,	/* in: source file containing the assertion */
+	ulint line);		/* in: line number of the assertion */
+
+#ifdef __NETWARE__
+/* Flag for ignoring further assertion failures.
+On NetWare, have a graceful exit rather than a segfault to avoid abends. */
+extern ibool	panic_shutdown;
+/* Abort the execution. */
+void ut_dbg_panic(void);
+# define UT_DBG_PANIC ut_dbg_panic()
+/* Stop threads in ut_a(). */
+# define UT_DBG_STOP	while (0)	/* We do not do this on NetWare */
+#else /* __NETWARE__ */
+/* Flag for indicating that all threads should stop.  This will be set
+by ut_dbg_assertion_failed(). */
 extern ibool	ut_dbg_stop_threads;
 
+/* A null pointer that will be dereferenced to trigger a memory trap */
 extern ulint*	ut_dbg_null_ptr;
 
-extern const char*	ut_dbg_msg_assert_fail;
-extern const char*	ut_dbg_msg_trap;
-extern const char*	ut_dbg_msg_stop;
-/* Have a graceful exit on NetWare rather than a segfault to avoid abends */
-#ifdef __NETWARE__
-extern ibool 	panic_shutdown;
-#define ut_a(EXPR) do {\
-	if (!((ulint)(EXPR) + ut_dbg_zero)) {\
-                ut_print_timestamp(stderr);\
-	   	fprintf(stderr, ut_dbg_msg_assert_fail,\
-		os_thread_pf(os_thread_get_curr_id()), __FILE__,\
-                (ulint)__LINE__);\
-		fputs("InnoDB: Failing assertion: " #EXPR "\n", stderr);\
-		fputs(ut_dbg_msg_trap, stderr);\
-		ut_dbg_stop_threads = TRUE;\
-		if (ut_dbg_stop_threads) {\
-        		fprintf(stderr, ut_dbg_msg_stop,\
-	    os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\
-	    	}\
-		if(!panic_shutdown){\
-		panic_shutdown = TRUE;\
-		innobase_shutdown_for_mysql();}\
-		exit(1);\
-		}\
-} while (0)
-#define ut_error do {\
-		ut_print_timestamp(stderr);\
-		fprintf(stderr, ut_dbg_msg_assert_fail,\
-		os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\
-		fprintf(stderr, ut_dbg_msg_trap);\
-		ut_dbg_stop_threads = TRUE;\
-		if(!panic_shutdown){panic_shutdown = TRUE;\
-		innobase_shutdown_for_mysql();}\
-} while (0)
-#else
-#define ut_a(EXPR) do {\
-	if (!((ulint)(EXPR) + ut_dbg_zero)) {\
-                ut_print_timestamp(stderr);\
-	   	fprintf(stderr, ut_dbg_msg_assert_fail,\
-		os_thread_pf(os_thread_get_curr_id()), __FILE__,\
-                (ulint)__LINE__);\
-		fputs("InnoDB: Failing assertion: " #EXPR "\n", stderr);\
-		fputs(ut_dbg_msg_trap, stderr);\
-		ut_dbg_stop_threads = TRUE;\
-		if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL;\
-	}\
-	if (ut_dbg_stop_threads) {\
-	        fprintf(stderr, ut_dbg_msg_stop,\
-     os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\
-		os_thread_sleep(1000000000);\
-	}\
+/*****************************************************************
+Stop a thread after assertion failure. */
+
+void
+ut_dbg_stop_thread(
+/*===============*/
+	const char*	file,
+	ulint		line);
+
+/* Abort the execution. */
+# define UT_DBG_PANIC					\
+	if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL
+/* Stop threads in ut_a(). */
+# define UT_DBG_STOP do						\
+	if (UNIV_UNLIKELY(ut_dbg_stop_threads)) {		\
+		ut_dbg_stop_thread(__FILE__, (ulint) __LINE__);	\
+	} while (0)
+#endif /* __NETWARE__ */
+
+/* Abort execution if EXPR does not evaluate to nonzero. */
+#define ut_a(EXPR) do {						\
+	if (UT_DBG_FAIL(EXPR)) {				\
+		ut_dbg_assertion_failed(#EXPR,			\
+				__FILE__, (ulint) __LINE__);	\
+		UT_DBG_PANIC;					\
+	}							\
+	UT_DBG_STOP; 						\
 } while (0)
 
-#define ut_error do {\
-        ut_print_timestamp(stderr);\
-	fprintf(stderr, ut_dbg_msg_assert_fail,\
-	os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\
-	fprintf(stderr, ut_dbg_msg_trap);\
-	ut_dbg_stop_threads = TRUE;\
-	if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL;\
+/* Abort execution. */
+#define ut_error do {						\
+	ut_dbg_assertion_failed(0, __FILE__, (ulint) __LINE__);	\
+	UT_DBG_PANIC;						\
 } while (0)
-#endif
 
 #ifdef UNIV_DEBUG
 #define ut_ad(EXPR)  	ut_a(EXPR)
diff --git a/innobase/include/ut0rnd.ic b/innobase/include/ut0rnd.ic
index 06d7012f60b8500587d5c0a06a6f50715339ace5..d2ab087d491b9bb8dd22add4953180fa062520c1 100644
--- a/innobase/include/ut0rnd.ic
+++ b/innobase/include/ut0rnd.ic
@@ -207,12 +207,12 @@ ut_fold_binary(
 	const byte*	str,	/* in: string of bytes */
 	ulint		len)	/* in: length */
 {
-	ulint	i;
-	ulint	fold = 0;
+	const byte*	str_end	= str + len;
+	ulint		fold = 0;
 
 	ut_ad(str);
 
-	for (i = 0; i < len; i++) {
+	while (str < str_end) {
 		fold = ut_fold_ulint_pair(fold, (ulint)(*str));
 
 		str++;
diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c
index 73ecc717e0e0f99a700b674408c3e74a08459c71..48db7ced0cb872cc2be3aba603103533733ea43d 100644
--- a/innobase/lock/lock0lock.c
+++ b/innobase/lock/lock0lock.c
@@ -292,7 +292,25 @@ waiting, in its lock queue. Solution: We can copy the locks as gap type
 locks, so that also the waiting locks are transformed to granted gap type
 locks on the inserted record. */
 
+/* LOCK COMPATIBILITY MATRIX
+ *    IS IX S  X  AI
+ * IS +  +  +  -  +
+ * IX +  +  -  -  +
+ * S  +  -  +  -  -
+ * X  -  -  -  -  -
+ * AI +  +  -  -  -
+ *
+ * Note that for rows, InnoDB only acquires S or X locks.
+ * For tables, InnoDB normally acquires IS or IX locks.
+ * S or X table locks are only acquired for LOCK TABLES.
+ * Auto-increment (AI) locks are needed because of
+ * statement-level MySQL binlog.
+ * See also lock_mode_compatible().
+ */
+
+#ifdef UNIV_DEBUG
 ibool	lock_print_waits	= FALSE;
+#endif /* UNIV_DEBUG */
 
 /* The lock system */
 lock_sys_t*	lock_sys	= NULL;
@@ -348,17 +366,26 @@ static
 ibool
 lock_deadlock_occurs(
 /*=================*/
-			/* out: TRUE if a deadlock was detected */
+			/* out: TRUE if a deadlock was detected and we
+			chose trx as a victim; FALSE if no deadlock, or
+			there was a deadlock, but we chose other
+			transaction(s) as victim(s) */
 	lock_t*	lock,	/* in: lock the transaction is requesting */
 	trx_t*	trx);	/* in: transaction */
 /************************************************************************
 Looks recursively for a deadlock. */
 static
-ibool
+ulint
 lock_deadlock_recursive(
 /*====================*/
-				/* out: TRUE if a deadlock was detected
-				or the calculation took too long */
+				/* out: 0 if no deadlock found,
+				LOCK_VICTIM_IS_START if there was a deadlock
+				and we chose 'start' as the victim,
+				LOCK_VICTIM_IS_OTHER if a deadlock
+				was found and we chose some other trx as a
+				victim: we must do the search again in this
+				last case because there may be another
+				deadlock! */
 	trx_t*	start,		/* in: recursion starting point */
 	trx_t*	trx,		/* in: a transaction waiting for a lock */
 	lock_t*	wait_lock,	/* in: the lock trx is waiting to be granted */
@@ -492,12 +519,7 @@ lock_clust_rec_cons_read_sees(
 
 	trx_id = row_get_rec_trx_id(rec, index, offsets);
 	
-	if (read_view_sees_trx_id(view, trx_id)) {
-
-		return(TRUE);
-	}
-
-	return(FALSE);
+	return(read_view_sees_trx_id(view, trx_id));
 }
 
 /*************************************************************************
@@ -1261,7 +1283,6 @@ lock_rec_get_next(
 /*==============*/
 			/* out: next lock, NULL if none exists */
 	rec_t*	rec,	/* in: record on a page */
-	ibool	comp,	/* in: TRUE=compact page format */
 	lock_t*	lock)	/* in: lock */
 {
 #ifdef UNIV_SYNC_DEBUG
@@ -1269,19 +1290,19 @@ lock_rec_get_next(
 #endif /* UNIV_SYNC_DEBUG */
 	ut_ad(lock_get_type(lock) == LOCK_REC);
 
-	for (;;) {
-		lock = lock_rec_get_next_on_page(lock);
-
-		if (lock == NULL) {
-
-			return(NULL);
-		}
-
-		if (lock_rec_get_nth_bit(lock, rec_get_heap_no(rec, comp))) {
-
-			return(lock);
-		}
+	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)));
 	}
+
+	return(lock);
 }
 
 /*************************************************************************
@@ -1294,22 +1315,18 @@ lock_rec_get_first(
 	rec_t*	rec)	/* in: record on a page */
 {
 	lock_t*	lock;
-	ibool	comp;
 
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&kernel_mutex));
 #endif /* UNIV_SYNC_DEBUG */
 
 	lock = lock_rec_get_first_on_page(rec);
-	comp = page_is_comp(buf_frame_align(rec));
+	if (UNIV_LIKELY_NULL(lock)) {
+		ulint	heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
 
-	while (lock) {
-		if (lock_rec_get_nth_bit(lock, rec_get_heap_no(rec, comp))) {
-
-			break;
+		while (lock && !lock_rec_get_nth_bit(lock, heap_no)) {
+			lock = lock_rec_get_next_on_page(lock);
 		}
-
-		lock = lock_rec_get_next_on_page(lock);
 	}
 
 	return(lock);
@@ -1471,7 +1488,6 @@ lock_rec_has_expl(
 			for a supremum record we regard this always a gap
 			type request */
 	rec_t*	rec,	/* in: record */
-	ibool	comp,	/* in: TRUE=compact page format */
 	trx_t*	trx)	/* in: transaction */
 {
 	lock_t*	lock;
@@ -1501,7 +1517,7 @@ lock_rec_has_expl(
 		    	return(lock);
 		}
 
-		lock = lock_rec_get_next(rec, comp, lock);
+		lock = lock_rec_get_next(rec, lock);
 	}
 
 	return(NULL);
@@ -1520,7 +1536,6 @@ lock_rec_other_has_expl_req(
 	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 */	
-	ibool	comp,	/* in: TRUE=compact record format */
 	trx_t*	trx)	/* in: transaction, or NULL if requests by all
 			transactions are taken into account */
 {
@@ -1545,7 +1560,7 @@ lock_rec_other_has_expl_req(
 		    	return(lock);
 		}
 
-		lock = lock_rec_get_next(rec, comp, lock);
+		lock = lock_rec_get_next(rec, lock);
 	}
 
 	return(NULL);
@@ -1566,13 +1581,11 @@ lock_rec_other_has_conflicting(
 	trx_t*	trx)	/* in: our transaction */
 {
 	lock_t*	lock;
-	ibool	comp;
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&kernel_mutex));
 #endif /* UNIV_SYNC_DEBUG */
 
 	lock = lock_rec_get_first(rec);
-	comp = page_is_comp(buf_frame_align(rec));
 
 	while (lock) {
 		if (lock_rec_has_to_wait(trx, mode, lock,
@@ -1581,7 +1594,7 @@ lock_rec_other_has_conflicting(
 			return(lock);
 		}
 		
-		lock = lock_rec_get_next(rec, comp, lock);
+		lock = lock_rec_get_next(rec, lock);
 	}
 
 	return(NULL);
@@ -1607,7 +1620,7 @@ lock_rec_find_similar_on_page(
 	ut_ad(mutex_own(&kernel_mutex));
 #endif /* UNIV_SYNC_DEBUG */
 
-	heap_no = rec_get_heap_no(rec, page_is_comp(buf_frame_align(rec)));
+	heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
 	lock = lock_rec_get_first_on_page(rec);
 
 	while (lock != NULL) {
@@ -1709,6 +1722,8 @@ lock_rec_create(
 	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);
+
 	/* If rec is the supremum record, then we reset the gap and
 	LOCK_REC_NOT_GAP bits, as all locks on the supremum are
 	automatically of the gap type */
@@ -1725,7 +1740,7 @@ lock_rec_create(
 
 	lock = mem_heap_alloc(trx->lock_heap, sizeof(lock_t) + n_bytes);
 	
-	if (lock == NULL) {
+	if (UNIV_UNLIKELY(lock == NULL)) {
 
 		return(NULL);
 	}
@@ -1826,7 +1841,7 @@ lock_rec_enqueue_waiting(
 
 		lock_reset_lock_and_trx_wait(lock);
 		lock_rec_reset_nth_bit(lock, rec_get_heap_no(rec,
-					page_is_comp(buf_frame_align(rec))));
+					page_rec_is_comp(rec)));
 
 		return(DB_DEADLOCK);
 	}
@@ -1845,11 +1860,13 @@ lock_rec_enqueue_waiting(
 
 	ut_a(que_thr_stop(thr));
 
+#ifdef UNIV_DEBUG
 	if (lock_print_waits) {
 		fprintf(stderr, "Lock wait for trx %lu in index ",
 			(ulong) ut_dulint_get_low(trx->id));
 		ut_print_name(stderr, trx, index->name);
 	}
+#endif /* UNIV_DEBUG */
 	
 	return(DB_LOCK_WAIT);	
 }
@@ -1876,7 +1893,6 @@ lock_rec_add_to_queue(
 	lock_t*	lock;
 	lock_t*	similar_lock	= NULL;
 	ulint	heap_no;
-	page_t*	page		= buf_frame_align(rec);
 	ibool	somebody_waits	= FALSE;
 	
 #ifdef UNIV_SYNC_DEBUG
@@ -1885,11 +1901,11 @@ lock_rec_add_to_queue(
 	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, page_is_comp(page), trx));
+					rec, 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, page_is_comp(page), trx));
+					rec, trx));
 
 	type_mode = type_mode | LOCK_REC;
 
@@ -1898,7 +1914,7 @@ lock_rec_add_to_queue(
 	try to avoid unnecessary memory consumption of a new record lock
 	struct for a gap type lock */
 
-	if (rec == page_get_supremum_rec(page)) {
+	if (page_rec_is_supremum(rec)) {
 		ut_ad(!(type_mode & LOCK_REC_NOT_GAP));
 
 		/* There should never be LOCK_REC_NOT_GAP on a supremum
@@ -1909,7 +1925,7 @@ lock_rec_add_to_queue(
 
 	/* Look for a waiting lock request on the same record or on a gap */
 
-	heap_no = rec_get_heap_no(rec, page_is_comp(page));
+	heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
 	lock = lock_rec_get_first_on_page(rec);
 
 	while (lock != NULL) {
@@ -1984,7 +2000,7 @@ lock_rec_lock_fast(
 			|| mode - (LOCK_MODE_MASK & mode) == 0
 			|| mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP);
 			
-	heap_no = rec_get_heap_no(rec, page_is_comp(buf_frame_align(rec)));
+	heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
 	
 	lock = lock_rec_get_first_on_page(rec);
 
@@ -2065,8 +2081,7 @@ lock_rec_lock_slow(
 			
 	trx = thr_get_trx(thr);
 		
-	if (lock_rec_has_expl(mode, rec,
-				page_is_comp(buf_frame_align(rec)), trx)) {
+	if (lock_rec_has_expl(mode, rec, trx)) {
 		/* The trx already has a strong enough lock on rec: do
 		nothing */
 
@@ -2207,16 +2222,14 @@ lock_grant(
                 release it at the end of the SQL statement */
 
                 lock->trx->auto_inc_lock = lock;
-        } else if (lock_get_type(lock) == LOCK_TABLE_EXP ||
-			lock_get_type(lock) == LOCK_TABLE_TRANSACTIONAL) {
-		ut_a(lock_get_mode(lock) == LOCK_S
-			|| lock_get_mode(lock) == LOCK_X);
-	}
+        }
 
+#ifdef UNIV_DEBUG
 	if (lock_print_waits) {
 		fprintf(stderr, "Lock wait for trx %lu ends\n",
 		       (ulong) ut_dulint_get_low(lock->trx->id));
 	}
+#endif /* UNIV_DEBUG */
 
 	/* If we are resolving a deadlock by choosing another transaction
 	as a victim, then our original transaction may not be in the
@@ -2383,14 +2396,12 @@ lock_rec_reset_and_release_wait(
 {
 	lock_t*	lock;
 	ulint	heap_no;
-	ibool	comp;
 
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&kernel_mutex));
 #endif /* UNIV_SYNC_DEBUG */
 
-	comp = page_is_comp(buf_frame_align(rec));
-	heap_no = rec_get_heap_no(rec, comp);
+	heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
 	
 	lock = lock_rec_get_first(rec);
 
@@ -2401,7 +2412,7 @@ lock_rec_reset_and_release_wait(
 			lock_rec_reset_nth_bit(lock, heap_no);
 		}
 
-		lock = lock_rec_get_next(rec, comp, lock);
+		lock = lock_rec_get_next(rec, lock);
 	}
 }	
 
@@ -2419,13 +2430,11 @@ lock_rec_inherit_to_gap(
 			the locks on this record */
 {
 	lock_t*	lock;
-	ibool	comp;
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&kernel_mutex));
 #endif /* UNIV_SYNC_DEBUG */
 	
 	lock = lock_rec_get_first(rec);
-	comp = page_is_comp(buf_frame_align(rec));
 
 	while (lock != NULL) {
 		if (!lock_rec_get_insert_intention(lock)) {
@@ -2435,7 +2444,7 @@ lock_rec_inherit_to_gap(
 	 			     		heir, lock->index, lock->trx);
 	 	}
 	 	
-		lock = lock_rec_get_next(rec, comp, lock);
+		lock = lock_rec_get_next(rec, lock);
 	}
 }	
 
@@ -2452,13 +2461,11 @@ lock_rec_inherit_to_gap_if_gap_lock(
 			the locks on this record */
 {
 	lock_t*	lock;
-	ibool	comp;
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&kernel_mutex));
 #endif /* UNIV_SYNC_DEBUG */
 	
 	lock = lock_rec_get_first(rec);
-	comp = page_is_comp(buf_frame_align(rec));
 
 	while (lock != NULL) {
 		if (!lock_rec_get_insert_intention(lock)
@@ -2470,7 +2477,7 @@ lock_rec_inherit_to_gap_if_gap_lock(
 	 			     		heir, lock->index, lock->trx);
 	 	}
 
-		lock = lock_rec_get_next(rec, comp, lock);
+		lock = lock_rec_get_next(rec, lock);
 	}
 }	
 
@@ -2484,7 +2491,7 @@ lock_rec_move(
 	rec_t*	receiver,	/* in: record which gets locks; this record
 				must have no lock requests on it! */
 	rec_t*	donator,	/* in: record which gives locks */
-	ibool	comp)		/* in: TRUE=compact page format */
+	ulint	comp)		/* in: nonzero=compact page format */
 {
 	lock_t*	lock;
 	ulint	heap_no;
@@ -2514,7 +2521,7 @@ lock_rec_move(
 
 		lock_rec_add_to_queue(type_mode, receiver, lock->index,
 								lock->trx);
-		lock = lock_rec_get_next(donator, comp, lock);
+		lock = lock_rec_get_next(donator, lock);
 	}
 
 	ut_ad(lock_rec_get_first(donator) == NULL);
@@ -2540,7 +2547,7 @@ lock_move_reorganize_page(
 	UT_LIST_BASE_NODE_T(lock_t)	old_locks;
 	mem_heap_t*	heap		= NULL;
 	rec_t*		sup;
-	ibool		comp;
+	ulint		comp;
 
 	lock_mutex_enter_kernel();
 
@@ -2659,8 +2666,9 @@ lock_move_rec_list_end(
 	ulint		heap_no;
 	rec_t*		sup;
 	ulint		type_mode;
-	ibool		comp;
-	
+	ulint		comp;
+	ut_ad(page == buf_frame_align(rec));
+
 	lock_mutex_enter_kernel();
 
 	/* Note: when we move locks from record to record, waiting locks
@@ -2745,7 +2753,7 @@ lock_move_rec_list_start(
 	page_cur_t	cur2;
 	ulint		heap_no;
 	ulint		type_mode;
-	ibool		comp;
+	ulint		comp;
 
 	ut_a(new_page);
 
@@ -2754,6 +2762,7 @@ lock_move_rec_list_start(
 	lock = lock_rec_get_first_on_page(page);
 	comp = page_is_comp(page);
 	ut_ad(comp == page_is_comp(new_page));
+	ut_ad(page == buf_frame_align(rec));
 
 	while (lock != NULL) {
 		
@@ -2812,7 +2821,7 @@ lock_update_split_right(
 	page_t*	right_page,	/* in: right page */
 	page_t*	left_page)	/* in: left page */
 {
-	ibool	comp;
+	ulint	comp;
 	lock_mutex_enter_kernel();
 	comp = page_is_comp(left_page);
 	ut_ad(comp == page_is_comp(right_page));
@@ -2875,7 +2884,7 @@ lock_update_root_raise(
 	page_t*	new_page,	/* in: index page to which copied */
 	page_t*	root)		/* in: root page */
 {
-	ibool	comp;
+	ulint	comp;
 	lock_mutex_enter_kernel();
 	comp = page_is_comp(root);
 	ut_ad(comp == page_is_comp(new_page));
@@ -2898,7 +2907,7 @@ lock_update_copy_and_discard(
 	page_t*	new_page,	/* in: index page to which copied */
 	page_t*	page)		/* in: index page; NOT the root! */
 {
-	ibool	comp;
+	ulint	comp;
 	lock_mutex_enter_kernel();
 	comp = page_is_comp(page);
 	ut_ad(comp == page_is_comp(new_page));
@@ -2945,31 +2954,34 @@ lock_update_merge_left(
 	page_t*	right_page)	/* in: merged index page which will be
 				discarded */
 {
-	ibool	comp;
+	rec_t*	left_next_rec;
+	rec_t*	left_supremum;
+	ulint	comp;
 	lock_mutex_enter_kernel();
 	comp = page_is_comp(left_page);
 	ut_ad(comp == page_is_comp(right_page));
+	ut_ad(left_page == buf_frame_align(orig_pred));
 
-	if (page_rec_get_next(orig_pred) != page_get_supremum_rec(left_page)) {
+	left_next_rec = page_rec_get_next(orig_pred);
+	left_supremum = page_get_supremum_rec(left_page);
+
+	if (UNIV_LIKELY(left_next_rec != left_supremum)) {
 
 		/* Inherit the locks on the supremum of the left page to the
 		first record which was moved from the right page */
 
-		lock_rec_inherit_to_gap(page_rec_get_next(orig_pred),
-					page_get_supremum_rec(left_page));
+		lock_rec_inherit_to_gap(left_next_rec, left_supremum);
 
 		/* Reset the locks on the supremum of the left page,
 		releasing waiting transactions */
 
-		lock_rec_reset_and_release_wait(page_get_supremum_rec(
-								left_page));
+		lock_rec_reset_and_release_wait(left_supremum);
 	}
 
 	/* Move the locks from the supremum of right page to the supremum
 	of the left page */
 	
-	lock_rec_move(page_get_supremum_rec(left_page),
-				page_get_supremum_rec(right_page), comp);
+	lock_rec_move(left_supremum, page_get_supremum_rec(right_page), comp);
 
 	lock_rec_free_all_from_discard_page(right_page);
 
@@ -3028,7 +3040,7 @@ lock_update_discard(
 
 		lock_rec_reset_and_release_wait(rec);
 
-		if (rec == page_get_supremum_rec(page)) {
+		if (page_rec_is_supremum(rec)) {
 
 			break;
 		}
@@ -3091,19 +3103,16 @@ actual record is being moved. */
 void
 lock_rec_store_on_page_infimum(
 /*===========================*/
+	page_t*	page,	/* in: page containing the record */
 	rec_t*	rec)	/* in: record whose lock state is stored
 			on the infimum record of the same page; lock
 			bits are reset on the record */
 {
-	page_t*	page;
-	ibool	comp;
-
-	page = buf_frame_align(rec);
-	comp = page_is_comp(page);
+	ut_ad(page == buf_frame_align(rec));
 
 	lock_mutex_enter_kernel();
 	
-	lock_rec_move(page_get_infimum_rec(page), rec, comp);
+	lock_rec_move(page_get_infimum_rec(page), rec, page_is_comp(page));
 
 	lock_mutex_exit_kernel();	
 }
@@ -3120,10 +3129,10 @@ lock_rec_restore_from_page_infimum(
 			whose infimum stored the lock state; lock bits are
 			reset on the infimum */ 
 {
-	ibool	comp;
+	ulint	comp;
 	lock_mutex_enter_kernel();
 	comp = page_is_comp(page);
-	ut_ad(comp == page_is_comp(buf_frame_align(rec)));
+	ut_ad(!comp == !page_rec_is_comp(rec));
 
 	lock_rec_move(rec, page_get_infimum_rec(page), comp);
 	
@@ -3316,11 +3325,11 @@ lock_deadlock_recursive(
 				} else {
 					lock_table_print(ef, start->wait_lock);
 				}
-
+#ifdef UNIV_DEBUG
 				if (lock_print_waits) {
 					fputs("Deadlock detected\n", stderr);
 				}
-
+#endif /* UNIV_DEBUG */
 				if (ut_dulint_cmp(wait_lock->trx->undo_no,
 							start->undo_no) >= 0) {
 					/* Our recursion starting point
@@ -3418,14 +3427,6 @@ lock_table_create(
 	lock->type_mode = type_mode | LOCK_TABLE;
 	lock->trx = trx;
 
-	if (lock_get_type(lock) == LOCK_TABLE_EXP) {
-		lock->trx->n_lock_table_exp++;
-	}
-
-	if (lock_get_type(lock) == LOCK_TABLE_TRANSACTIONAL) {
-		lock->trx->n_lock_table_transactional++;
-	}
-
 	lock->un_member.tab_lock.table = table;
 
 	UT_LIST_ADD_LAST(un_member.tab_lock.locks, table->locks, lock);
@@ -3462,14 +3463,6 @@ lock_table_remove_low(
 		trx->auto_inc_lock = NULL;
 	}
 
-	if (lock_get_type(lock) == LOCK_TABLE_EXP) {
-		trx->n_lock_table_exp--;
-	}
-
-        if (lock_get_type(lock) == LOCK_TABLE_TRANSACTIONAL) {
-		trx->n_lock_table_transactional--;
-	}
-
 	UT_LIST_REMOVE(trx_locks, trx->trx_locks, lock);
 	UT_LIST_REMOVE(un_member.tab_lock.locks, table->locks, lock);
 }	
@@ -3600,10 +3593,7 @@ lock_table(
 				/* out: DB_SUCCESS, DB_LOCK_WAIT,
 				DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
 	ulint		flags,	/* in: if BTR_NO_LOCKING_FLAG bit is set,
-				does nothing;
-				if LOCK_TABLE_EXP|LOCK_TABLE_TRANSACTIONAL
-				bits are set,
-				creates an explicit table lock */
+				does nothing */
 	dict_table_t*	table,	/* in: database table in dictionary cache */
 	ulint		mode,	/* in: lock mode */
 	que_thr_t*	thr)	/* in: query thread */
@@ -3618,8 +3608,7 @@ lock_table(
 		return(DB_SUCCESS);
 	}
 
-	ut_a(flags == 0 || flags == LOCK_TABLE_EXP || 
-					flags == LOCK_TABLE_TRANSACTIONAL);
+	ut_a(flags == 0);
 
 	trx = thr_get_trx(thr);
 
@@ -3732,9 +3721,7 @@ lock_table_dequeue(
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&kernel_mutex));
 #endif /* UNIV_SYNC_DEBUG */
-	ut_a(lock_get_type(in_lock) == LOCK_TABLE ||
-		lock_get_type(in_lock) == LOCK_TABLE_EXP ||
-		lock_get_type(in_lock) == LOCK_TABLE_TRANSACTIONAL);
+	ut_a(lock_get_type(in_lock) == LOCK_TABLE);
 
 	lock = UT_LIST_GET_NEXT(un_member.tab_lock.locks, in_lock);
 
@@ -3838,12 +3825,6 @@ lock_release_off_kernel(
 			}
 
 			lock_table_dequeue(lock);
-
-			if (lock_get_type(lock) == LOCK_TABLE_EXP ||
-			    lock_get_type(lock) == LOCK_TABLE_TRANSACTIONAL) {
-				ut_a(lock_get_mode(lock) == LOCK_S
-					|| lock_get_mode(lock) == LOCK_X);
-			}
 		}
 
 		if (count == LOCK_RELEASE_KERNEL_INTERVAL) {
@@ -3863,74 +3844,6 @@ lock_release_off_kernel(
 	mem_heap_empty(trx->lock_heap);
 
 	ut_a(trx->auto_inc_lock == NULL);
-	ut_a(trx->n_lock_table_exp == 0);
-	ut_a(trx->n_lock_table_transactional == 0);
-}
-
-/*************************************************************************
-Releases table locks explicitly requested with LOCK TABLES (indicated by
-lock type LOCK_TABLE_EXP), and releases possible other transactions waiting
-because of these locks. */
-
-void
-lock_release_tables_off_kernel(
-/*===========================*/
-	trx_t*	trx)	/* in: transaction */
-{
-	dict_table_t*	table;
-	ulint		count;
-	lock_t*		lock;
-
-#ifdef UNIV_SYNC_DEBUG
-	ut_ad(mutex_own(&kernel_mutex));
-#endif /* UNIV_SYNC_DEBUG */
-
-	lock = UT_LIST_GET_LAST(trx->trx_locks);
-
-	count = 0;
-
-	while (lock != NULL) {
-
-		count++;
-
-		if (lock_get_type(lock) == LOCK_TABLE_EXP) {
-			ut_a(lock_get_mode(lock) == LOCK_S
-				|| lock_get_mode(lock) == LOCK_X);
-			if (trx->insert_undo || trx->update_undo) {
-
-				/* The trx may have modified the table.
-				We block the use of the MySQL query
-				cache for all currently active
-				transactions. */
-
-				table = lock->un_member.tab_lock.table;
-
-				table->query_cache_inv_trx_id =
-							trx_sys->max_trx_id;
-			}
-
-			lock_table_dequeue(lock);
-
-			lock = UT_LIST_GET_LAST(trx->trx_locks);
-			continue;
-		}
-
-		if (count == LOCK_RELEASE_KERNEL_INTERVAL) {
-			/* Release the kernel mutex for a while, so that we
-			do not monopolize it */
-
-			lock_mutex_exit_kernel();
-
-			lock_mutex_enter_kernel();
-
-			count = 0;
-		}
-
-		lock = UT_LIST_GET_PREV(trx_locks, lock);
-	}
-
-	ut_a(trx->n_lock_table_exp == 0);
-	ut_a(trx->n_lock_table_transactional == 0);
 }
 
 /*************************************************************************
@@ -4043,15 +3956,7 @@ lock_table_print(
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&kernel_mutex));
 #endif /* UNIV_SYNC_DEBUG */
-	ut_a(lock_get_type(lock) == LOCK_TABLE ||
-		lock_get_type(lock) == LOCK_TABLE_EXP ||
-		lock_get_type(lock) == LOCK_TABLE_TRANSACTIONAL);
-
-	if (lock_get_type(lock) == LOCK_TABLE_EXP) {
-		fputs("EXPLICIT ", file);
-	} else if (lock_get_type(lock) == LOCK_TABLE_TRANSACTIONAL) {
-		fputs("TRANSACTIONAL ", file);
-	}
+	ut_a(lock_get_type(lock) == LOCK_TABLE);
 
 	fputs("TABLE LOCK table ", file);
 	ut_print_name(file, lock->trx, lock->un_member.tab_lock.table->name);
@@ -4187,7 +4092,7 @@ lock_rec_print(
 	}
 
 	mtr_commit(&mtr);
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 }
@@ -4483,15 +4388,14 @@ lock_rec_queue_validate(
 {
 	trx_t*	impl_trx;	
 	lock_t*	lock;
-	ibool	comp;
 
 	ut_a(rec);
 	ut_ad(rec_offs_validate(rec, index, offsets));
-	comp = page_is_comp(buf_frame_align(rec));
+	ut_ad(!page_rec_is_comp(rec) == !rec_offs_comp(offsets));
 
 	lock_mutex_enter_kernel();
 
-	if (page_rec_is_supremum(rec) || page_rec_is_infimum(rec)) {
+	if (!page_rec_is_user_rec(rec)) {
 
 		lock = lock_rec_get_first(rec);
 
@@ -4511,7 +4415,7 @@ lock_rec_queue_validate(
 				ut_a(lock->index == index);
 			}
 
-			lock = lock_rec_get_next(rec, comp, lock);
+			lock = lock_rec_get_next(rec, lock);
 		}
 
 		lock_mutex_exit_kernel();
@@ -4524,10 +4428,10 @@ lock_rec_queue_validate(
 		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, comp, impl_trx)) {
+				LOCK_WAIT, rec, impl_trx)) {
 
 			ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, rec,
-							comp, impl_trx));
+							impl_trx));
 		}
 	}
 
@@ -4541,10 +4445,10 @@ lock_rec_queue_validate(
 				rec, index, offsets);
 
 		if (impl_trx && lock_rec_other_has_expl_req(LOCK_S, 0,
-				LOCK_WAIT, rec, comp, impl_trx)) {
+				LOCK_WAIT, rec, impl_trx)) {
 
 			ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP,
-						rec, comp, impl_trx));
+						rec, impl_trx));
 		}
 	}
 
@@ -4561,21 +4465,23 @@ lock_rec_queue_validate(
 		}
 
 		if (!lock_rec_get_gap(lock) && !lock_get_wait(lock)) {
+
+			ulint	mode;
 		
 			if (lock_get_mode(lock) == LOCK_S) {
-				ut_a(!lock_rec_other_has_expl_req(LOCK_X,
-						0, 0, rec, comp, lock->trx));
+				mode = LOCK_X;
 			} else {
-				ut_a(!lock_rec_other_has_expl_req(LOCK_S,
-						0, 0, rec, comp, lock->trx));
+				mode = LOCK_S;
 			}
+			ut_a(!lock_rec_other_has_expl_req(mode,
+						0, 0, rec, 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, comp, lock);
+		lock = lock_rec_get_next(rec, lock);
 	}
 
 	lock_mutex_exit_kernel();
@@ -4673,7 +4579,7 @@ function_exit:
 
 	mtr_commit(&mtr);
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	return(TRUE);
@@ -4859,7 +4765,7 @@ lock_rec_insert_check_and_lock(
 		offsets = rec_get_offsets(next_rec, index, offsets_,
 						ULINT_UNDEFINED, &heap);
 		ut_ad(lock_rec_queue_validate(next_rec, index, offsets));
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 	}
@@ -4887,7 +4793,7 @@ lock_rec_convert_impl_to_expl(
 #endif /* UNIV_SYNC_DEBUG */
 	ut_ad(page_rec_is_user_rec(rec));
 	ut_ad(rec_offs_validate(rec, index, offsets));
-	ut_ad(page_is_comp(buf_frame_align(rec)) == index->table->comp);
+	ut_ad(!page_rec_is_comp(rec) == !rec_offs_comp(offsets));
 
 	if (index->type & DICT_CLUSTERED) {
 		impl_trx = lock_clust_rec_some_has_impl(rec, index, offsets);
@@ -4901,7 +4807,7 @@ lock_rec_convert_impl_to_expl(
 		record, set one for it */
 
 		if (!lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, rec,
-					index->table->comp, impl_trx)) {
+					impl_trx)) {
 
 			lock_rec_add_to_queue(LOCK_REC | LOCK_X
 					      | LOCK_REC_NOT_GAP, rec, index,
@@ -5008,7 +4914,7 @@ lock_sec_rec_modify_check_and_lock(
 		offsets = rec_get_offsets(rec, index, offsets_,
 						ULINT_UNDEFINED, &heap);
 		ut_ad(lock_rec_queue_validate(rec, index, offsets));
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 	}
diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c
index 560f51401acf6f0fe1fccd19d347a7d337cb99d4..5953262ece7920814022ecb52aeee3a80e42e9ff 100644
--- a/innobase/log/log0log.c
+++ b/innobase/log/log0log.c
@@ -57,10 +57,11 @@ ulint	log_fsp_current_free_limit		= 0;
 /* Global log system variable */
 log_t*	log_sys	= NULL;
 
+#ifdef UNIV_DEBUG
 ibool	log_do_write = TRUE;
 
 ibool	log_debug_writes = FALSE;
-
+#endif /* UNIV_DEBUG */
 
 /* These control how often we print warnings if the last checkpoint is too
 old */
@@ -974,22 +975,24 @@ log_group_check_flush_completion(
 #endif /* UNIV_SYNC_DEBUG */
 
 	if (!log_sys->one_flushed && group->n_pending_writes == 0) {
+#ifdef UNIV_DEBUG
 		if (log_debug_writes) {
 			fprintf(stderr,
 				"Log flushed first to group %lu\n", (ulong) group->id);
 		}
-	
+#endif /* UNIV_DEBUG */
 		log_sys->written_to_some_lsn = log_sys->write_lsn;
 		log_sys->one_flushed = TRUE;
 
 		return(LOG_UNLOCK_NONE_FLUSHED_LOCK);
 	}
 
+#ifdef UNIV_DEBUG
 	if (log_debug_writes && (group->n_pending_writes == 0)) {
 
 		fprintf(stderr, "Log flushed to group %lu\n", (ulong) group->id);
 	}
-
+#endif /* UNIV_DEBUG */
 	return(0);
 }
 
@@ -1066,12 +1069,13 @@ log_io_complete(
 		        fil_flush(group->space_id);
 		}
 
+#ifdef UNIV_DEBUG
 		if (log_debug_writes) {
 			fprintf(stderr,
 				"Checkpoint info written to group %lu\n",
 				group->id);
 		}
-
+#endif /* UNIV_DEBUG */
 		log_io_complete_checkpoint();
 
 		return;
@@ -1133,12 +1137,13 @@ log_group_file_header_flush(
 
 	dest_offset = nth_file * group->file_size;
 
+#ifdef UNIV_DEBUG
 	if (log_debug_writes) {
 		fprintf(stderr,
 			"Writing log file header to group %lu file %lu\n",
 			(ulong) group->id, (ulong) nth_file);
 	}
-
+#endif /* UNIV_DEBUG */
 	if (log_do_write) {
 		log_sys->n_log_ios++;	
 		
@@ -1226,7 +1231,8 @@ loop:
 	} else {
 		write_len = len;
 	}
-	
+
+#ifdef UNIV_DEBUG
 	if (log_debug_writes) {
 
 		fprintf(stderr,
@@ -1250,7 +1256,7 @@ loop:
 					+ i * OS_FILE_LOG_BLOCK_SIZE));
 		}
 	}
-
+#endif /* UNIV_DEBUG */
 	/* Calculate the checksums for each log block and write them to
 	the trailer fields of the log blocks */
 
@@ -1384,6 +1390,7 @@ loop:
 		return;
 	}
 
+#ifdef UNIV_DEBUG
 	if (log_debug_writes) {
 		fprintf(stderr,
 			"Writing log from %lu %lu up to lsn %lu %lu\n",
@@ -1392,7 +1399,7 @@ loop:
 			(ulong) ut_dulint_get_high(log_sys->lsn),
 			(ulong)	ut_dulint_get_low(log_sys->lsn));
 	}
-
+#endif /* UNIV_DEBUG */
 	log_sys->n_pending_writes++;
 
 	group = UT_LIST_GET_FIRST(log_sys->log_groups);
@@ -1961,12 +1968,14 @@ log_checkpoint(
 
 	log_sys->next_checkpoint_lsn = oldest_lsn;
 
+#ifdef UNIV_DEBUG
 	if (log_debug_writes) {
 		fprintf(stderr, "Making checkpoint no %lu at lsn %lu %lu\n",
 			(ulong) ut_dulint_get_low(log_sys->next_checkpoint_no),
 			(ulong) ut_dulint_get_high(oldest_lsn),
 			(ulong) ut_dulint_get_low(oldest_lsn));
 	}
+#endif /* UNIV_DEBUG */
 
 	log_groups_write_checkpoint_info();
 
@@ -2029,8 +2038,6 @@ log_checkpoint_margin(void)
 	ulint	checkpoint_age;
 	ulint	advance;
 	dulint	oldest_lsn;
-	dulint	new_oldest;
-	ibool	do_preflush;
 	ibool	sync;
 	ibool	checkpoint_sync;
 	ibool	do_checkpoint;
@@ -2038,7 +2045,6 @@ log_checkpoint_margin(void)
 loop:
 	sync = FALSE;
 	checkpoint_sync = FALSE;
-	do_preflush = FALSE;
 	do_checkpoint = FALSE;
 
 	mutex_enter(&(log->mutex));
@@ -2058,21 +2064,13 @@ loop:
 		/* A flush is urgent: we have to do a synchronous preflush */
 
 		sync = TRUE;
-	
-		advance = 2 * (age - log->max_modified_age_sync);
-
-		new_oldest = ut_dulint_add(oldest_lsn, advance);
-
-		do_preflush = TRUE;
-
+		advance = 2 * (age - log->max_modified_age_async);
 	} else if (age > log->max_modified_age_async) {
 
 		/* A flush is not urgent: we do an asynchronous preflush */
 		advance = age - log->max_modified_age_async;
-
-		new_oldest = ut_dulint_add(oldest_lsn, advance);
-
-		do_preflush = TRUE;
+	} else {
+		advance = 0;
 	}
 
 	checkpoint_age = ut_dulint_minus(log->lsn, log->last_checkpoint_lsn);
@@ -2096,7 +2094,9 @@ loop:
 	
 	mutex_exit(&(log->mutex));
 
-	if (do_preflush) {
+	if (advance) {
+		dulint	new_oldest = ut_dulint_add(oldest_lsn, advance);
+
 		success = log_preflush_pool_modified_pages(new_oldest, sync);
 
 		/* If the flush succeeded, this thread has done its part
@@ -2347,9 +2347,11 @@ loop:
 			exit(1);
 		}
 
+#ifdef UNIV_DEBUG
 		if (log_debug_writes) {
 			fprintf(stderr, "Created archive file %s\n", name);
 		}
+#endif /* UNIV_DEBUG */
 
 		ret = os_file_close(file_handle);
 	
@@ -2375,7 +2377,8 @@ loop:
 
 		len = group->file_size - (next_offset % group->file_size);
 	}
-	
+
+#ifdef UNIV_DEBUG
 	if (log_debug_writes) {
 		fprintf(stderr,
 		"Archiving starting at lsn %lu %lu, len %lu to group %lu\n",
@@ -2383,6 +2386,7 @@ loop:
 					(ulong) ut_dulint_get_low(start_lsn),
 					(ulong) len, (ulong) group->id);
 	}
+#endif /* UNIV_DEBUG */
 
 	log_sys->n_pending_archive_ios++;
 
@@ -2473,11 +2477,13 @@ log_archive_write_complete_groups(void)
 		trunc_files = n_files - 1;
 	}
 
+#ifdef UNIV_DEBUG
 	if (log_debug_writes && trunc_files) {
 		fprintf(stderr,
 			"Complete file(s) archived to group %lu\n",
 							  (ulong) group->id);
 	}
+#endif /* UNIV_DEBUG */
 
 	/* Calculate the archive file space start lsn */
 	start_lsn = ut_dulint_subtract(log_sys->next_archived_lsn,
@@ -2500,9 +2506,11 @@ log_archive_write_complete_groups(void)
 	fil_space_truncate_start(group->archive_space_id,
 					trunc_files * group->file_size);
 
+#ifdef UNIV_DEBUG
 	if (log_debug_writes) {
 		fputs("Archiving writes completed\n", stderr);
 	}
+#endif /* UNIV_DEBUG */
 }
 
 /**********************************************************
@@ -2519,9 +2527,11 @@ log_archive_check_completion_low(void)
 	if (log_sys->n_pending_archive_ios == 0
 			&& log_sys->archiving_phase == LOG_ARCHIVE_READ) {
 
+#ifdef UNIV_DEBUG
 		if (log_debug_writes) {
 			fputs("Archiving read completed\n", stderr);
 		}
+#endif /* UNIV_DEBUG */
 
 	    	/* Archive buffer has now been read in: start archive writes */
 
@@ -2665,6 +2675,7 @@ loop:
 
 	log_sys->next_archived_lsn = limit_lsn;
 
+#ifdef UNIV_DEBUG
 	if (log_debug_writes) {
 		fprintf(stderr,
 			"Archiving from lsn %lu %lu to lsn %lu %lu\n",
@@ -2673,6 +2684,7 @@ loop:
 			(ulong) ut_dulint_get_high(limit_lsn),
 			(ulong) ut_dulint_get_low(limit_lsn));
 	}
+#endif /* UNIV_DEBUG */
 
 	/* Read the log segment to the archive buffer */
 	
@@ -2775,12 +2787,14 @@ log_archive_close_groups(
 			group->archived_file_no += 2;
 		}
 
+#ifdef UNIV_DEBUG
 		if (log_debug_writes) {
 			fprintf(stderr,
 			"Incrementing arch file no to %lu in log group %lu\n",
 				(ulong) group->archived_file_no + 2,
 			        (ulong) group->id);
 		}
+#endif /* UNIV_DEBUG */
 	}
 }
 
diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c
index 6597122f1047e344c2c1bdeaeeaff4140334a4fb..0417d01d89ad5e66c73ab23153738c124ef8e74f 100644
--- a/innobase/log/log0recv.c
+++ b/innobase/log/log0recv.c
@@ -489,6 +489,7 @@ recv_find_max_checkpoint(
 			log_group_read_checkpoint_info(group, field);
 
 			if (!recv_check_cp_is_consistent(buf)) {
+#ifdef UNIV_DEBUG
 				if (log_debug_writes) {
 					fprintf(stderr, 
 	    "InnoDB: Checkpoint in group %lu at %lu invalid, %lu\n",
@@ -498,7 +499,7 @@ recv_find_max_checkpoint(
 					      + LOG_CHECKPOINT_CHECKSUM_1));
 
 				}
-
+#endif /* UNIV_DEBUG */
 				goto not_consistent;
 			}
 
@@ -511,13 +512,15 @@ recv_find_max_checkpoint(
 			checkpoint_no =
 				mach_read_from_8(buf + LOG_CHECKPOINT_NO);
 
+#ifdef UNIV_DEBUG
 			if (log_debug_writes) {
 				fprintf(stderr, 
 			"InnoDB: Checkpoint number %lu found in group %lu\n",
 				(ulong) ut_dulint_get_low(checkpoint_no),
 				(ulong) group->id);
 			}
-				
+#endif /* UNIV_DEBUG */
+
 			if (ut_dulint_cmp(checkpoint_no, max_no) >= 0) {
 				*max_group = group;
 				*max_field = field;
@@ -540,7 +543,7 @@ recv_find_max_checkpoint(
 "InnoDB: to create the InnoDB data files, but log file creation failed.\n"
 "InnoDB: If that is the case, please refer to\n"
 "InnoDB: http://dev.mysql.com/doc/mysql/en/Error_creating_InnoDB.html\n");
-
+		*max_field = 0;
 		return(DB_ERROR);
 	}
 
@@ -765,6 +768,7 @@ recv_parse_or_apply_log_rec_body(
 	case MLOG_REC_INSERT: case MLOG_COMP_REC_INSERT:
 		if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
 				type == MLOG_COMP_REC_INSERT, &index))) {
+			ut_a(!page||!!page_is_comp(page)==index->table->comp);
 			ptr = page_cur_parse_insert_rec(FALSE, ptr, end_ptr,
 							index, page, mtr);
 		}
@@ -772,20 +776,27 @@ recv_parse_or_apply_log_rec_body(
 	case MLOG_REC_CLUST_DELETE_MARK: case MLOG_COMP_REC_CLUST_DELETE_MARK:
 		if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
 			type == MLOG_COMP_REC_CLUST_DELETE_MARK, &index))) {
+			ut_a(!page||!!page_is_comp(page)==index->table->comp);
 			ptr = btr_cur_parse_del_mark_set_clust_rec(ptr,
 						end_ptr, index, page);
 		}
 		break;
-	case MLOG_REC_SEC_DELETE_MARK: case MLOG_COMP_REC_SEC_DELETE_MARK:
-		if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
-			type == MLOG_COMP_REC_SEC_DELETE_MARK, &index))) {
-			ptr = btr_cur_parse_del_mark_set_sec_rec(ptr, end_ptr,
-								index, page);
+	case MLOG_COMP_REC_SEC_DELETE_MARK:
+		/* This log record type is obsolete, but we process it for
+		backward compatibility with MySQL 5.0.3 and 5.0.4. */
+		ut_a(!page || page_is_comp(page));
+		ptr = mlog_parse_index(ptr, end_ptr, TRUE, &index);
+		if (!ptr) {
+			break;
 		}
+		/* Fall through */
+	case MLOG_REC_SEC_DELETE_MARK:
+		ptr = btr_cur_parse_del_mark_set_sec_rec(ptr, end_ptr, page);
 		break;
 	case MLOG_REC_UPDATE_IN_PLACE: case MLOG_COMP_REC_UPDATE_IN_PLACE:
 		if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
 			type == MLOG_COMP_REC_UPDATE_IN_PLACE, &index))) {
+			ut_a(!page||!!page_is_comp(page)==index->table->comp);
 			ptr = btr_cur_parse_update_in_place(ptr, end_ptr,
 							page, index);
 		}
@@ -795,6 +806,7 @@ recv_parse_or_apply_log_rec_body(
 		if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
 			type == MLOG_COMP_LIST_END_DELETE
 			|| type == MLOG_COMP_LIST_START_DELETE, &index))) {
+			ut_a(!page||!!page_is_comp(page)==index->table->comp);
 			ptr = page_parse_delete_rec_list(type, ptr, end_ptr,
 							index, page, mtr);
 		}
@@ -802,6 +814,7 @@ recv_parse_or_apply_log_rec_body(
 	case MLOG_LIST_END_COPY_CREATED: case MLOG_COMP_LIST_END_COPY_CREATED:
 		if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
 			type == MLOG_COMP_LIST_END_COPY_CREATED, &index))) {
+			ut_a(!page||!!page_is_comp(page)==index->table->comp);
 			ptr = page_parse_copy_rec_list_to_created_page(ptr,
 						end_ptr, index, page, mtr);
 		}
@@ -809,6 +822,7 @@ recv_parse_or_apply_log_rec_body(
 	case MLOG_PAGE_REORGANIZE: case MLOG_COMP_PAGE_REORGANIZE:
 		if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
 				type == MLOG_COMP_PAGE_REORGANIZE, &index))) {
+			ut_a(!page||!!page_is_comp(page)==index->table->comp);
 			ptr = btr_parse_page_reorganize(ptr, end_ptr, index,
 								page, mtr);
 		}
@@ -841,6 +855,7 @@ recv_parse_or_apply_log_rec_body(
 	case MLOG_REC_DELETE: case MLOG_COMP_REC_DELETE:
 		if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
 				type == MLOG_COMP_REC_DELETE, &index))) {
+			ut_a(!page||!!page_is_comp(page)==index->table->comp);
 			ptr = page_cur_parse_delete_rec(ptr, end_ptr,
 							index, page, mtr);
 		}
@@ -1186,6 +1201,7 @@ recv_recover_page(
 				start_lsn = recv->start_lsn;
 			}
 
+#ifdef UNIV_DEBUG
 			if (log_debug_writes) {
 				fprintf(stderr, 
      "InnoDB: Applying log rec type %lu len %lu to space %lu page no %lu\n",
@@ -1193,6 +1209,7 @@ recv_recover_page(
 					(ulong) recv_addr->space,
 					(ulong) recv_addr->page_no);
 			}
+#endif /* UNIV_DEBUG */
 
 			recv_parse_or_apply_log_rec_body(recv->type, buf,
 						buf + recv->len, page, &mtr);
@@ -1801,25 +1818,25 @@ recv_parse_log_rec(
 
 	new_ptr = mlog_parse_initial_log_record(ptr, end_ptr, type, space,
 								page_no);
-	if (!new_ptr) {
+	*body = new_ptr;
+
+	if (UNIV_UNLIKELY(!new_ptr)) {
 
 	        return(0);
 	}
 
 	/* Check that page_no is sensible */
 
-	if (*page_no > 0x8FFFFFFFUL) {
+	if (UNIV_UNLIKELY(*page_no > 0x8FFFFFFFUL)) {
 
 		recv_sys->found_corrupt_log = TRUE;
 
 		return(0);
 	}
 
-	*body = new_ptr;
-
 	new_ptr = recv_parse_or_apply_log_rec_body(*type, new_ptr, end_ptr,
 								NULL, NULL);
-	if (new_ptr == NULL) {
+	if (UNIV_UNLIKELY(new_ptr == NULL)) {
 
 		return(0);
 	}
@@ -2013,12 +2030,14 @@ loop:
 		recv_sys->recovered_offset += len;
 		recv_sys->recovered_lsn = new_recovered_lsn;
 
+#ifdef UNIV_DEBUG
 		if (log_debug_writes) {
 			fprintf(stderr, 
 "InnoDB: Parsed a single log rec type %lu len %lu space %lu page no %lu\n",
 				(ulong) type, (ulong) len, (ulong) space,
 				(ulong) page_no);
 		}
+#endif /* UNIV_DEBUG */
 
 		if (type == MLOG_DUMMY_RECORD) {
 			/* Do nothing */
@@ -2101,13 +2120,15 @@ loop:
 							body, ptr + len);
 #endif /* UNIV_LOG_REPLICATE */
 			}
-			
+
+#ifdef UNIV_DEBUG
 			if (log_debug_writes) {
 				fprintf(stderr, 
 "InnoDB: Parsed a multi log rec type %lu len %lu space %lu page no %lu\n",
 				(ulong) type, (ulong) len, (ulong) space,
 				(ulong) page_no);
 			}
+#endif /* UNIV_DEBUG */
 
 			total_len += len;
 			n_recs++;
@@ -2514,6 +2535,7 @@ recv_group_scan_log_recs(
 		start_lsn = end_lsn;
 	}
 
+#ifdef UNIV_DEBUG
 	if (log_debug_writes) {
 		fprintf(stderr,
 	"InnoDB: Scanned group %lu up to log sequence number %lu %lu\n",
@@ -2521,6 +2543,7 @@ recv_group_scan_log_recs(
 				(ulong) ut_dulint_get_high(*group_scanned_lsn),
 				(ulong) ut_dulint_get_low(*group_scanned_lsn));
 	}
+#endif /* UNIV_DEBUG */
 }
 
 /************************************************************
@@ -2906,10 +2929,12 @@ recv_recovery_from_checkpoint_finish(void)
 		recv_apply_hashed_log_recs(TRUE);
 	}
 
+#ifdef UNIV_DEBUG
 	if (log_debug_writes) {
 		fprintf(stderr,
 		"InnoDB: Log records applied to the database\n");
 	}
+#endif /* UNIV_DEBUG */
 
 	if (recv_needed_recovery) {
 		trx_sys_print_mysql_master_log_pos();
@@ -3246,6 +3271,7 @@ ask_again:
 			break;
 		}
 	
+#ifdef UNIV_DEBUG
 		if (log_debug_writes) {
 			fprintf(stderr, 
 "InnoDB: Archive read starting at lsn %lu %lu, len %lu from file %s\n",
@@ -3253,6 +3279,7 @@ ask_again:
 					(ulong) ut_dulint_get_low(start_lsn),
 					(ulong) len, name);
 		}
+#endif /* UNIV_DEBUG */
 
 		fil_io(OS_FILE_READ | OS_FILE_LOG, TRUE,
 			group->archive_space_id, read_offset / UNIV_PAGE_SIZE,
diff --git a/innobase/mtr/mtr0log.c b/innobase/mtr/mtr0log.c
index 4f826f242e8b0d98a8c8a3b8bd97dd36b6b1a375..0308619073af08b19f857e2b448ac8f9d75c77e9 100644
--- a/innobase/mtr/mtr0log.c
+++ b/innobase/mtr/mtr0log.c
@@ -15,6 +15,7 @@ Created 12/7/1995 Heikki Tuuri
 #include "buf0buf.h"
 #include "dict0boot.h"
 #include "log0recv.h"
+#include "page0page.h"
 
 /************************************************************
 Catenates n bytes to the mtr log. */
@@ -22,9 +23,9 @@ Catenates n bytes to the mtr log. */
 void
 mlog_catenate_string(
 /*=================*/
-	mtr_t*	mtr,	/* in: mtr */
-	byte*	str,	/* in: string to write */
-	ulint	len)	/* in: string length */
+	mtr_t*		mtr,	/* in: mtr */
+	const byte*	str,	/* in: string to write */
+	ulint		len)	/* in: string length */
 {
 	dyn_array_t*	mlog;
 
@@ -301,14 +302,15 @@ corresponding log record to the mini-transaction log. */
 void
 mlog_write_string(
 /*==============*/
-	byte*	ptr,	/* in: pointer where to write */
-	byte*	str,	/* in: string to write */
-	ulint	len,	/* in: string length */
-	mtr_t*	mtr)	/* in: mini-transaction handle */
+	byte*		ptr,	/* in: pointer where to write */
+	const byte*	str,	/* in: string to write */
+	ulint		len,	/* in: string length */
+	mtr_t*		mtr)	/* in: mini-transaction handle */
 {
 	byte*	log_ptr;
 
-	if (ptr < buf_pool->frame_zero || ptr >= buf_pool->high_end) {
+	if (UNIV_UNLIKELY(ptr < buf_pool->frame_zero)
+	    || UNIV_UNLIKELY(ptr >= buf_pool->high_end)) {
 		fprintf(stderr,
 	"InnoDB: Error: trying to write to a stray memory location %p\n", ptr);
 		ut_error;
@@ -405,7 +407,9 @@ mlog_open_and_write_index(
 	const byte*	log_start;
 	const byte*	log_end;
 
-	if (!index->table->comp) {
+	ut_ad(!!page_rec_is_comp(rec) == index->table->comp);
+
+	if (!page_rec_is_comp(rec)) {
 		log_start = log_ptr = mlog_open(mtr, 11 + size);
 		if (!log_ptr) {
 			return(NULL); /* logging is disabled */
@@ -498,6 +502,8 @@ mlog_parse_index(
 	dict_table_t*	table;
 	dict_index_t*	ind;
 
+	ut_ad(comp == FALSE || comp == TRUE);
+
 	if (comp) {
 		if (end_ptr < ptr + 4) {
 			return(NULL);
diff --git a/innobase/mtr/mtr0mtr.c b/innobase/mtr/mtr0mtr.c
index 6e918806eb1c68f356ad746fd8e5f69fdd325ae9..da045be1f6291edb75f0a180ea5cf5f9b968b11b 100644
--- a/innobase/mtr/mtr0mtr.c
+++ b/innobase/mtr/mtr0mtr.c
@@ -48,16 +48,11 @@ mtr_memo_slot_release(
 	object = slot->object;
 	type = slot->type;
 
-	if (object != NULL) {
+	if (UNIV_LIKELY(object != NULL)) {
 		if (type <= MTR_MEMO_BUF_FIX) {
 			buf_page_release((buf_block_t*)object, type, mtr);
 		} else if (type == MTR_MEMO_S_LOCK) {
 			rw_lock_s_unlock((rw_lock_t*)object);
-#ifndef UNIV_DEBUG
-		} else {
-			rw_lock_x_unlock((rw_lock_t*)object);
-		}
-#endif
 #ifdef UNIV_DEBUG
 		} else if (type == MTR_MEMO_X_LOCK) {
 			rw_lock_x_unlock((rw_lock_t*)object);
@@ -65,8 +60,11 @@ mtr_memo_slot_release(
 			ut_ad(type == MTR_MEMO_MODIFY);
 			ut_ad(mtr_memo_contains(mtr, object,
 						MTR_MEMO_PAGE_X_FIX));
-		}
+#else
+		} else {
+			rw_lock_x_unlock((rw_lock_t*)object);
 #endif
+		}
 	}
 
 	slot->object = NULL;
diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c
index ac5d1c72c7299fab8ed44ec29475e72bc0a3ec0f..8102f24f25acf70baf1f8ffebb7d32267c2aec7a 100644
--- a/innobase/os/os0file.c
+++ b/innobase/os/os0file.c
@@ -83,7 +83,7 @@ struct os_aio_slot_struct{
 					made and only the slot message
 					needs to be passed to the caller
 					of os_aio_simulated_handle */
-	void*		message1;	/* message which is given by the */
+	fil_node_t*	message1;	/* message which is given by the */
 	void*		message2;	/* the requester of an aio operation
 					and which can be used to identify
 					which pending aio operation was
@@ -133,17 +133,17 @@ os_event_t*	os_aio_segment_wait_events	= NULL;
 
 /* The aio arrays for non-ibuf i/o and ibuf i/o, as well as sync aio. These
 are NULL when the module has not yet been initialized. */
-os_aio_array_t*	os_aio_read_array	= NULL;
-os_aio_array_t*	os_aio_write_array	= NULL;
-os_aio_array_t*	os_aio_ibuf_array	= NULL;
-os_aio_array_t*	os_aio_log_array	= NULL;
-os_aio_array_t*	os_aio_sync_array	= NULL;
+static os_aio_array_t*	os_aio_read_array	= NULL;
+static os_aio_array_t*	os_aio_write_array	= NULL;
+static os_aio_array_t*	os_aio_ibuf_array	= NULL;
+static os_aio_array_t*	os_aio_log_array	= NULL;
+static os_aio_array_t*	os_aio_sync_array	= NULL;
 
-ulint	os_aio_n_segments	= ULINT_UNDEFINED;
+static ulint	os_aio_n_segments	= ULINT_UNDEFINED;
 
 /* If the following is TRUE, read i/o handler threads try to
 wait until a batch of new read requests have been posted */
-ibool	os_aio_recommend_sleep_for_read_threads	= FALSE;
+static ibool	os_aio_recommend_sleep_for_read_threads	= FALSE;
 
 ulint	os_n_file_reads		= 0;
 ulint	os_bytes_read_since_printout = 0;
@@ -158,7 +158,7 @@ ibool	os_has_said_disk_full	= FALSE;
 
 /* The mutex protecting the following counts of pending pread and pwrite
 operations */
-os_mutex_t os_file_count_mutex;
+static os_mutex_t os_file_count_mutex;
 ulint	os_file_n_pending_preads  = 0;
 ulint	os_file_n_pending_pwrites = 0;
 
@@ -3025,7 +3025,7 @@ os_aio_array_reserve_slot(
 				/* out: pointer to slot */
 	ulint		type,	/* in: OS_FILE_READ or OS_FILE_WRITE */
 	os_aio_array_t*	array,	/* in: aio array */
-	void*		message1,/* in: message to be passed along with
+	fil_node_t*	message1,/* in: message to be passed along with
 				the aio operation */
 	void*		message2,/* in: message to be passed along with
 				the aio operation */
@@ -3287,7 +3287,7 @@ os_aio(
 	ulint		offset_high, /* in: most significant 32 bits of
 				offset */
 	ulint		n,	/* in: number of bytes to read or write */
-	void*		message1,/* in: messages for the aio handler (these
+	fil_node_t*	message1,/* in: messages for the aio handler (these
 				can be used to identify a completed aio
 				operation); if mode is OS_AIO_SYNC, these
 				are ignored */
@@ -3472,7 +3472,7 @@ os_aio_windows_handle(
 				ignored */
 	ulint	pos,		/* this parameter is used only in sync aio:
 				wait for the aio slot at this position */  
-	void**	message1,	/* out: the messages passed with the aio
+	fil_node_t**message1,	/* out: the messages passed with the aio
 				request; note that also in the case where
 				the aio operation failed, these output
 				parameters are valid and can be used to
@@ -3563,7 +3563,7 @@ os_aio_posix_handle(
 /*================*/
 				/* out: TRUE if the aio operation succeeded */
 	ulint	array_no,	/* in: array number 0 - 3 */
-	void**	message1,	/* out: the messages passed with the aio
+	fil_node_t**message1,	/* out: the messages passed with the aio
 				request; note that also in the case where
 				the aio operation failed, these output
 				parameters are valid and can be used to
@@ -3644,7 +3644,7 @@ os_aio_simulated_handle(
 				i/o thread, segment 1 the log i/o thread,
 				then follow the non-ibuf read threads, and as
 				the last are the non-ibuf write threads */
-	void**	message1,	/* out: the messages passed with the aio
+	fil_node_t**message1,	/* out: the messages passed with the aio
 				request; note that also in the case where
 				the aio operation failed, these output
 				parameters are valid and can be used to
@@ -4182,6 +4182,7 @@ os_aio_refresh_stats(void)
 	os_last_printout = time(NULL);
 }
 
+#ifdef UNIV_DEBUG
 /**************************************************************************
 Checks that all slots in the system have been freed, that is, there are
 no pending io operations. */
@@ -4241,3 +4242,4 @@ os_aio_all_slots_free(void)
 
 	return(FALSE);
 }
+#endif /* UNIV_DEBUG */
diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c
index 7738f5a34f01b645aa3c85f151bca8b0e8358679..df6d898d4ac67f2e176f3139712b4e22c694a307 100644
--- a/innobase/page/page0cur.c
+++ b/innobase/page/page0cur.c
@@ -129,7 +129,7 @@ page_cur_try_search_shortcut(
 #endif
 	success = TRUE;
 exit_func:
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	return(success);
@@ -451,7 +451,7 @@ page_cur_search_with_match(
 	*iup_matched_bytes   = up_matched_bytes;
 	*ilow_matched_fields = low_matched_fields;
 	*ilow_matched_bytes  = low_matched_bytes;
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 }
@@ -515,8 +515,12 @@ page_cur_insert_rec_write_log(
 	byte*	log_ptr;
 	byte*	log_end;
 	ulint	i;
+	ulint	comp;
 
 	ut_a(rec_size < UNIV_PAGE_SIZE);
+	ut_ad(buf_frame_align(insert_rec) == buf_frame_align(cursor_rec));
+	ut_ad(!page_rec_is_comp(insert_rec) == !index->table->comp);
+	comp = page_rec_is_comp(insert_rec);
 
 	{
 		mem_heap_t*	heap		= NULL;
@@ -539,7 +543,7 @@ page_cur_insert_rec_write_log(
 		ut_ad(rec_size == rec_offs_size(ins_offs));
 		cur_rec_size = rec_offs_size(cur_offs);
 
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 	}
@@ -565,7 +569,7 @@ page_cur_insert_rec_write_log(
 				ins_ptr++;
 				cur_ptr++;
 			} else if ((i < extra_size)
-				   && (i >= extra_size - (index->table->comp
+				   && (i >= extra_size - (comp
 					? REC_N_NEW_EXTRA_BYTES
 					: REC_N_OLD_EXTRA_BYTES))) {
 				i = extra_size;
@@ -580,7 +584,7 @@ page_cur_insert_rec_write_log(
 	if (mtr_get_log_mode(mtr) != MTR_LOG_SHORT_INSERTS) {
 
 		log_ptr = mlog_open_and_write_index(mtr, insert_rec, index,
-				index->table->comp
+				comp
 				? MLOG_COMP_REC_INSERT : MLOG_REC_INSERT,
 				2 + 5 + 1 + 5 + 5 + MLOG_BUF_MARGIN);
 
@@ -605,8 +609,8 @@ page_cur_insert_rec_write_log(
 		log_end = &log_ptr[5 + 1 + 5 + 5 + MLOG_BUF_MARGIN];
 	}
 
-	if ((rec_get_info_and_status_bits(insert_rec, index->table->comp) !=
-	     rec_get_info_and_status_bits(cursor_rec, index->table->comp))
+	if ((rec_get_info_and_status_bits(insert_rec, comp) !=
+	     rec_get_info_and_status_bits(cursor_rec, comp))
 	    || (extra_size != cur_extra_size)
 	    || (rec_size != cur_rec_size)) {
 
@@ -622,8 +626,7 @@ page_cur_insert_rec_write_log(
 	if (extra_info_yes) {
 		/* Write the info bits */
 		mach_write_to_1(log_ptr,
-			rec_get_info_and_status_bits(insert_rec,
-							index->table->comp));
+			rec_get_info_and_status_bits(insert_rec, comp));
 		log_ptr++;
 
 		/* Write the record origin offset */
@@ -757,6 +760,8 @@ page_cur_parse_insert_rec(
 		return(ptr + end_seg_len);
 	}
 
+	ut_ad(!!page_is_comp(page) == index->table->comp);
+
 	/* Read from the log the inserted index record end segment which
 	differs from the cursor record */
 
@@ -771,7 +776,7 @@ page_cur_parse_insert_rec(
 
 	if (extra_info_yes == 0) {
 		info_and_status_bits = rec_get_info_and_status_bits(
-					cursor_rec, index->table->comp);
+					cursor_rec, page_is_comp(page));
 		origin_offset = rec_offs_extra_size(offsets);
 		mismatch_index = rec_offs_size(offsets) - end_seg_len;
 	}
@@ -807,7 +812,7 @@ page_cur_parse_insert_rec(
 	ut_memcpy(buf, rec_get_start(cursor_rec, offsets), mismatch_index);
 	ut_memcpy(buf + mismatch_index, ptr, end_seg_len);
 
-	rec_set_info_and_status_bits(buf + origin_offset, index->table->comp,
+	rec_set_info_and_status_bits(buf + origin_offset, page_is_comp(page),
 							info_and_status_bits);
 
 	page_cur_position(cursor_rec, &cursor);
@@ -821,7 +826,7 @@ page_cur_parse_insert_rec(
 		mem_free(buf);
 	}
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 
@@ -861,7 +866,7 @@ page_cur_insert_rec_low(
 	rec_t*		owner_rec;
 	ulint		n_owned;
 	mem_heap_t*	heap		= NULL;
-	ibool		comp		= index->table->comp;
+	ulint		comp;
 
 	ut_ad(cursor && mtr);
 	ut_ad(tuple || rec);
@@ -869,8 +874,8 @@ page_cur_insert_rec_low(
 	ut_ad(rec || dtuple_check_typed(tuple));
 
 	page = page_cur_get_page(cursor);
-
-	ut_ad(page_is_comp(page) == comp);
+	comp = page_is_comp(page);
+	ut_ad(index->table->comp == !!comp);
 
 	ut_ad(cursor->rec != page_get_supremum_rec(page));	
 
@@ -890,7 +895,7 @@ page_cur_insert_rec_low(
 	insert_buf = page_mem_alloc(page, rec_size, index, &heap_no);
 
 	if (insert_buf == NULL) {
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 		return(NULL);
@@ -980,7 +985,7 @@ page_cur_insert_rec_low(
 	page_cur_insert_rec_write_log(insert_rec, rec_size, current_rec,
 				index, mtr);
 	
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	return(insert_rec);
@@ -1000,8 +1005,10 @@ page_copy_rec_list_to_created_page_write_log(
 {
 	byte*	log_ptr;
 
+	ut_ad(!!page_is_comp(page) == index->table->comp);
+
 	log_ptr = mlog_open_and_write_index(mtr, page, index,
-			index->table->comp
+			page_is_comp(page)
 			? MLOG_COMP_LIST_END_COPY_CREATED
 			: MLOG_LIST_END_COPY_CREATED, 4);
 	ut_a(log_ptr);
@@ -1084,7 +1091,7 @@ page_copy_rec_list_end_to_created_page(
 	ulint	log_mode;
 	byte*	log_ptr;
 	ulint	log_data_len;
-	ibool		comp		= page_is_comp(page);
+	ulint		comp		= page_is_comp(page);
 	mem_heap_t*	heap		= NULL;
 	ulint		offsets_[REC_OFFS_NORMAL_SIZE];
 	ulint*		offsets		= offsets_;
@@ -1186,7 +1193,7 @@ page_copy_rec_list_end_to_created_page(
 		slot_index--;
 	}
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 
@@ -1230,8 +1237,10 @@ page_cur_delete_rec_write_log(
 {
 	byte*	log_ptr;
 
+	ut_ad(!!page_rec_is_comp(rec) == index->table->comp);
+
 	log_ptr = mlog_open_and_write_index(mtr, rec, index,
-			index->table->comp
+			page_rec_is_comp(rec)
 			? MLOG_COMP_REC_DELETE
 			: MLOG_REC_DELETE, 2);
 
@@ -1242,7 +1251,7 @@ page_cur_delete_rec_write_log(
 	}
 
 	/* Write the cursor rec offset as a 2-byte ulint */
-	mach_write_to_2(log_ptr, rec - buf_frame_align(rec));
+	mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));
 
 	mlog_close(mtr, log_ptr + 2);
 }	
@@ -1285,7 +1294,7 @@ page_cur_parse_delete_rec(
 		page_cur_delete_rec(&cursor, index,
 				rec_get_offsets(rec, index, offsets_,
 				ULINT_UNDEFINED, &heap), mtr);
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 	}
@@ -1320,6 +1329,7 @@ page_cur_delete_rec(
 	page = page_cur_get_page(cursor);
 	current_rec = cursor->rec;
 	ut_ad(rec_offs_validate(current_rec, index, offsets));
+	ut_ad(!!page_is_comp(page) == index->table->comp);
 
 	/* The record must not be the supremum or infimum record. */
 	ut_ad(current_rec != page_get_supremum_rec(page));	
diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c
index f3217e91f58a440f02d83bfb3151eb677e7feb7a..9c957ac8554303d52d2e96a65c1ec000cc3507d5 100644
--- a/innobase/page/page0page.c
+++ b/innobase/page/page0page.c
@@ -72,65 +72,70 @@ page_dir_find_owner_slot(
 			/* out: the directory slot number */
 	rec_t*	rec)	/* in: the physical record */
 {
-	ulint			i;
-	ulint			steps		= 0;
-	page_t*			page;	
-	page_dir_slot_t*	slot;
-	rec_t*			original_rec	= rec;
-	ibool			comp;
-	
+	page_t*				page;
+	register uint16			rec_offs_bytes;
+	register page_dir_slot_t*	slot;
+	register const page_dir_slot_t*	first_slot;
+	register rec_t*			r = rec;
+
 	ut_ad(page_rec_check(rec));
 
 	page = buf_frame_align(rec);
-	comp = page_is_comp(page);
-
-	while (rec_get_n_owned(rec, comp) == 0) {
-		steps++;
-		rec = page_rec_get_next(rec);
+	first_slot = page_dir_get_nth_slot(page, 0);
+	slot = page_dir_get_nth_slot(page, page_dir_get_n_slots(page) - 1);
+
+	if (page_is_comp(page)) {
+		while (rec_get_n_owned(r, TRUE) == 0) {
+			r = page + rec_get_next_offs(r, TRUE);
+			ut_ad(r >= page + PAGE_NEW_SUPREMUM);
+			ut_ad(r < page + (UNIV_PAGE_SIZE - PAGE_DIR));
+		}
+	} else {
+		while (rec_get_n_owned(r, FALSE) == 0) {
+			r = page + rec_get_next_offs(r, FALSE);
+			ut_ad(r >= page + PAGE_OLD_SUPREMUM);
+			ut_ad(r < page + (UNIV_PAGE_SIZE - PAGE_DIR));
+		}
 	}
-	
-	page = buf_frame_align(rec);
 
-	i = page_dir_get_n_slots(page) - 1;
-	slot = page_dir_get_nth_slot(page, i); 
+	rec_offs_bytes = mach_encode_2(r - page);
 
-	while (page_dir_slot_get_rec(slot) != rec) {
+	while (UNIV_LIKELY(*(uint16*) slot != rec_offs_bytes)) {
 
- 		if (i == 0) {
+		if (UNIV_UNLIKELY(slot == first_slot)) {
 			fprintf(stderr,
 			"InnoDB: Probable data corruption on page %lu\n"
 			"InnoDB: Original record ",
 			(ulong) buf_frame_get_page_no(page));
 
-			if (comp) {
+			if (page_is_comp(page)) {
 				fputs("(compact record)", stderr);
 			} else {
-				rec_print_old(stderr, original_rec);
+				rec_print_old(stderr, rec);
 			}
 
-			fprintf(stderr, "\n"
-			"InnoDB: on that page. Steps %lu.\n", (ulong) steps);
-			fputs(
+			fputs("\n"
+			"InnoDB: on that page.\n"
 			"InnoDB: Cannot find the dir slot for record ",
 				stderr);
-			if (comp) {
+			if (page_is_comp(page)) {
 				fputs("(compact record)", stderr);
 			} else {
-				rec_print_old(stderr, rec);
+				rec_print_old(stderr, page
+					+ mach_decode_2(rec_offs_bytes));
 			}
 			fputs("\n"
 			"InnoDB: on that page!\n", stderr);
 
 			buf_page_print(page);
 
-	  		ut_error;
-	  	}
+			ut_error;
+		}
 
-		i--;
-		slot = page_dir_get_nth_slot(page, i); 
+		slot += PAGE_DIR_SLOT_SIZE;
 	}
 
-	return(i);
+	return(((ulint) (first_slot - slot)) / PAGE_DIR_SLOT_SIZE);
 }
 
 /******************************************************************
@@ -252,13 +257,13 @@ page_mem_alloc(
 			*heap_no = rec_get_heap_no(rec, page_is_comp(page));
 
 			block = rec_get_start(rec, offsets);
-			if (heap) {
+			if (UNIV_LIKELY_NULL(heap)) {
 				mem_heap_free(heap);
 			}
 			return(block);
 		}
 
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 	}
@@ -290,7 +295,7 @@ page_create_write_log(
 	buf_frame_t*	frame,	/* in: a buffer frame where the page is
 				created */
 	mtr_t*		mtr,	/* in: mini-transaction handle */
-	ibool		comp)	/* in: TRUE=compact page format */
+	ulint		comp)	/* in: nonzero=compact page format */
 {
 	mlog_write_initial_log_record(frame,
 			comp ? MLOG_COMP_PAGE_CREATE : MLOG_PAGE_CREATE, mtr);
@@ -305,7 +310,7 @@ page_parse_create(
 			/* out: end of log record or NULL */
 	byte*	ptr,	/* in: buffer */
 	byte*	end_ptr __attribute__((unused)), /* in: buffer end */
-	ibool	comp,	/* in: TRUE=compact page format */
+	ulint	comp,	/* in: nonzero=compact page format */
 	page_t*	page,	/* in: page or NULL */
 	mtr_t*	mtr)	/* in: mtr or NULL */
 {
@@ -330,7 +335,7 @@ page_create(
 	buf_frame_t*	frame,	/* in: a buffer frame where the page is
 				created */
 	mtr_t*		mtr,	/* in: mini-transaction handle */
-	ibool		comp)	/* in: TRUE=compact page format */
+	ulint		comp)	/* in: nonzero=compact page format */
 {
 	page_dir_slot_t* slot;
 	mem_heap_t*	heap;
@@ -396,9 +401,9 @@ page_create(
 	dtuple_set_info_bits(tuple, REC_STATUS_SUPREMUM);
 	field = dtuple_get_nth_field(tuple, 0);
 
-	dfield_set_data(field, "supremum", 9 - comp);
+	dfield_set_data(field, "supremum", comp ? 8 : 9);
 	dtype_set(dfield_get_type(field),
-		DATA_VARCHAR, DATA_ENGLISH | DATA_NOT_NULL, 9 - comp, 0);
+		DATA_VARCHAR, DATA_ENGLISH | DATA_NOT_NULL, comp ? 8 : 9, 0);
 
 	supremum_rec = rec_convert_dtuple_to_rec(heap_top, index, tuple);
 
@@ -478,10 +483,11 @@ page_copy_rec_list_end_no_locks(
 		page_cur_move_to_next(&cur1);
 	}
 
-	ut_a(index->table->comp == page_is_comp(page));
-	ut_a(index->table->comp == page_is_comp(new_page));
+	ut_a(!!page_is_comp(new_page) == index->table->comp);
+	ut_a(page_is_comp(new_page) == page_is_comp(page));
 	ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) == (ulint)
-		(index->table->comp ? PAGE_NEW_INFIMUM : PAGE_OLD_INFIMUM));
+		(page_is_comp(new_page)
+		? PAGE_NEW_INFIMUM : PAGE_OLD_INFIMUM));
 
 	page_cur_set_before_first(new_page, &cur2);
 	
@@ -489,12 +495,15 @@ page_copy_rec_list_end_no_locks(
 
 	sup = page_get_supremum_rec(page);
 	
-	while (sup != page_cur_get_rec(&cur1)) {
+	for (;;) {
 		rec_t*	cur1_rec = page_cur_get_rec(&cur1);
+		if (cur1_rec == sup) {
+			break;
+		}
 		offsets = rec_get_offsets(cur1_rec, index, offsets,
 					ULINT_UNDEFINED, &heap);
-		if (!page_cur_rec_insert(&cur2, cur1_rec, index,
-							offsets, mtr)) {
+		if (UNIV_UNLIKELY(!page_cur_rec_insert(&cur2, cur1_rec, index,
+							offsets, mtr))) {
 			/* Track an assertion failure reported on the mailing
 			list on June 18th, 2003 */
 
@@ -514,7 +523,7 @@ page_copy_rec_list_end_no_locks(
 		page_cur_move_to_next(&cur2);
 	}
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 }
@@ -608,7 +617,7 @@ page_copy_rec_list_start(
 
 	btr_search_move_or_delete_hash_entries(new_page, page, index);
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 }
@@ -619,7 +628,6 @@ UNIV_INLINE
 void
 page_delete_rec_list_write_log(
 /*===========================*/
-	page_t*		page,	/* in: index page */
 	rec_t*		rec,	/* in: record on page */
 	dict_index_t*	index,	/* in: record descriptor */
 	byte		type,	/* in: operation type:
@@ -632,10 +640,10 @@ page_delete_rec_list_write_log(
 		|| type == MLOG_COMP_LIST_END_DELETE
 		|| type == MLOG_COMP_LIST_START_DELETE);
 
-	log_ptr = mlog_open_and_write_index(mtr, page, index, type, 2);
+	log_ptr = mlog_open_and_write_index(mtr, rec, index, type, 2);
 	if (log_ptr) {
 		/* Write the parameter as a 2-byte ulint */
-		mach_write_to_2(log_ptr, rec - page);
+		mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));
 		mlog_close(mtr, log_ptr + 2);
 	}
 }
@@ -679,6 +687,8 @@ page_parse_delete_rec_list(
 		return(ptr);
 	}
 
+	ut_ad(!!page_is_comp(page) == index->table->comp);
+
 	if (type == MLOG_LIST_END_DELETE
 			|| type == MLOG_COMP_LIST_END_DELETE) {
 		page_delete_rec_list_end(page, page + offset, index,
@@ -716,7 +726,7 @@ page_delete_rec_list_end(
 	ulint	count;
 	ulint	n_owned;
 	rec_t*	sup;
-	ibool	comp;
+	ulint	comp;
 
 	/* Reset the last insert info in the page header and increment
 	the modify clock for the frame */
@@ -731,12 +741,12 @@ page_delete_rec_list_end(
 	
 	sup = page_get_supremum_rec(page);
 	
-	if (rec == page_get_infimum_rec(page)) {
+	comp = page_is_comp(page);
+	if (page_rec_is_infimum_low(rec - page)) {
 		rec = page_rec_get_next(rec);
 	}
 
-	comp = page_is_comp(page);
-	page_delete_rec_list_write_log(page, rec, index,
+	page_delete_rec_list_write_log(rec, index,
 		comp ? MLOG_COMP_LIST_END_DELETE : MLOG_LIST_END_DELETE, mtr);
 
 	if (rec == sup) {
@@ -772,7 +782,7 @@ page_delete_rec_list_end(
 			rec2 = page_rec_get_next(rec2);
 		}
 
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 	}
@@ -841,13 +851,15 @@ page_delete_rec_list_start(
 	byte		type;
 	*offsets_ = (sizeof offsets_) / sizeof *offsets_;
 
-	if (index->table->comp) {
+	ut_ad(!!page_is_comp(page) == index->table->comp);
+
+	if (page_is_comp(page)) {
 		type = MLOG_COMP_LIST_START_DELETE;
 	} else {
 		type = MLOG_LIST_START_DELETE;
 	}
 
-	page_delete_rec_list_write_log(page, rec, index, type, mtr);
+	page_delete_rec_list_write_log(rec, index, type, mtr);
 
 	page_cur_set_before_first(page, &cur1);
 
@@ -868,7 +880,7 @@ page_delete_rec_list_start(
 		page_cur_delete_rec(&cur1, index, offsets, mtr);
 	}
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 
@@ -1221,7 +1233,7 @@ page_rec_get_n_recs_before(
 	rec_t*			slot_rec;
 	page_t*			page;
 	ulint			i;
-	ibool			comp;
+	ulint			comp;
 	lint			n	= 0;
 
 	ut_ad(page_rec_check(rec));
@@ -1264,9 +1276,9 @@ page_rec_print(
 	rec_t*		rec,	/* in: physical record */
 	const ulint*	offsets)/* in: record descriptor */
 {
-	ibool	comp	= page_is_comp(buf_frame_align(rec));
+	ulint	comp	= page_is_comp(buf_frame_align(rec));
 
-	ut_a(comp == rec_offs_comp(offsets));
+	ut_a(!comp == !rec_offs_comp(offsets));
 	rec_print_new(stderr, rec, offsets);
 	fprintf(stderr,
      		"            n_owned: %lu; heap_no: %lu; next rec: %lu\n",
@@ -1335,7 +1347,7 @@ page_print_list(
 	ulint*		offsets		= offsets_;
 	*offsets_ = (sizeof offsets_) / sizeof *offsets_;
 
-	ut_a(page_is_comp(page) == index->table->comp);
+	ut_a(!!page_is_comp(page) == index->table->comp);
 
 	fprintf(stderr,
 		"--------------------------------\n"
@@ -1381,7 +1393,7 @@ page_print_list(
 		"--------------------------------\n",
 		(ulong) (count + 1));
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 }	
@@ -1447,11 +1459,11 @@ page_rec_validate(
 	ulint	n_owned;
 	ulint	heap_no;
 	page_t*	page;
-	ibool	comp;
+	ulint	comp;
 
 	page = buf_frame_align(rec);
 	comp = page_is_comp(page);
-	ut_a(comp == rec_offs_comp(offsets));
+	ut_a(!comp == !rec_offs_comp(offsets));
 
 	page_rec_check(rec);
 	rec_validate(rec, offsets);
@@ -1528,7 +1540,7 @@ page_simple_validate(
 	ulint		count;
 	ulint		own_count;
 	ibool		ret	= FALSE;
-	ibool		comp	= page_is_comp(page);
+	ulint		comp	= page_is_comp(page);
 
 	/* Check first that the record heap and the directory do not
 	overlap. */
@@ -1725,11 +1737,11 @@ page_validate(
 	ulint		n_slots;
 	ibool		ret		= FALSE;
 	ulint		i;
-	ibool		comp		= page_is_comp(page);
+	ulint		comp		= page_is_comp(page);
 	ulint*		offsets		= NULL;
 	ulint*		old_offsets	= NULL;
 
-	if (comp != index->table->comp) {
+	if (!!comp != index->table->comp) {
 		fputs("InnoDB: 'compact format' flag mismatch\n", stderr);
 		goto func_exit2;
 	}
@@ -1810,8 +1822,7 @@ page_validate(
 			}
 		}
 
-		if ((rec != page_get_supremum_rec(page))
-		    && (rec != page_get_infimum_rec(page))) {
+		if (page_rec_is_user_rec(rec)) {
 
 			data_size += rec_offs_size(offsets);
 		}
diff --git a/innobase/rem/rem0cmp.c b/innobase/rem/rem0cmp.c
index 74348b865a86b22359fbffb3dd23bf7ca5208f06..7c33476fb9e99c6311abe7240b7cb5aea9ae5000 100644
--- a/innobase/rem/rem0cmp.c
+++ b/innobase/rem/rem0cmp.c
@@ -320,7 +320,7 @@ cmp_data_data_slow(
 	    || (cur_type->mtype == DATA_BLOB
 	        && 0 == (cur_type->prtype & DATA_BINARY_TYPE)
 		&& dtype_get_charset_coll(cur_type->prtype) !=
-				data_mysql_latin1_swedish_charset_coll)) {
+				DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
 
 		return(cmp_whole_field(cur_type,
 					data1, (unsigned) len1,
@@ -451,6 +451,20 @@ cmp_dtuple_rec_with_match(
 	ut_ad(cur_field <= dtuple_get_n_fields_cmp(dtuple));
 	ut_ad(cur_field <= rec_offs_n_fields(offsets));
 
+	if (cur_bytes == 0 && cur_field == 0) {
+		ulint	rec_info = rec_get_info_bits(rec,
+				rec_offs_comp(offsets));
+		ulint	tup_info = dtuple_get_info_bits(dtuple);
+
+		if (rec_info & REC_INFO_MIN_REC_FLAG) {
+			ret = !(tup_info & REC_INFO_MIN_REC_FLAG);
+			goto order_resolved;
+		} else if (tup_info & REC_INFO_MIN_REC_FLAG) {
+			ret = -1;
+			goto order_resolved;
+		}
+	}
+
 	/* Match fields in a loop; stop if we run out of fields in dtuple
 	or find an externally stored field */
 
@@ -469,32 +483,7 @@ cmp_dtuple_rec_with_match(
 		the predefined minimum record, or the field is externally
 		stored */
 
-		if (cur_bytes == 0) {
-			if (cur_field == 0) {
-
-				if (rec_get_info_bits(rec,
-						rec_offs_comp(offsets))
-				    & REC_INFO_MIN_REC_FLAG) {
-
-					if (dtuple_get_info_bits(dtuple)
-				    	    & REC_INFO_MIN_REC_FLAG) {
-
-				    		ret = 0;
-				    	} else {
-				    		ret = 1;
-				    	}
-
-					goto order_resolved;
-				}
-
-				if (dtuple_get_info_bits(dtuple)
-				    & REC_INFO_MIN_REC_FLAG) {
- 				    	ret = -1;
-
-					goto order_resolved;
-				}
-			}
-
+		if (UNIV_LIKELY(cur_bytes == 0)) {
 			if (rec_offs_nth_extern(offsets, cur_field)) {
 				/* We do not compare to an externally
 				stored field */
@@ -504,24 +493,20 @@ cmp_dtuple_rec_with_match(
 				goto order_resolved;
 			}
 
-		    	if (dtuple_f_len == UNIV_SQL_NULL
-		            || rec_f_len == UNIV_SQL_NULL) {
-
-				if (dtuple_f_len == rec_f_len) {
+		    	if (dtuple_f_len == UNIV_SQL_NULL) {
+				if (rec_f_len == UNIV_SQL_NULL) {
 
 					goto next_field;
 				}
 
-				if (rec_f_len == UNIV_SQL_NULL) {
-					/* We define the SQL null to be the 
-					smallest possible value of a field 
-					in the alphabetical order */
-
-					ret = 1;
-				} else {
-					ret = -1;
-				}
+				ret = -1;
+				goto order_resolved;
+			} else if (rec_f_len == UNIV_SQL_NULL) {
+				/* We define the SQL null to be the
+				smallest possible value of a field
+				in the alphabetical order */
 
+				ret = 1;
 				goto order_resolved;
 			}
 		}
@@ -530,7 +515,7 @@ cmp_dtuple_rec_with_match(
 	    	    || (cur_type->mtype == DATA_BLOB
 	        	&& 0 == (cur_type->prtype & DATA_BINARY_TYPE)
 			&& dtype_get_charset_coll(cur_type->prtype) !=
-				data_mysql_latin1_swedish_charset_coll)) {
+				DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
 
 			ret = cmp_whole_field(
 				cur_type,
@@ -555,7 +540,7 @@ cmp_dtuple_rec_with_match(
 		/* Compare then the fields */		
 		
 		for (;;) {
-			if (rec_f_len <= cur_bytes) {
+			if (UNIV_UNLIKELY(rec_f_len <= cur_bytes)) {
 				if (dtuple_f_len <= cur_bytes) {
 
 					goto next_field;
@@ -572,7 +557,7 @@ cmp_dtuple_rec_with_match(
 				rec_byte = *rec_b_ptr;
 			}
 
-			if (dtuple_f_len <= cur_bytes) {
+			if (UNIV_UNLIKELY(dtuple_f_len <= cur_bytes)) {
 				dtuple_byte = dtype_get_pad_char(cur_type);
 
 				if (dtuple_byte == ULINT_UNDEFINED) {
@@ -600,14 +585,16 @@ cmp_dtuple_rec_with_match(
 				rec_byte = cmp_collate(rec_byte);
 				dtuple_byte = cmp_collate(dtuple_byte);
 			}
-			
-			if (dtuple_byte > rec_byte) {
-				ret = 1;
-				goto order_resolved;
 
-			} else if (dtuple_byte < rec_byte) {
-				ret = -1;
-				goto order_resolved;
+			ret = dtuple_byte - rec_byte;
+			if (UNIV_UNLIKELY(ret)) {
+				if (ret < 0) {
+					ret = -1;
+					goto order_resolved;
+				} else {
+					ret = 1;
+					goto order_resolved;
+				}
 			}
 		next_byte:
 			/* Next byte */
@@ -740,7 +727,7 @@ cmp_rec_rec_with_match(
 	ulint	cur_bytes; 	/* number of already matched bytes in current
 				field */
 	int	ret = 3333;	/* return value */
-	ibool	comp;
+	ulint	comp;
 
 	ut_ad(rec1 && rec2 && index);
 	ut_ad(rec_offs_validate(rec1, index, offsets1));
@@ -832,7 +819,7 @@ cmp_rec_rec_with_match(
 	    	    || (cur_type->mtype == DATA_BLOB
 	        	&& 0 == (cur_type->prtype & DATA_BINARY_TYPE)
 			&& dtype_get_charset_coll(cur_type->prtype) !=
-				data_mysql_latin1_swedish_charset_coll)) {
+				DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
 
 			ret = cmp_whole_field(cur_type,
 					rec1_b_ptr, (unsigned) rec1_f_len,
@@ -983,12 +970,8 @@ cmp_debug_dtuple_rec_with_match(
 		if (rec_get_info_bits(rec, rec_offs_comp(offsets))
 					& REC_INFO_MIN_REC_FLAG) {
 
-			if (dtuple_get_info_bits(dtuple)
-				    	    & REC_INFO_MIN_REC_FLAG) {
-				ret = 0;
-			} else {
-				ret = 1;
-			}
+			ret = !(dtuple_get_info_bits(dtuple)
+				    	    & REC_INFO_MIN_REC_FLAG);
 
 			goto order_resolved;
 		}
diff --git a/innobase/rem/rem0rec.c b/innobase/rem/rem0rec.c
index 542c746209b9f238a765ec500402df9dddaecde7..580a7bfe5090e4ff2acefaaa00b2a84fe04c3073 100644
--- a/innobase/rem/rem0rec.c
+++ b/innobase/rem/rem0rec.c
@@ -159,22 +159,20 @@ rec_init_offsets(
 	ulint*		offsets)/* in/out: array of offsets;
 				in: n=rec_offs_n_fields(offsets) */
 {
-	ulint	n_fields = rec_offs_n_fields(offsets);
 	ulint	i	= 0;
 	ulint	offs;
 
 	rec_offs_make_valid(rec, index, offsets);
 
-	if (index->table->comp) {
+	if (UNIV_LIKELY(index->table->comp)) {
 		const byte*	nulls;
 		const byte*	lens;
 		dict_field_t*	field;
-		dtype_t*	type;
 		ulint		null_mask;
 		ulint		status = rec_get_status(rec);
 		ulint		n_node_ptr_field = ULINT_UNDEFINED;
 
-		switch (status) {
+		switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) {
 		case REC_STATUS_INFIMUM:
 		case REC_STATUS_SUPREMUM:
 			/* the field is 8 bytes long */
@@ -196,56 +194,69 @@ rec_init_offsets(
 		null_mask = 1;
 
 		/* read the lengths of fields 0..n */
-		for (; i < n_fields; i++) {
-			ibool	is_null = FALSE, is_external = FALSE;
+		do {
 			ulint	len;
-			if (i == n_node_ptr_field) {
-				len = 4;
+			if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
+				len = offs += 4;
 				goto resolved;
 			}
 
 			field = dict_index_get_nth_field(index, i);
-			type = dict_col_get_type(dict_field_get_col(field));
-			if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
+			if (!(dtype_get_prtype(dict_col_get_type(
+						dict_field_get_col(field)))
+						& DATA_NOT_NULL)) {
 				/* nullable field => read the null flag */
-				is_null = (*nulls & null_mask) != 0;
-				null_mask <<= 1;
-				if (null_mask == 0x100) {
+
+				if (UNIV_UNLIKELY(!(byte) null_mask)) {
 					nulls--;
 					null_mask = 1;
 				}
+
+				if (*nulls & null_mask) {
+					null_mask <<= 1;
+					/* No length is stored for NULL fields.
+					We do not advance offs, and we set
+					the length to zero and enable the
+					SQL NULL flag in offsets[]. */
+					len = offs | REC_OFFS_SQL_NULL;
+					goto resolved;
+				}
+				null_mask <<= 1;
 			}
 
-			if (is_null) {
-				/* No length is stored for NULL fields. */
-				len = 0;
-			} else if (!field->fixed_len) {
+			if (UNIV_UNLIKELY(!field->fixed_len)) {
 				/* Variable-length field: read the length */
+				dtype_t*	type = dict_col_get_type(
+						dict_field_get_col(field));
 				len = *lens--;
-				if (dtype_get_len(type) > 255
-				    || dtype_get_mtype(type) == DATA_BLOB) {
+				if (UNIV_UNLIKELY(dtype_get_len(type) > 255)
+				    || UNIV_UNLIKELY(dtype_get_mtype(type)
+							== DATA_BLOB)) {
 					if (len & 0x80) {
 						/* 1exxxxxxx xxxxxxxx */
-						is_external = !!(len & 0x40);
-						len &= 0x3f;
 						len <<= 8;
 						len |= *lens--;
+
+						offs += len & 0x3fff;
+						if (UNIV_UNLIKELY(len
+								& 0x4000)) {
+							len = offs
+							| REC_OFFS_EXTERNAL;
+						} else {
+							len = offs;
+						}
+
+						goto resolved;
 					}
 				}
+
+				len = offs += len;
 			} else {
-				len = field->fixed_len;
+				len = offs += field->fixed_len;
 			}
 		resolved:
-			offs += len;
-			len = offs;
-			if (is_external) {
-				len |= REC_OFFS_EXTERNAL;
-			}
-			if (is_null) {
-				len |= REC_OFFS_SQL_NULL;
-			}
 			rec_offs_base(offsets)[i + 1] = len;
-		}
+		} while (++i < rec_offs_n_fields(offsets));
 
 		*rec_offs_base(offsets) =
 			(rec - (lens + 1)) | REC_OFFS_COMPACT;
@@ -253,22 +264,22 @@ rec_init_offsets(
 		/* Old-style record: determine extra size and end offsets */
 		offs = REC_N_OLD_EXTRA_BYTES;
 		if (rec_get_1byte_offs_flag(rec)) {
-			offs += n_fields;
+			offs += rec_offs_n_fields(offsets);
 			*rec_offs_base(offsets) = offs;
 			/* Determine offsets to fields */
-			for (; i < n_fields; i++) {
+			do {
 				offs = rec_1_get_field_end_info(rec, i);
 				if (offs & REC_1BYTE_SQL_NULL_MASK) {
 					offs &= ~REC_1BYTE_SQL_NULL_MASK;
 					offs |= REC_OFFS_SQL_NULL;
 				}
 				rec_offs_base(offsets)[1 + i] = offs;
-			}
+			} while (++i < rec_offs_n_fields(offsets));
 		} else {
-			offs += 2 * n_fields;
+			offs += 2 * rec_offs_n_fields(offsets);
 			*rec_offs_base(offsets) = offs;
 			/* Determine offsets to fields */
-			for (; i < n_fields; i++) {
+			do {
 				offs = rec_2_get_field_end_info(rec, i);
 				if (offs & REC_2BYTE_SQL_NULL_MASK) {
 					offs &= ~REC_2BYTE_SQL_NULL_MASK;
@@ -279,7 +290,7 @@ rec_init_offsets(
 					offs |= REC_OFFS_EXTERNAL;
 				}
 				rec_offs_base(offsets)[1 + i] = offs;
-			}
+			} while (++i < rec_offs_n_fields(offsets));
 		}
 	}
 }
@@ -310,8 +321,9 @@ rec_get_offsets_func(
 	ut_ad(index);
 	ut_ad(heap);
 
-	if (index->table->comp) {
-		switch (rec_get_status(rec)) {
+	if (UNIV_LIKELY(index->table->comp)) {
+		switch (UNIV_EXPECT(rec_get_status(rec),
+				REC_STATUS_ORDINARY)) {
 		case REC_STATUS_ORDINARY:
 			n = dict_index_get_n_fields(index);
 			break;
@@ -331,13 +343,14 @@ rec_get_offsets_func(
 		n = rec_get_n_fields_old(rec);
 	}
 
-	if (n_fields < n) {
+	if (UNIV_UNLIKELY(n_fields < n)) {
 		n = n_fields;
 	}
 
 	size = n + (1 + REC_OFFS_HEADER_SIZE);
 
-	if (!offsets || rec_offs_get_n_alloc(offsets) < size) {
+	if (UNIV_UNLIKELY(!offsets) ||
+			UNIV_UNLIKELY(rec_offs_get_n_alloc(offsets) < size)) {
 		if (!*heap) {
 			*heap = mem_heap_create_func(size * sizeof(ulint),
 				NULL, MEM_HEAP_DYNAMIC, file, line);
@@ -652,9 +665,17 @@ rec_set_field_extern_bits(
 				to log about the change */
 {
 	ulint	i;
-	
-	for (i = 0; i < n_fields; i++) {
-		rec_set_nth_field_extern_bit(rec, index, vec[i], TRUE, mtr);
+
+	if (UNIV_LIKELY(index->table->comp)) {
+		for (i = 0; i < n_fields; i++) {
+			rec_set_nth_field_extern_bit_new(rec, index, vec[i],
+								TRUE, mtr);
+		}
+	} else {
+		for (i = 0; i < n_fields; i++) {
+			rec_set_nth_field_extern_bit_old(rec, vec[i],
+								TRUE, mtr);
+		}
 	}
 }
 
@@ -949,7 +970,7 @@ rec_convert_dtuple_to_rec(
 	ut_ad(dtuple_validate(dtuple));
 	ut_ad(dtuple_check_typed(dtuple));
 
-	if (index->table->comp) {
+	if (UNIV_LIKELY(index->table->comp)) {
 		rec = rec_convert_dtuple_to_rec_new(buf, index, dtuple);
 	} else {
 		rec = rec_convert_dtuple_to_rec_old(buf, dtuple);
@@ -965,7 +986,7 @@ rec_convert_dtuple_to_rec(
 		offsets = rec_get_offsets(rec, index,
 					offsets_, ULINT_UNDEFINED, &heap);
 		ut_ad(rec_validate(rec, offsets));
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 	}
@@ -1078,17 +1099,19 @@ rec_copy_prefix_to_buf(
 					for the copied prefix, or NULL */
 	ulint*		buf_size)	/* in/out: buffer size */
 {
-	byte*		nulls	= rec - (REC_N_NEW_EXTRA_BYTES + 1);
-	byte*		lens	= nulls - (index->n_nullable + 7) / 8;
+	byte*		nulls;
+	byte*		lens;
 	dict_field_t*	field;
 	dtype_t*	type;
 	ulint		i;
-	ulint		prefix_len	= 0;
+	ulint		prefix_len;
 	ibool		is_null;
-	ulint		null_mask	= 1;
+	ulint		null_mask;
 	ulint		status;
 
-	if (!index->table->comp) {
+	UNIV_PREFETCH_RW(*buf);
+
+	if (UNIV_UNLIKELY(!index->table->comp)) {
 		ut_ad(rec_validate_old(rec));
 		return(rec_copy_prefix_to_buf_old(rec, n_fields,
 			rec_get_field_start_offs(rec, n_fields),
@@ -1109,10 +1132,16 @@ rec_copy_prefix_to_buf(
 	case REC_STATUS_SUPREMUM:
 		/* infimum or supremum record: no sense to copy anything */
 	default:
-		ut_a(0);
+		ut_error;
 		return(NULL);
 	}
 
+	nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
+	lens = nulls - (index->n_nullable + 7) / 8;
+	UNIV_PREFETCH_R(lens);
+	prefix_len = 0;
+	null_mask = 1;
+
 	/* read the lengths of fields 0..n */
 	for (i = 0; i < n_fields; i++) {
 		field = dict_index_get_nth_field(index, i);
@@ -1122,8 +1151,11 @@ rec_copy_prefix_to_buf(
 			/* nullable field => read the null flag */
 			is_null = !!(*nulls & null_mask);
 			null_mask <<= 1;
-			if (null_mask == 0x100)
-				nulls--, null_mask = 1;
+			if (null_mask == 0x100) {
+				--nulls;
+				UNIV_PREFETCH_R(nulls);
+				null_mask = 1;
+			}
 		}
 
 		if (is_null) {
@@ -1138,12 +1170,15 @@ rec_copy_prefix_to_buf(
 					len &= 0x3f;
 					len <<= 8;
 					len |= *lens--;
+					UNIV_PREFETCH_R(lens);
 				}
 			}
 			prefix_len += len;
 		}
 	}
 
+	UNIV_PREFETCH_R(rec + prefix_len);
+
 	prefix_len += rec - (lens + 1);
 
 	if ((*buf == NULL) || (*buf_size < prefix_len)) {
@@ -1412,7 +1447,7 @@ rec_print(
 
 		rec_print_new(file, rec, rec_get_offsets(rec, index, offsets_,
 						ULINT_UNDEFINED, &heap));
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 	}
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c
index 303fe5749bc96c89d62d10c380ddfbe4884b7077..776094d0de5c5eb9f642725a45daa33b707245e6 100644
--- a/innobase/row/row0ins.c
+++ b/innobase/row/row0ins.c
@@ -478,7 +478,7 @@ row_ins_cascade_calc_update_vec(
 		
 			if (parent_ufield->field_no == parent_field_no) {
 
-				ulint	fixed_size;
+				ulint	min_size;
 
 				/* A field in the parent index record is
 				updated. Let us make the update vector
@@ -508,10 +508,13 @@ row_ins_cascade_calc_update_vec(
 				column, do not allow the update */
 
 				if (ufield->new_val.len != UNIV_SQL_NULL
-				    && ufield->new_val.len
-				       > dtype_get_len(type)) {
+				    && dtype_get_at_most_n_mbchars(
+						type, dtype_get_len(type),
+						ufield->new_val.len,
+						ufield->new_val.data)
+				    < ufield->new_val.len) {
 
-				        return(ULINT_UNDEFINED);
+					return(ULINT_UNDEFINED);
 				}
 
 				/* If the parent column type has a different
@@ -519,29 +522,46 @@ row_ins_cascade_calc_update_vec(
 				need to pad with spaces the new value of the
 				child column */
 
-				fixed_size = dtype_get_fixed_size(type);
-
-				/* TODO: pad in UCS-2 with 0x0020.
-				TODO: How does the special truncation of
-				UTF-8 CHAR cols affect this? */
+				min_size = dtype_get_min_size(type);
 
-				if (fixed_size
+				if (min_size
 				    && ufield->new_val.len != UNIV_SQL_NULL
-				    && ufield->new_val.len < fixed_size) {
+				    && ufield->new_val.len < min_size) {
 
+					char*		pad_start;
+					const char*	pad_end;
 				        ufield->new_val.data =
 						mem_heap_alloc(heap,
-								fixed_size);
-					ufield->new_val.len = fixed_size;
-					ut_a(dtype_get_pad_char(type)
-					     != ULINT_UNDEFINED);
-
-					memset(ufield->new_val.data,
-					       (byte)dtype_get_pad_char(type),
-					       fixed_size);
+								min_size);
+					pad_start = ufield->new_val.data
+						+ ufield->new_val.len;
+					pad_end = ufield->new_val.data
+						+ min_size;
+					ufield->new_val.len = min_size;
 					ut_memcpy(ufield->new_val.data,
 						parent_ufield->new_val.data,
 						parent_ufield->new_val.len);
+
+					switch (UNIV_EXPECT(
+						dtype_get_mbminlen(type), 1)) {
+					default:
+						ut_error;
+					case 1:
+						/* space=0x20 */
+						memset(pad_start, 0x20,
+							pad_end - pad_start);
+						break;
+					case 2:
+						/* space=0x0020 */
+						ut_a(!(ufield->new_val.len
+									% 2));
+						ut_a(!(min_size % 2));
+						do {
+							*pad_start++ = 0x00;
+							*pad_start++ = 0x20;
+						} while (pad_start < pad_end);
+						break;
+					}
 				}
 
 				ufield->extern_storage = FALSE;
@@ -1255,9 +1275,11 @@ run_again:
 	/* Scan index records and check if there is a matching record */
 
 	for (;;) {
+		page_t*	page;
 		rec = btr_pcur_get_rec(&pcur);
+		page = buf_frame_align(rec);
 
-		if (rec == page_get_infimum_rec(buf_frame_align(rec))) {
+		if (rec == page_get_infimum_rec(page)) {
 
 			goto next_rec;
 		}
@@ -1265,7 +1287,7 @@ run_again:
 		offsets = rec_get_offsets(rec, check_index,
 					offsets, ULINT_UNDEFINED, &heap);
 
-		if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
+		if (rec == page_get_supremum_rec(page)) {
 
 			err = row_ins_set_shared_rec_lock(LOCK_ORDINARY, rec,
 						check_index, offsets, thr);
@@ -1392,7 +1414,7 @@ do_possible_lock_wait:
 	}
 
 exit_func:
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	return(err);
@@ -1529,12 +1551,7 @@ row_ins_dupl_error_with_rec(
 	        }
 	}
 
-	if (!rec_get_deleted_flag(rec, index->table->comp)) {
-
-	        return(TRUE);
-	}
-
-	return(FALSE);
+	return(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
 }	
 
 /*******************************************************************
@@ -1629,7 +1646,7 @@ row_ins_scan_sec_index_for_duplicate(
 			break;
 		}
 
-		if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
+		if (page_rec_is_supremum(rec)) {
 		
 			goto next_rec;
 		}
@@ -1660,7 +1677,7 @@ next_rec:
 		}
 	}
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	mtr_commit(&mtr);
@@ -1697,7 +1714,6 @@ row_ins_duplicate_error_in_clust(
 #ifndef UNIV_HOTBACKUP
 	ulint	err;
 	rec_t*	rec;
-	page_t*	page;
 	ulint	n_unique;
 	trx_t*	trx		= thr_get_trx(thr);
 	mem_heap_t*heap		= NULL;
@@ -1728,9 +1744,8 @@ row_ins_duplicate_error_in_clust(
 	if (cursor->low_match >= n_unique) {
 		
 		rec = btr_cur_get_rec(cursor);
-		page = buf_frame_align(rec);
 
-		if (rec != page_get_infimum_rec(page)) {
+		if (!page_rec_is_infimum(rec)) {
 			offsets = rec_get_offsets(rec, cursor->index, offsets,
 						ULINT_UNDEFINED, &heap);
 
@@ -1772,9 +1787,8 @@ row_ins_duplicate_error_in_clust(
 	if (cursor->up_match >= n_unique) {
 
 		rec = page_rec_get_next(btr_cur_get_rec(cursor));
-		page = buf_frame_align(rec);
 
-		if (rec != page_get_supremum_rec(page)) {
+		if (!page_rec_is_supremum(rec)) {
 			offsets = rec_get_offsets(rec, cursor->index, offsets,
 						ULINT_UNDEFINED, &heap);
 
@@ -1842,7 +1856,6 @@ row_ins_must_modify(
 {
 	ulint	enough_match;
 	rec_t*	rec;
-	page_t*	page;
 	
 	/* NOTE: (compare to the note in row_ins_duplicate_error) Because node
 	pointers on upper levels of the B-tree may match more to entry than
@@ -1856,9 +1869,8 @@ row_ins_must_modify(
 	if (cursor->low_match >= enough_match) {
 
 		rec = btr_cur_get_rec(cursor);
-		page = buf_frame_align(rec);
 
-		if (rec != page_get_infimum_rec(page)) {
+		if (!page_rec_is_infimum(rec)) {
 
 			return(ROW_INS_PREV);
 		}
@@ -1897,7 +1909,6 @@ row_ins_index_entry_low(
 	ulint		modify = 0; /* remove warning */
 	rec_t*		insert_rec;
 	rec_t*		rec;
-	rec_t*		first_rec;
 	ulint		err;
 	ulint		n_unique;
 	big_rec_t*	big_rec			= NULL;
@@ -1932,15 +1943,20 @@ row_ins_index_entry_low(
 		err = DB_SUCCESS;
 
 		goto function_exit;
-	}	
-					
-	first_rec = page_rec_get_next(page_get_infimum_rec(
-			buf_frame_align(btr_cur_get_rec(&cursor))));
+	}
+
+#ifdef UNIV_DEBUG
+	{
+		page_t*	page = btr_cur_get_page(&cursor);
+		rec_t*	first_rec = page_rec_get_next(
+				page_get_infimum_rec(page));
 
-	if (!page_rec_is_supremum(first_rec)) {
-		ut_a(rec_get_n_fields(first_rec, index)
+		if (UNIV_LIKELY(first_rec != page_get_supremum_rec(page))) {
+			ut_a(rec_get_n_fields(first_rec, index)
 			== dtuple_get_n_fields(entry));
+		}
 	}
+#endif
 
 	n_unique = dict_index_get_n_unique(index);
 
@@ -2048,7 +2064,7 @@ function_exit:
 		mtr_commit(&mtr);
 	}
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	return(err);
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index fafbef4c999844ba401e46b4b55754cb391a9c3c..eb50b83a4d5394f8d7df7077f50b399ae2ddeb48 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -265,7 +265,7 @@ row_mysql_store_col_in_innobase_format(
 					necessarily the length of the actual
 					payload data; if the column is a true
 					VARCHAR then this is irrelevant */
-	ibool		comp)		/* in: TRUE = compact format */
+	ulint		comp)		/* in: nonzero=compact format */
 {
 	byte*		ptr 	= mysql_data;
 	dtype_t*	dtype;
@@ -970,25 +970,6 @@ run_again:
 	return((int) err);
 }
 
-/*************************************************************************
-Unlocks all table locks explicitly requested by trx (with LOCK TABLES,
-lock type LOCK_TABLE_EXP). */
-
-void		  	
-row_unlock_tables_for_mysql(
-/*========================*/
-	trx_t*	trx)	/* in: transaction */
-{
-	if (!trx->n_lock_table_exp) {
-
-		return;
-	}
-
-	mutex_enter(&kernel_mutex);
-	lock_release_tables_off_kernel(trx);
-	mutex_exit(&kernel_mutex);
-}
-
 /*************************************************************************
 Sets a table lock on the table mentioned in prebuilt. */
 
@@ -1000,9 +981,10 @@ row_lock_table_for_mysql(
 					table handle */
 	dict_table_t*	table,		/* in: table to lock, or NULL
 					if prebuilt->table should be
-					locked or a
+					locked as
 					prebuilt->select_lock_type */
-	ulint		mode)		/* in: lock mode of table */
+	ulint		mode)		/* in: lock mode of table
+					(ignored if table==NULL) */
 {
 	trx_t*		trx 		= prebuilt->trx;
 	que_thr_t*	thr;
@@ -1038,14 +1020,8 @@ run_again:
 	if (table) {
 		err = lock_table(0, table, mode, thr);
 	} else {
-		if (mode == LOCK_TABLE_TRANSACTIONAL) {
-			err = lock_table(LOCK_TABLE_TRANSACTIONAL, 
-					prebuilt->table,
-					prebuilt->select_lock_type, thr);
-		} else {
-			err = lock_table(LOCK_TABLE_EXP, prebuilt->table,
-					prebuilt->select_lock_type, thr);
-		}
+		err = lock_table(0, prebuilt->table,
+				prebuilt->select_lock_type, thr);
 	}
 
 	trx->error_state = err;
@@ -3858,7 +3834,7 @@ funct_exit:
 		que_graph_free(graph);
 	}
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	
@@ -3893,6 +3869,7 @@ row_scan_and_check_index(
 	int		cmp;
 	ibool		contains_null;
 	ulint		i;
+	ulint		cnt;
 	mem_heap_t*	heap		= NULL;
 	ulint		offsets_[REC_OFFS_NORMAL_SIZE];
 	ulint*		offsets		= offsets_;
@@ -3915,11 +3892,19 @@ row_scan_and_check_index(
  	dtuple_set_n_fields(prebuilt->search_tuple, 0);
 
 	prebuilt->select_lock_type = LOCK_NONE;
+	cnt = 1000;
 
 	ret = row_search_for_mysql(buf, PAGE_CUR_G, prebuilt, 0, 0);
 loop:
+	/* Check thd->killed every 1,000 scanned rows */
+	if (--cnt == 0) {
+		if (trx_is_interrupted(prebuilt->trx)) {
+			goto func_exit;
+		}
+		cnt = 1000;
+	}
 	if (ret != DB_SUCCESS) {
-
+	func_exit:
 		mem_free(buf);
 		mem_heap_free(heap);
 
@@ -4046,7 +4031,7 @@ row_check_table_for_mysql(
 		ut_print_name(stderr, index->name);
 		putc('\n', stderr); */
 	
-		if (!btr_validate_tree(index->tree)) {
+		if (!btr_validate_tree(index->tree, prebuilt->trx)) {
 			ret = DB_ERROR;
 		} else {
 			if (!row_scan_and_check_index(prebuilt,
@@ -4054,6 +4039,10 @@ row_check_table_for_mysql(
 				ret = DB_ERROR;
 			}
 
+			if (trx_is_interrupted(prebuilt->trx)) {
+				break;
+			}
+
 			/* fprintf(stderr, "%lu entries in index %s\n", n_rows,
 			  index->name); */
 
diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c
index 5893e0160114ce6aeeb23230e49a794204b9d799..abcf97110d9b7f3b5bafd0f6081c2815880125ed 100644
--- a/innobase/row/row0purge.c
+++ b/innobase/row/row0purge.c
@@ -126,7 +126,7 @@ row_purge_remove_clust_if_poss_low(
 	if (0 != ut_dulint_cmp(node->roll_ptr,
 		row_get_rec_roll_ptr(rec, index, rec_get_offsets(
 			rec, index, offsets_, ULINT_UNDEFINED, &heap)))) {
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 		/* Someone else has modified the record later: do not remove */
@@ -135,7 +135,7 @@ row_purge_remove_clust_if_poss_low(
 		return(TRUE);
 	}
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 
diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c
index a6d3f1d5ab07bb1ae422904905500b492e4a7dac..9a74397dc08fd3d47c6dfefe8d4fc8238a14a2eb 100644
--- a/innobase/row/row0row.c
+++ b/innobase/row/row0row.c
@@ -535,7 +535,7 @@ row_build_row_ref_in_tuple(
 	}
 
 	ut_ad(dtuple_check_typed(ref));
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 }
@@ -616,7 +616,6 @@ row_search_on_row_ref(
 	ulint		low_match;	
 	rec_t*		rec;
 	dict_index_t*	index;
-	page_t*		page;	
 
 	ut_ad(dtuple_check_typed(ref));
 
@@ -629,9 +628,8 @@ row_search_on_row_ref(
 	low_match = btr_pcur_get_low_match(pcur);
 
 	rec = btr_pcur_get_rec(pcur);
-	page = buf_frame_align(rec);
 
-	if (rec == page_get_infimum_rec(page)) {
+	if (page_rec_is_infimum(rec)) {
 
 		return(FALSE);
 	}
@@ -702,7 +700,6 @@ row_search_index_entry(
 {
 	ulint	n_fields;
 	ulint	low_match;
-	page_t*	page;
 	rec_t*	rec;
 
 	ut_ad(dtuple_check_typed(entry));
@@ -711,11 +708,10 @@ row_search_index_entry(
 	low_match = btr_pcur_get_low_match(pcur);
 
 	rec = btr_pcur_get_rec(pcur);
-	page = buf_frame_align(rec);
 
 	n_fields = dtuple_get_n_fields(entry);
 
-	if (rec == page_get_infimum_rec(page)) {
+	if (page_rec_is_infimum(rec)) {
 
 		return(FALSE);
 	}
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index 94cf82d6a3d3d338bb8c463624a4d33f2a5f3266..c7a548fe448d532b2ff2ab1f1125fd323eb78d0a 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -125,7 +125,7 @@ row_sel_sec_rec_is_for_clust_rec(
         }
 
 func_exit:
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	return(is_equal);
@@ -630,6 +630,8 @@ row_sel_get_clust_rec(
 	ulint*		offsets		= offsets_;
 	*offsets_ = (sizeof offsets_) / sizeof *offsets_;
 
+	*out_rec = NULL;
+
 	offsets = rec_get_offsets(rec,
 				btr_pcur_get_btr_cur(&plan->pcur)->index,
 				offsets, ULINT_UNDEFINED, &heap);
@@ -663,8 +665,6 @@ row_sel_get_clust_rec(
 		clustered index record did not exist in the read view of
 		trx. */
 
-		clust_rec = NULL;
-
 		goto func_exit;
 	}
 
@@ -733,7 +733,6 @@ row_sel_get_clust_rec(
 		if ((old_vers || rec_get_deleted_flag(rec, plan->table->comp))
 		    && !row_sel_sec_rec_is_for_clust_rec(rec, plan->index,
 							clust_rec, index)) {
-			clust_rec = NULL;
 			goto func_exit;
 		}
 	}
@@ -742,11 +741,11 @@ row_sel_get_clust_rec(
 
 	row_sel_fetch_columns(index, clust_rec, offsets,
 					UT_LIST_GET_FIRST(plan->columns));
-func_exit:
 	*out_rec = clust_rec;
+func_exit:
 	err = DB_SUCCESS;
 err_exit:
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	return(err);
@@ -1066,7 +1065,7 @@ row_sel_try_search_shortcut(
 
 	plan->n_rows_fetched++;
 func_exit:
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	return(SEL_FOUND);
@@ -1261,7 +1260,7 @@ rec_loop:
 	/* PHASE 1: Set a lock if specified */
 
 	if (!node->asc && cursor_just_opened
-		&& (rec != page_get_supremum_rec(buf_frame_align(rec)))) {
+		&& !page_rec_is_supremum(rec)) {
 
 		/* When we open a cursor for a descending search, we must set
 		a next-key lock on the successor record: otherwise it would
@@ -1299,7 +1298,7 @@ rec_loop:
 		}
 	}
 
-	if (rec == page_get_infimum_rec(buf_frame_align(rec))) {
+	if (page_rec_is_infimum(rec)) {
 
 		/* The infimum record on a page cannot be in the result set,
 		and neither can a record lock be placed on it: we skip such
@@ -1337,7 +1336,7 @@ rec_loop:
 		}
 	}
 
-	if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
+	if (page_rec_is_supremum(rec)) {
 
 		/* A page supremum record cannot be in the result set: skip
 		it now when we have placed a possible lock on it */
@@ -1780,7 +1779,7 @@ lock_wait_or_error:
 	ut_ad(sync_thread_levels_empty_gen(TRUE));
 
 func_exit:
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	return(err);
@@ -2416,14 +2415,12 @@ row_sel_store_mysql_rec(
 	mem_heap_t*		extern_field_heap	= NULL;
 	byte*			data;
 	ulint			len;
-	byte*			blob_buf;
-	int			pad_char;
 	ulint			i;
 	
 	ut_ad(prebuilt->mysql_template);
 	ut_ad(rec_offs_validate(rec, NULL, offsets));
 
-	if (prebuilt->blob_heap != NULL) {
+	if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
 		mem_heap_free(prebuilt->blob_heap);
 		prebuilt->blob_heap = NULL;
 	}
@@ -2435,7 +2432,8 @@ row_sel_store_mysql_rec(
 		data = rec_get_nth_field(rec, offsets,
 					templ->rec_field_no, &len);
 
-		if (rec_offs_nth_extern(offsets, templ->rec_field_no)) {
+		if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets,
+						templ->rec_field_no))) {
 
 			/* Copy an externally stored field to the temporary
 			heap */
@@ -2456,7 +2454,7 @@ row_sel_store_mysql_rec(
 		}
 
 		if (len != UNIV_SQL_NULL) {
-			if (templ->type == DATA_BLOB) {
+			if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
 
 				ut_a(prebuilt->templ_contains_blob);
 
@@ -2465,8 +2463,9 @@ row_sel_store_mysql_rec(
 				of 1000000 bytes. Since the test takes some
 				CPU time, we do not use it for small BLOBs. */
 
-				if (len > 2000000
-				    && !ut_test_malloc(len + 1000000)) {
+				if (UNIV_UNLIKELY(len > 2000000)
+				    && UNIV_UNLIKELY(!ut_test_malloc(
+							len + 1000000))) {
 
 					ut_print_timestamp(stderr);
 					fprintf(stderr,
@@ -2492,11 +2491,9 @@ row_sel_store_mysql_rec(
 						mem_heap_create(len);
 				}
 
-				blob_buf = mem_heap_alloc(prebuilt->blob_heap,
-									len);
-				ut_memcpy(blob_buf, data, len);
-
-				data = blob_buf;
+				data = memcpy(mem_heap_alloc(
+						prebuilt->blob_heap, len),
+						data, len);
 			}
 		
 			row_sel_field_store_in_mysql_format(
@@ -2521,41 +2518,45 @@ row_sel_store_mysql_rec(
 			account caused seg faults with NULL BLOB fields, and
 		        bug number 154 in the MySQL bug database: GROUP BY
 		        and DISTINCT could treat NULL values inequal. */
+			int	pad_char;
 
 			mysql_rec[templ->mysql_null_byte_offset] |=
 					(byte) (templ->mysql_null_bit_mask);
-			if (templ->type == DATA_VARCHAR
-			    || templ->type == DATA_CHAR
-			    || templ->type == DATA_BINARY
-			    || templ->type == DATA_FIXBINARY
-			    || templ->type == DATA_MYSQL
-			    || templ->type == DATA_VARMYSQL) {
+			switch (templ->type) {
+			case DATA_VARCHAR:
+			case DATA_CHAR:
+			case DATA_BINARY:
+			case DATA_FIXBINARY:
+			case DATA_MYSQL:
+			case DATA_VARMYSQL:
 			        /* MySQL pads all non-BLOB and non-TEXT
 				string types with space ' ' */
-			    
-				pad_char = ' ';
-			} else {
-				pad_char = '\0';
+				if (UNIV_UNLIKELY(templ->mbminlen == 2)) {
+					/* Treat UCS2 as a special case. */
+					data = mysql_rec
+						+ templ->mysql_col_offset;
+					len = templ->mysql_col_len;
+					/* There are two UCS2 bytes per char,
+					so the length has to be even. */
+					ut_a(!(len & 1));
+					/* Pad with 0x0020. */
+					while (len) {
+						*data++ = 0x00;
+						*data++ = 0x20;
+						len -= 2;
+					}
+					continue;
+				}
+				pad_char = 0x20;
+				break;
+			default:
+				pad_char = 0x00;
+				break;
 			}
 
-			/* Handle UCS2 strings differently. */
-			if (pad_char != '\0' && templ->mbminlen == 2) {
-				/* There are two bytes per char, so the length
-				has to be an even number. */
-				ut_a(!(templ->mysql_col_len & 1));
-				data = mysql_rec + templ->mysql_col_offset;
-				len = templ->mysql_col_len;
-				/* Pad with 0x0020. */
-				while (len >= 2) {
-					*data++ = 0x00;
-					*data++ = 0x20;
-					len -= 2;
-				}
-			} else {
-				ut_ad(!pad_char || templ->mbminlen == 1);
-				memset(mysql_rec + templ->mysql_col_offset,
+			ut_ad(!pad_char || templ->mbminlen == 1);
+			memset(mysql_rec + templ->mysql_col_offset,
 					pad_char, templ->mysql_col_len);
-			}
 		}
 	} 
 
@@ -2849,8 +2850,9 @@ row_sel_pop_cached_row_for_mysql(
 	mysql_row_templ_t*	templ;
 	byte*			cached_rec;
         ut_ad(prebuilt->n_fetch_cached > 0);
+	ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len);
 	
-	if (prebuilt->keep_other_fields_on_keyread)
+	if (UNIV_UNLIKELY(prebuilt->keep_other_fields_on_keyread))
 	{
 		/* Copy cache record field by field, don't touch fields that 
 		are not covered by current key */
@@ -2877,7 +2879,7 @@ row_sel_pop_cached_row_for_mysql(
 	else
 	{
 		ut_memcpy(buf, prebuilt->fetch_cache[prebuilt->fetch_cache_first],
-				prebuilt->mysql_row_len);
+				prebuilt->mysql_prefix_len);
 	}
 	prebuilt->n_fetch_cached--;
 	prebuilt->fetch_cache_first++;
@@ -2925,9 +2927,9 @@ row_sel_push_cache_row_for_mysql(
 
 	ut_ad(prebuilt->fetch_cache_first == 0);
 
-	if (!row_sel_store_mysql_rec(
+	if (UNIV_UNLIKELY(!row_sel_store_mysql_rec(
 			prebuilt->fetch_cache[prebuilt->n_fetch_cached],
-			prebuilt, rec, offsets)) {
+			prebuilt, rec, offsets))) {
 		ut_error;
 	}
 
@@ -3048,11 +3050,7 @@ row_search_for_mysql(
 	rec_t*		index_rec;
 	rec_t*		clust_rec;
 	rec_t*		old_vers;
-	ulint		err             = DB_SUCCESS;
-	ibool		moved;
-	ibool		cons_read_requires_clust_rec;
-	ibool		was_lock_wait;
-	ulint		shortcut;
+	ulint		err				= DB_SUCCESS;
 	ibool		unique_search			= FALSE;
 	ibool		unique_search_from_clust_index	= FALSE;
 	ibool		mtr_has_extra_clust_latch 	= FALSE;
@@ -3062,9 +3060,9 @@ row_search_for_mysql(
 					locking SELECT, and the isolation
 					level is <= TRX_ISO_READ_COMMITTED,
 					then this is set to FALSE */
-	ibool		success;
-	ibool		comp;
+#ifdef UNIV_SEARCH_DEBUG
 	ulint		cnt				= 0;
+#endif /* UNIV_SEARCH_DEBUG */
 	ulint		next_offs;
 	mtr_t		mtr;
 	mem_heap_t*	heap				= NULL;
@@ -3075,7 +3073,7 @@ row_search_for_mysql(
 	ut_ad(index && pcur && search_tuple);
 	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
 
-	if (prebuilt->table->ibd_file_missing) {
+	if (UNIV_UNLIKELY(prebuilt->table->ibd_file_missing)) {
 	        ut_print_timestamp(stderr);
 	        fprintf(stderr, "  InnoDB: Error:\n"
 "InnoDB: MySQL is trying to use a table handle but the .ibd file for\n"
@@ -3089,7 +3087,7 @@ row_search_for_mysql(
 		return(DB_ERROR);
 	}
 
-	if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
+	if (UNIV_UNLIKELY(prebuilt->magic_n != ROW_PREBUILT_ALLOCATED)) {
 		fprintf(stderr,
 		"InnoDB: Error: trying to free a corrupt\n"
 		"InnoDB: table handle. Magic n %lu, table name ",
@@ -3103,7 +3101,7 @@ row_search_for_mysql(
 	}
 
 	if (trx->n_mysql_tables_in_use == 0
-            && prebuilt->select_lock_type == LOCK_NONE) {
+	    && UNIV_UNLIKELY(prebuilt->select_lock_type == LOCK_NONE)) {
 		/* Note that if MySQL uses an InnoDB temp table that it
 		created inside LOCK TABLES, then n_mysql_tables_in_use can
 		be zero; in that case select_lock_type is set to LOCK_X in
@@ -3126,8 +3124,8 @@ row_search_for_mysql(
 	/* PHASE 0: Release a possible s-latch we are holding on the
 	adaptive hash index latch if there is someone waiting behind */
 
-	if (trx->has_search_latch
-	    && btr_search_latch.writer != RW_LOCK_NOT_LOCKED) {
+	if (UNIV_UNLIKELY(btr_search_latch.writer != RW_LOCK_NOT_LOCKED)
+	    && trx->has_search_latch) {
 
 		/* There is an x-latch request on the adaptive hash index:
 		release the s-latch to reduce starvation and wait for
@@ -3143,7 +3141,7 @@ row_search_for_mysql(
 	/*-------------------------------------------------------------*/
 	/* PHASE 1: Try to pop the row from the prefetch cache */
 
-	if (direction == 0) {
+	if (UNIV_UNLIKELY(direction == 0)) {
 		trx->op_info = "starting index read";
 	
 		prebuilt->n_rows_fetched = 0;
@@ -3161,8 +3159,8 @@ row_search_for_mysql(
 			prebuilt->fetch_direction = direction;
 		}
 
-		if (direction != prebuilt->fetch_direction) {
-			if (prebuilt->n_fetch_cached > 0) {
+		if (UNIV_UNLIKELY(direction != prebuilt->fetch_direction)) {
+			if (UNIV_UNLIKELY(prebuilt->n_fetch_cached > 0)) {
 				ut_error;
 				/* TODO: scrollable cursor: restore cursor to
 				the place of the latest returned row,
@@ -3174,7 +3172,7 @@ row_search_for_mysql(
 			prebuilt->n_fetch_cached = 0;
 			prebuilt->fetch_cache_first = 0;
 
-		} else if (prebuilt->n_fetch_cached > 0) {
+		} else if (UNIV_LIKELY(prebuilt->n_fetch_cached > 0)) {
 			row_sel_pop_cached_row_for_mysql(buf, prebuilt);
 
 			prebuilt->n_rows_fetched++;
@@ -3234,7 +3232,8 @@ row_search_for_mysql(
 		1 column. Return immediately if this is not a HANDLER
 		command. */
 
-		if (direction != 0 && !prebuilt->used_in_HANDLER) {
+		if (UNIV_UNLIKELY(direction != 0 &&
+				!prebuilt->used_in_HANDLER)) {
         
 			err = DB_RECORD_NOT_FOUND;
 			goto func_exit;
@@ -3252,9 +3251,9 @@ row_search_for_mysql(
 	cannot use the adaptive hash index in a search in the case the row
 	may be long and there may be externally stored fields */
 
-	if (unique_search
+	if (UNIV_UNLIKELY(direction == 0)
+	    && unique_search
 	    && index->type & DICT_CLUSTERED
-	    && direction == 0
 	    && !prebuilt->templ_contains_blob
 	    && !prebuilt->used_in_HANDLER
 	    && (prebuilt->mysql_row_len < UNIV_PAGE_SIZE / 8)) {
@@ -3286,9 +3285,9 @@ row_search_for_mysql(
 				trx->has_search_latch = TRUE;
 			}
 #endif
-			shortcut = row_sel_try_search_shortcut_for_mysql(&rec,
-					prebuilt, &offsets, &heap, &mtr);
-			if (shortcut == SEL_FOUND) {
+			switch (row_sel_try_search_shortcut_for_mysql(&rec,
+					prebuilt, &offsets, &heap, &mtr)) {
+			case SEL_FOUND:
 #ifdef UNIV_SEARCH_DEBUG
 				ut_a(0 == cmp_dtuple_rec(search_tuple,
 							rec, offsets));
@@ -3322,9 +3321,8 @@ row_search_for_mysql(
 				position */
 				err = DB_SUCCESS;
 				goto func_exit;
-			
-			} else if (shortcut == SEL_EXHAUSTED) {
 
+			case SEL_EXHAUSTED:
  				mtr_commit(&mtr);
 
 				/* ut_print_name(stderr, index->name);
@@ -3367,6 +3365,7 @@ shortcut_fails_too_big_rec:
 
 		/* Scan the MySQL query string; check if SELECT is the first
 	        word there */
+		ibool	success;
 
 		dict_accept(*trx->mysql_query_str, "SELECT", &success);
 
@@ -3382,7 +3381,7 @@ shortcut_fails_too_big_rec:
 	naturally moves upward (in fetch next) in alphabetical order,
 	otherwise downward */
 	
-	if (direction == 0) {
+	if (UNIV_UNLIKELY(direction == 0)) {
 		if (mode == PAGE_CUR_GE || mode == PAGE_CUR_G) {
 			moves_up = TRUE;
 		}
@@ -3396,10 +3395,9 @@ shortcut_fails_too_big_rec:
 
 	clust_index = dict_table_get_first_index(index->table);
 
-	if (direction != 0) {		
-		moved = sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
-							moves_up, &mtr);
-		if (!moved) {
+	if (UNIV_LIKELY(direction != 0)) {
+		if (!sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
+							moves_up, &mtr)) {
 			goto next_rec;
 		}
 
@@ -3440,11 +3438,13 @@ shortcut_fails_too_big_rec:
 		trx_assign_read_view(trx);
 		prebuilt->sql_stat_start = FALSE;
 	} else {
+		ulint	lock_mode;
 		if (prebuilt->select_lock_type == LOCK_S) {		
-			err = lock_table(0, index->table, LOCK_IS, thr);
+			lock_mode = LOCK_IS;
 		} else {
-			err = lock_table(0, index->table, LOCK_IX, thr);
+			lock_mode = LOCK_IX;
 		}
+		err = lock_table(0, index->table, lock_mode, thr);
 
 		if (err != DB_SUCCESS) {
 
@@ -3458,8 +3458,8 @@ rec_loop:
 	/* PHASE 4: Look for matching records in a loop */
 	
 	rec = btr_pcur_get_rec(pcur);
-	comp = index->table->comp;
-	ut_ad(comp == page_is_comp(buf_frame_align(rec)));
+	ut_ad(!!page_rec_is_comp(rec) == index->table->comp);
+#ifdef UNIV_SEARCH_DEBUG
 /*
 	fputs("Using ", stderr);
 	dict_index_name_print(stderr, index);
@@ -3467,7 +3467,9 @@ rec_loop:
 			buf_frame_get_page_no(buf_frame_align(rec)));
 	rec_print(rec);
 */
-	if (rec == page_get_infimum_rec(buf_frame_align(rec))) {
+#endif /* UNIV_SEARCH_DEBUG */
+
+	if (page_rec_is_infimum(rec)) {
 
 		/* The infimum record on a page cannot be in the result set,
 		and neither can a record lock be placed on it: we skip such
@@ -3476,10 +3478,11 @@ rec_loop:
 		goto next_rec;
 	}
 
-	if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
+	if (page_rec_is_supremum(rec)) {
 
-		if (prebuilt->select_lock_type != LOCK_NONE
-		    && set_also_gap_locks) {
+		if (set_also_gap_locks
+		    && !srv_locks_unsafe_for_binlog
+		    && prebuilt->select_lock_type != LOCK_NONE) {
 
 			/* Try to place a lock on the index record */
 
@@ -3487,18 +3490,16 @@ rec_loop:
 			we do not lock gaps. Supremum record is really
 			a gap and therefore we do not set locks there. */
 			
-			if (!srv_locks_unsafe_for_binlog) {
-				offsets = rec_get_offsets(rec, index, offsets,
-						ULINT_UNDEFINED, &heap);
-				err = sel_set_rec_lock(rec, index, offsets,
-						prebuilt->select_lock_type,
-						LOCK_ORDINARY, thr);
-				if (err != DB_SUCCESS) {
+			offsets = rec_get_offsets(rec, index, offsets,
+					ULINT_UNDEFINED, &heap);
+			err = sel_set_rec_lock(rec, index, offsets,
+					prebuilt->select_lock_type,
+					LOCK_ORDINARY, thr);
 
-					goto lock_wait_or_error;
-				}
-			}
+			if (err != DB_SUCCESS) {
 
+				goto lock_wait_or_error;
+			}
 		}
 		/* A page supremum record cannot be in the result set: skip
 		it now that we have placed a possible lock on it */
@@ -3510,12 +3511,19 @@ rec_loop:
 	/* Do sanity checks in case our cursor has bumped into page
 	corruption */
 	
-	next_offs = rec_get_next_offs(rec, comp);
-
-	if (next_offs >= UNIV_PAGE_SIZE
-		|| next_offs <
-		(ulint) (comp ? PAGE_NEW_SUPREMUM : PAGE_OLD_SUPREMUM)) {
-
+	if (page_rec_is_comp(rec)) {
+		next_offs = rec_get_next_offs(rec, TRUE);
+		if (UNIV_UNLIKELY(next_offs < PAGE_NEW_SUPREMUM)) {
+			goto wrong_offs;
+		}
+	} else {
+		next_offs = rec_get_next_offs(rec, FALSE);
+		if (UNIV_UNLIKELY(next_offs < PAGE_OLD_SUPREMUM)) {
+			goto wrong_offs;
+		}
+	}
+	if (UNIV_UNLIKELY(next_offs >= UNIV_PAGE_SIZE - PAGE_DIR)) {
+	wrong_offs:
 		if (srv_force_recovery == 0 || moves_up == FALSE) {
 			ut_print_timestamp(stderr);
 			buf_page_print(buf_frame_align(rec));
@@ -3528,7 +3536,7 @@ rec_loop:
 			fprintf(stderr,
 "InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n"
 "InnoDB: ",
-				(ulong) (rec - buf_frame_align(rec)),
+				(ulong) ut_align_offset(rec, UNIV_PAGE_SIZE),
 				(ulong) next_offs,
 				(ulong) buf_frame_get_page_no(rec));
 			dict_index_name_print(stderr, trx, index);
@@ -3546,7 +3554,7 @@ rec_loop:
 			fprintf(stderr,
 "InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n"
 "InnoDB: ",
-			   (ulong) (rec - buf_frame_align(rec)),
+			   (ulong) ut_align_offset(rec, UNIV_PAGE_SIZE),
 			   (ulong) next_offs,
 			   (ulong) buf_frame_get_page_no(rec));
 			dict_index_name_print(stderr, trx, index);
@@ -3561,13 +3569,13 @@ rec_loop:
 
 	offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
 
-	if (srv_force_recovery > 0) {
+	if (UNIV_UNLIKELY(srv_force_recovery > 0)) {
 		if (!rec_validate(rec, offsets)
 		|| !btr_index_rec_validate(rec, index, FALSE)) {
 			fprintf(stderr,
 "InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n"
 "InnoDB: ",
-			   (ulong) (rec - buf_frame_align(rec)),
+			   (ulong) ut_align_offset(rec, UNIV_PAGE_SIZE),
 			   (ulong) next_offs,
 			   (ulong) buf_frame_get_page_no(rec));
 			dict_index_name_print(stderr, trx, index);
@@ -3593,25 +3601,22 @@ rec_loop:
 		
 		if (0 != cmp_dtuple_rec(search_tuple, rec, offsets)) {
 
-			if (prebuilt->select_lock_type != LOCK_NONE
-		    	    && set_also_gap_locks) {
+			if (set_also_gap_locks
+			    && !srv_locks_unsafe_for_binlog
+			    && prebuilt->select_lock_type != LOCK_NONE) {
 
 				/* Try to place a gap lock on the index 
 				record only if innodb_locks_unsafe_for_binlog
 				option is not set */
 
-				if (srv_locks_unsafe_for_binlog == FALSE) { 
-
-					err = sel_set_rec_lock(rec, index,
-						offsets,
+				err = sel_set_rec_lock(rec, index, offsets,
 						prebuilt->select_lock_type,
 						LOCK_GAP, thr);
-					if (err != DB_SUCCESS) {
 
-						goto lock_wait_or_error;
-					}
-				}
+				if (err != DB_SUCCESS) {
 
+					goto lock_wait_or_error;
+				}
 			}
 
 			btr_pcur_store_position(pcur, &mtr);
@@ -3627,25 +3632,22 @@ rec_loop:
 
 		if (!cmp_dtuple_is_prefix_of_rec(search_tuple, rec, offsets)) {
 			
-			if (prebuilt->select_lock_type != LOCK_NONE
-			    && set_also_gap_locks) {
+			if (set_also_gap_locks
+			    && !srv_locks_unsafe_for_binlog
+			    && prebuilt->select_lock_type != LOCK_NONE) {
 
 				/* Try to place a gap lock on the index 
 				record only if innodb_locks_unsafe_for_binlog
 				option is not set */
 
-				if (srv_locks_unsafe_for_binlog == FALSE) {
-
-					err = sel_set_rec_lock(rec, index,
-						offsets,
+				err = sel_set_rec_lock(rec, index, offsets,
 						prebuilt->select_lock_type,
 						LOCK_GAP, thr);
-					if (err != DB_SUCCESS) {
 
-						goto lock_wait_or_error;
-					}
-				}
+				if (err != DB_SUCCESS) {
 
+					goto lock_wait_or_error;
+				}
 			}
 
 			btr_pcur_store_position(pcur, &mtr);
@@ -3661,29 +3663,25 @@ rec_loop:
 	/* We are ready to look at a possible new index entry in the result
 	set: the cursor is now placed on a user record */
 
-	cons_read_requires_clust_rec = FALSE;
-
 	if (prebuilt->select_lock_type != LOCK_NONE) {
 		/* Try to place a lock on the index record; note that delete
 		marked records are a special case in a unique search. If there
 		is a non-delete marked record, then it is enough to lock its
 		existence with LOCK_REC_NOT_GAP. */
 
+		/* If innodb_locks_unsafe_for_binlog option is used,
+		we lock only the record, i.e., next-key locking is
+		not used. */
+
 		ulint	lock_type;
 
 		if (!set_also_gap_locks
-		    || (unique_search && !rec_get_deleted_flag(rec, comp))) {
-			lock_type = LOCK_REC_NOT_GAP;
+		    || srv_locks_unsafe_for_binlog
+		    || (unique_search && !UNIV_UNLIKELY(rec_get_deleted_flag(
+					rec, page_rec_is_comp(rec))))) {
+			goto no_gap_lock;
 		} else {
-			/* If innodb_locks_unsafe_for_binlog option is used, 
-			we lock only the record, i.e., next-key locking is
-			not used. */
-
-	                if (srv_locks_unsafe_for_binlog) {
-				lock_type = LOCK_REC_NOT_GAP;
-			} else {
-				lock_type = LOCK_ORDINARY;
- 			}
+			lock_type = LOCK_ORDINARY;
 		}
 
 		/* If we are doing a 'greater or equal than a primary key
@@ -3703,7 +3701,7 @@ rec_loop:
 		    && dtuple_get_n_fields_cmp(search_tuple)
 		       == dict_index_get_n_unique(index)
 		    && 0 == cmp_dtuple_rec(search_tuple, rec, offsets)) {
-
+		no_gap_lock:
 			lock_type = LOCK_REC_NOT_GAP;
 		}
 
@@ -3731,7 +3729,7 @@ rec_loop:
 			high force recovery level set, we try to avoid crashes
 			by skipping this lookup */
 
-			if (srv_force_recovery < 5
+			if (UNIV_LIKELY(srv_force_recovery < 5)
                             && !lock_clust_rec_cons_read_sees(rec, index,
 						offsets, trx->read_view)) {
 
@@ -3762,13 +3760,15 @@ rec_loop:
 			have to look also into the clustered index: this
 			is necessary, because we can only get the undo
 			information via the clustered index record. */
-			
-			cons_read_requires_clust_rec = TRUE;
+
+			/* Get the clustered index record if needed */
+			index_rec = rec;
+			ut_ad(index != clust_index);
+			goto requires_clust_rec;
 		}
 	}
 
-	if (rec_get_deleted_flag(rec, comp)
-			&& !cons_read_requires_clust_rec) {
+	if (UNIV_UNLIKELY(rec_get_deleted_flag(rec, page_rec_is_comp(rec)))) {
 
 		/* The record is delete-marked: we can skip it if this is
 		not a consistent read which might see an earlier version
@@ -3782,14 +3782,14 @@ rec_loop:
 
 	index_rec = rec;
 
-	/* Before and after the following "if" block, "offsets" will be
-	related to "rec", which may be in "index", a secondary index or
-	the clustered index ("clust_index").  However, after this "if" block,
-	"rec" may be pointing to "clust_rec" of "clust_index". */
-	ut_ad(rec_offs_validate(rec, index, offsets));
-
-	if (index != clust_index && (cons_read_requires_clust_rec
-				|| prebuilt->need_to_access_clustered)) {
+	if (index != clust_index && prebuilt->need_to_access_clustered) {
+	requires_clust_rec:
+		/* Before and after this "if" block, "offsets" will be
+		related to "rec", which may be in a secondary index "index" or
+		the clustered index ("clust_index").  However, after this
+		"if" block, "rec" may be pointing to
+		"clust_rec" of "clust_index". */
+		ut_ad(rec_offs_validate(rec, index, offsets));
 
 		/* It was a non-clustered index and we must fetch also the
 		clustered index record */
@@ -3811,7 +3811,8 @@ rec_loop:
 			goto next_rec;
 		}
 
-		if (rec_get_deleted_flag(clust_rec, comp)) {
+		if (UNIV_UNLIKELY(rec_get_deleted_flag(clust_rec,
+					page_rec_is_comp(clust_rec)))) {
 
 			/* The record is delete marked: we can skip it */
 
@@ -3832,7 +3833,8 @@ rec_loop:
 				rec == clust_rec ? clust_index : index,
 				offsets));
 
-	if (prebuilt->n_rows_fetched >= MYSQL_FETCH_CACHE_THRESHOLD
+	if ((match_mode == ROW_SEL_EXACT
+		|| prebuilt->n_rows_fetched >= MYSQL_FETCH_CACHE_THRESHOLD)
 			&& prebuilt->select_lock_type == LOCK_NONE
 			&& !prebuilt->templ_contains_blob
 			&& !prebuilt->clust_index_was_generated
@@ -3907,7 +3909,7 @@ next_rec:
 	/*-------------------------------------------------------------*/
 	/* PHASE 5: Move the cursor to the next index record */
 	
-	if (mtr_has_extra_clust_latch) {
+	if (UNIV_UNLIKELY(mtr_has_extra_clust_latch)) {
 		/* We must commit mtr if we are moving to the next
 		non-clustered index record, because we could break the
 		latching order if we would access a different clustered
@@ -3919,34 +3921,38 @@ next_rec:
 		mtr_has_extra_clust_latch = FALSE;
 	
 		mtr_start(&mtr);
-		moved = sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
-							moves_up, &mtr);
-		if (moved) {
+		if (sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
+							moves_up, &mtr)) {
+#ifdef UNIV_SEARCH_DEBUG
 			cnt++;
+#endif /* UNIV_SEARCH_DEBUG */
 
 			goto rec_loop;
 		}
 	}
 
 	if (moves_up) {		
-		moved = btr_pcur_move_to_next(pcur, &mtr);
-	} else {
-		moved = btr_pcur_move_to_prev(pcur, &mtr);
-	}
+		if (UNIV_UNLIKELY(!btr_pcur_move_to_next(pcur, &mtr))) {
+		not_moved:
+			btr_pcur_store_position(pcur, &mtr);
 
-	if (!moved) {
-		btr_pcur_store_position(pcur, &mtr);
+			if (match_mode != 0) {
+				err = DB_RECORD_NOT_FOUND;
+			} else {
+				err = DB_END_OF_INDEX;
+			}
 
-		if (match_mode != 0) {
-			err = DB_RECORD_NOT_FOUND;
-		} else {
-			err = DB_END_OF_INDEX;
+			goto normal_return;
+		}
+	} else {
+		if (UNIV_UNLIKELY(!btr_pcur_move_to_prev(pcur, &mtr))) {
+			goto not_moved;
 		}
-
-		goto normal_return;
 	}
 
+#ifdef UNIV_SEARCH_DEBUG
 	cnt++;
+#endif /* UNIV_SEARCH_DEBUG */
 
 	goto rec_loop;
 
@@ -3964,11 +3970,10 @@ lock_wait_or_error:
 
 	que_thr_stop_for_mysql(thr);
 
-  thr->lock_state= QUE_THR_LOCK_ROW;
-	was_lock_wait = row_mysql_handle_errors(&err, trx, thr, NULL);
-  thr->lock_state= QUE_THR_LOCK_NOLOCK;
+	thr->lock_state = QUE_THR_LOCK_ROW;
 
-	if (was_lock_wait) {
+	if (row_mysql_handle_errors(&err, trx, thr, NULL)) {
+		thr->lock_state = QUE_THR_LOCK_NOLOCK;
 		mtr_start(&mtr);
 
 		sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
@@ -3978,9 +3983,13 @@ lock_wait_or_error:
 		goto rec_loop;
 	}
 
+	thr->lock_state = QUE_THR_LOCK_NOLOCK;
+
+#ifdef UNIV_SEARCH_DEBUG
 /*	fputs("Using ", stderr);
 	dict_index_name_print(stderr, index);
 	fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */
+#endif /* UNIV_SEARCH_DEBUG */
 	goto func_exit;
 
 normal_return:
@@ -3995,16 +4004,18 @@ normal_return:
 		err = DB_SUCCESS;
 	}
 
+#ifdef UNIV_SEARCH_DEBUG
 /*	fputs("Using ", stderr);
 	dict_index_name_print(stderr, index);
 	fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */
+#endif /* UNIV_SEARCH_DEBUG */
 	if (err == DB_SUCCESS) {
 		srv_n_rows_read++;
 	}
 
 func_exit:
 	trx->op_info = "";
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	return(err);
diff --git a/innobase/row/row0undo.c b/innobase/row/row0undo.c
index abe73cbe705ac0ae7d222db6f0b73b72a46ec927..435c0279dbb6f47e67834371c579499fafe28d41 100644
--- a/innobase/row/row0undo.c
+++ b/innobase/row/row0undo.c
@@ -190,7 +190,7 @@ row_undo_search_clust_to_pcur(
 
 	btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	return(ret);
diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c
index 3305724a89b4b2033802e3550a7b7f7a35f6cb3a..cf2b8db5d32a8f566b446388cde52c1dd70da965 100644
--- a/innobase/row/row0upd.c
+++ b/innobase/row/row0upd.c
@@ -815,9 +815,10 @@ row_upd_build_difference_binary(
 			goto skip_compare;
 		}
 
-		extern_bit = rec_offs_nth_extern(offsets, i);
+		extern_bit = upd_ext_vec_contains(ext_vec, n_ext_vec, i);
 		
-		if (extern_bit != upd_ext_vec_contains(ext_vec, n_ext_vec, i)
+		if (UNIV_UNLIKELY(extern_bit ==
+				!rec_offs_nth_extern(offsets, i))
 		    || !dfield_data_is_binary_equal(dfield, len, data)) {
 
 			upd_field = upd_get_nth_field(update, n_diff);
@@ -826,12 +827,8 @@ row_upd_build_difference_binary(
 
 			upd_field_set_field_no(upd_field, i, index, trx);
 
-			if (upd_ext_vec_contains(ext_vec, n_ext_vec, i)) {
-				upd_field->extern_storage = TRUE;
-			} else {
-				upd_field->extern_storage = FALSE;
-			}
-				
+			upd_field->extern_storage = extern_bit;
+
 			n_diff++;
 		}
 skip_compare:
@@ -1224,7 +1221,7 @@ row_upd_store_row(
 	
 	node->n_ext_vec = btr_push_update_extern_fields(node->ext_vec,
 						offsets, update);
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 }
@@ -1270,7 +1267,7 @@ row_upd_sec_index_entry(
 
 	rec = btr_cur_get_rec(btr_cur);
 
-	if (!found) {
+	if (UNIV_UNLIKELY(!found)) {
 		fputs("InnoDB: error in sec index entry update in\n"
 			"InnoDB: ", stderr);
 		dict_index_name_print(stderr, trx, index);
@@ -1423,7 +1420,7 @@ row_upd_clust_rec_by_insert(
 							index, thr, mtr);
 			if (err != DB_SUCCESS) {
 				mtr_commit(mtr);
-				if (heap) {
+				if (UNIV_LIKELY_NULL(heap)) {
 					mem_heap_free(heap);
 				}
 				return(err);
@@ -1549,7 +1546,7 @@ row_upd_clust_rec(
 			rec_get_offsets(rec, index, offsets_,
 				ULINT_UNDEFINED, &heap),
 			big_rec, mtr);
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 		mtr_commit(mtr);
@@ -1719,7 +1716,7 @@ row_upd_clust_step(
 			node->index = dict_table_get_next_index(index);
 		}
 	exit_func:
-		if (heap) {
+		if (UNIV_LIKELY_NULL(heap)) {
 			mem_heap_free(heap);
 		}
 		return(err);
@@ -1736,7 +1733,7 @@ row_upd_clust_step(
 		row_upd_eval_new_vals(node->update);
 	}
 
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 		
@@ -2016,7 +2013,7 @@ row_upd_in_place_in_select(
 			btr_pcur_get_rec(pcur), btr_cur->index, offsets_,
 			ULINT_UNDEFINED, &heap),
 		UT_LIST_GET_FIRST(node->columns));
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	row_upd_eval_new_vals(node->update);
diff --git a/innobase/row/row0vers.c b/innobase/row/row0vers.c
index 36f6c27636df9c8573db4021e38f7470b8998464..8e747423047035a4d36effb0cce83ea76063876a 100644
--- a/innobase/row/row0vers.c
+++ b/innobase/row/row0vers.c
@@ -57,11 +57,11 @@ row_vers_impl_x_locked_off_kernel(
 	dtuple_t*	entry	= NULL; /* assignment to eliminate compiler
 					warning */
 	trx_t*		trx;
-	ibool		vers_del;
-	ibool		rec_del;
+	ulint		vers_del;
+	ulint		rec_del;
 	ulint		err;
 	mtr_t		mtr;
-	ibool		comp;
+	ulint		comp;
 	
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&kernel_mutex));
@@ -121,10 +121,10 @@ row_vers_impl_x_locked_off_kernel(
 		goto exit_func;
 	}
 
-	comp = index->table->comp;
+	comp = page_rec_is_comp(rec);
 	ut_ad(index->table == clust_index->table);
-	ut_ad(comp == page_is_comp(buf_frame_align(rec)));
-	ut_ad(comp == page_is_comp(buf_frame_align(clust_rec)));
+	ut_ad(!!comp == index->table->comp);
+	ut_ad(!comp == !page_rec_is_comp(clust_rec));
 
 	/* We look up if some earlier version, which was modified by the trx_id
 	transaction, of the clustered index record would require rec to be in
@@ -310,7 +310,7 @@ row_vers_old_has_index_entry(
 	dtuple_t*	row;
 	dtuple_t*	entry;
 	ulint		err;
-	ibool		comp;
+	ulint		comp;
 
 	ut_ad(mtr_memo_contains(mtr, buf_block_align(rec), MTR_MEMO_PAGE_X_FIX)
 	   	|| mtr_memo_contains(mtr, buf_block_align(rec),
@@ -322,8 +322,8 @@ row_vers_old_has_index_entry(
 
 	clust_index = dict_table_get_first_index(index->table);
 
-	comp = index->table->comp;
-	ut_ad(comp == page_is_comp(buf_frame_align(rec)));
+	comp = page_rec_is_comp(rec);
+	ut_ad(!index->table->comp == !comp);
 	heap = mem_heap_create(1024);
 	clust_offsets = rec_get_offsets(rec, clust_index, NULL,
 					ULINT_UNDEFINED, &heap);
diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c
index 541b73b831df8c848591b25e11bae900a3563f12..7798e0c8e32d33e89f10f1785b321db4dd2fa30e 100644
--- a/innobase/srv/srv0start.c
+++ b/innobase/srv/srv0start.c
@@ -1040,7 +1040,9 @@ innobase_start_or_create_for_mysql(void)
 
 	srv_start_has_been_called = TRUE;
 
+#ifdef UNIV_DEBUG
 	log_do_write = TRUE;
+#endif /* UNIV_DEBUG */
 /*	yydebug = TRUE; */
 
 	srv_is_being_started = TRUE;
@@ -1554,8 +1556,9 @@ NetWare. */
 
 	os_thread_create(&srv_master_thread, NULL, thread_ids + 1 +
 							SRV_MAX_N_IO_THREADS);
+#ifdef UNIV_DEBUG
 	/* buf_debug_prints = TRUE; */
-
+#endif /* UNIV_DEBUG */
 	sum_of_data_file_sizes = 0;
 	
 	for (i = 0; i < srv_n_data_files; i++) {
diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c
index e604912e996571c4b789fddb5fe5181efd097423..f0f0e9a3a2ec22891514045c14b154b3736dc44f 100644
--- a/innobase/sync/sync0sync.c
+++ b/innobase/sync/sync0sync.c
@@ -1136,8 +1136,12 @@ sync_thread_add_level(
 	} else if (level == SYNC_DICT_HEADER) {
 		ut_a(sync_thread_levels_g(array, SYNC_DICT_HEADER));
 	} else if (level == SYNC_DICT) {
+#ifdef UNIV_DEBUG
 		ut_a(buf_debug_prints
 		     || sync_thread_levels_g(array, SYNC_DICT));
+#else /* UNIV_DEBUG */
+		ut_a(sync_thread_levels_g(array, SYNC_DICT));
+#endif /* UNIV_DEBUG */
 	} else {
 		ut_error;
 	}
diff --git a/innobase/trx/trx0rec.c b/innobase/trx/trx0rec.c
index fcb7582ce7307dbe1a9989881531bed1bd3e8411..3f3cfd3b000d27608a9b86de1c56e4b9a17acb9b 100644
--- a/innobase/trx/trx0rec.c
+++ b/innobase/trx/trx0rec.c
@@ -1134,7 +1134,7 @@ trx_undo_report_row_operation(
 
 			mutex_exit(&(trx->undo_mutex));
 			mtr_commit(&mtr);
-			if (heap) {
+			if (UNIV_LIKELY_NULL(heap)) {
 				mem_heap_free(heap);
 			}
 			return(DB_OUT_OF_FILE_SPACE);
@@ -1153,7 +1153,7 @@ trx_undo_report_row_operation(
 
 	*roll_ptr = trx_undo_build_roll_ptr(is_insert, rseg->id, page_no,
 								offset);
-	if (heap) {
+	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 	return(DB_SUCCESS);
diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c
index 69f7a99187fed9a354f708f30464c48350158964..fdfb7428129cd067936fa95bf67a4bdb9712bade 100644
--- a/innobase/trx/trx0roll.c
+++ b/innobase/trx/trx0roll.c
@@ -1237,10 +1237,12 @@ trx_finish_rollback_off_kernel(
 		return;
 	}
 
+#ifdef UNIV_DEBUG
 	if (lock_print_waits) {			
 		fprintf(stderr, "Trx %lu rollback finished\n",
 						(ulong) ut_dulint_get_low(trx->id));
 	}
+#endif /* UNIV_DEBUG */
 
 	trx_commit_off_kernel(trx);
 
diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c
index c6d1f953772171a7e778fe9a52144aa960f2d56f..9e155ee1de0876e11500a3d4b0cfff549c31fb89 100644
--- a/innobase/trx/trx0trx.c
+++ b/innobase/trx/trx0trx.c
@@ -158,8 +158,6 @@ trx_create(
 	trx->n_tickets_to_enter_innodb = 0;
 
 	trx->auto_inc_lock = NULL;
-	trx->n_lock_table_exp = 0;
-	trx->n_lock_table_transactional = 0;
 	
 	trx->read_view_heap = mem_heap_create(256);
 	trx->read_view = NULL;
@@ -309,8 +307,6 @@ trx_free(
 
 	ut_a(!trx->has_search_latch);
 	ut_a(!trx->auto_inc_lock);
-	ut_a(!trx->n_lock_table_exp);
-	ut_a(!trx->n_lock_table_transactional);
 
 	ut_a(trx->dict_operation_lock_mode == 0);
 
@@ -1711,12 +1707,6 @@ trx_print(
 					(ulong) trx->mysql_n_tables_locked);
 	}
 
-	if (trx->n_lock_table_transactional > 0 || trx->n_lock_table_exp > 0) {
-fprintf(f, "mysql explicit table locks %lu, transactional table locks %lu\n",
-				(ulong) trx->n_lock_table_exp,
-				(ulong) trx->n_lock_table_transactional);
-        }
-
 	newline = TRUE;
 
   	switch (trx->que_state) {
diff --git a/innobase/ut/ut0dbg.c b/innobase/ut/ut0dbg.c
index 0f6a27d35d95c54e6d37997219bfa730c11c16d7..e810d8dead76f759d740d380829ca95db0b4dad1 100644
--- a/innobase/ut/ut0dbg.c
+++ b/innobase/ut/ut0dbg.c
@@ -8,8 +8,11 @@ Created 1/30/1994 Heikki Tuuri
 
 #include "univ.i"
 
+#if defined(__GNUC__) && (__GNUC__ > 2)
+#else
 /* This is used to eliminate compiler warnings */
 ulint	ut_dbg_zero	= 0;
+#endif
 
 /* If this is set to TRUE all threads will stop into the next assertion
 and assert */
@@ -19,21 +22,69 @@ ibool panic_shutdown = FALSE;  	/* This is set to TRUE when on NetWare there
 				happens an InnoDB assertion failure or other
 				fatal error condition that requires an
 				immediate shutdown. */
-#endif
+#else /* __NETWARE__ */
 /* Null pointer used to generate memory trap */
 
 ulint*	ut_dbg_null_ptr		= NULL;
+#endif /* __NETWARE__ */
+
+/*****************************************************************
+Report a failed assertion. */
 
-const char*	ut_dbg_msg_assert_fail =
-"InnoDB: Assertion failure in thread %lu in file %s line %lu\n";
-const char*	ut_dbg_msg_trap =
+void
+ut_dbg_assertion_failed(
+/*====================*/
+	const char* expr,	/* in: the failed assertion (optional) */
+	const char* file,	/* in: source file containing the assertion */
+	ulint line)		/* in: line number of the assertion */
+{
+	ut_print_timestamp(stderr);
+	fprintf(stderr,
+		"InnoDB: Assertion failure in thread %lu"
+		" in file %s line %lu\n",
+		os_thread_pf(os_thread_get_curr_id()), file, line);
+	if (expr) {
+		fprintf(stderr,
+			"InnoDB: Failing assertion: %s\n", expr);
+	}
+
+	fputs(
 "InnoDB: We intentionally generate a memory trap.\n"
 "InnoDB: Submit a detailed bug report to http://bugs.mysql.com.\n"
 "InnoDB: If you get repeated assertion failures or crashes, even\n"
 "InnoDB: immediately after the mysqld startup, there may be\n"
 "InnoDB: corruption in the InnoDB tablespace. Please refer to\n"
 "InnoDB: http://dev.mysql.com/doc/mysql/en/Forcing_recovery.html\n"
-"InnoDB: about forcing recovery.\n";
+"InnoDB: about forcing recovery.\n", stderr);
+	ut_dbg_stop_threads = TRUE;
+}
+
+#ifdef __NETWARE__
+/*****************************************************************
+Shut down MySQL/InnoDB after assertion failure. */
+
+void
+ut_dbg_panic(void)
+/*==============*/
+{
+	if (!panic_shutdown) {
+		panic_shutdown = TRUE;
+		innobase_shutdown_for_mysql();
+	}
+	exit(1);
+}
+#else /* __NETWARE__ */
+/*****************************************************************
+Stop a thread after assertion failure. */
 
-const char*	ut_dbg_msg_stop =
-"InnoDB: Thread %lu stopped in file %s line %lu\n";
+void
+ut_dbg_stop_thread(
+/*===============*/
+	const char*	file,
+	ulint		line)
+{
+	fprintf(stderr, "InnoDB: Thread %lu stopped in file %s line %lu\n",
+		os_thread_pf(os_thread_get_curr_id()), file, line);
+	os_thread_sleep(1000000000);
+}
+#endif /* __NETWARE__ */
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 92ec482a468054091576547badaa6569596a6cf4..6dd07930244f6e52425e07d0fbb92535fdd95e9a 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -146,8 +146,7 @@ long innobase_mirrored_log_groups, innobase_log_files_in_group,
      innobase_buffer_pool_awe_mem_mb,
      innobase_buffer_pool_size, innobase_additional_mem_pool_size,
      innobase_file_io_threads,  innobase_lock_wait_timeout,
-     innobase_thread_concurrency, innobase_force_recovery,
-     innobase_open_files;
+     innobase_force_recovery, innobase_open_files;
 
 /* The default values for the following char* start-up parameters
 are determined in innobase_init below: */
@@ -327,7 +326,7 @@ innodb_srv_conc_enter_innodb(
 /*=========================*/
 	trx_t*	trx)	/* in: transaction handle */
 {
-	if (srv_thread_concurrency >= 500) {
+	if (UNIV_LIKELY(srv_thread_concurrency >= 20)) {
 
 		return;
 	}
@@ -344,7 +343,7 @@ innodb_srv_conc_exit_innodb(
 /*========================*/
 	trx_t*	trx)	/* in: transaction handle */
 {
-	if (srv_thread_concurrency >= 500) {
+	if (UNIV_LIKELY(srv_thread_concurrency >= 20)) {
 
 		return;
 	}
@@ -1044,6 +1043,18 @@ mysql_get_identifier_quote_char(
 						name, (int) namelen));
 }
 
+/**************************************************************************
+Determines if the currently running transaction has been interrupted. */
+extern "C"
+ibool
+trx_is_interrupted(
+/*===============*/
+			/* out: TRUE if interrupted */
+	trx_t*	trx)	/* in: transaction */
+{
+	return(trx && trx->mysql_thd && ((THD*) trx->mysql_thd)->killed);
+}
+
 /**************************************************************************
 Obtain a pointer to the MySQL THD object, as in current_thd().  This
 definition must match the one in sql/ha_innodb.cc! */
@@ -1302,8 +1313,8 @@ innobase_init(void)
 
 	data_mysql_default_charset_coll = (ulint)default_charset_info->number;
 
-	data_mysql_latin1_swedish_charset_coll =
-					(ulint)my_charset_latin1.number;
+	ut_a(DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL ==
+					my_charset_latin1.number);
 
 	/* Store the latin1_swedish_ci character ordering table to InnoDB. For
 	non-latin1_swedish_ci charsets we use the MySQL comparison functions,
@@ -2867,6 +2878,8 @@ build_template(
 	ibool		fetch_all_in_key	= FALSE;
 	ibool		fetch_primary_key_cols	= FALSE;
 	ulint		i;
+	/* byte offset of the end of last requested column */
+	ulint		mysql_prefix_len	= 0;
 
 	if (prebuilt->select_lock_type == LOCK_X) {
 		/* We always retrieve the whole clustered index record if we
@@ -2987,6 +3000,11 @@ build_template(
 					get_field_offset(table, field);
 
 		templ->mysql_col_len = (ulint) field->pack_length();
+		if (mysql_prefix_len < templ->mysql_col_offset
+				+ templ->mysql_col_len) {
+			mysql_prefix_len = templ->mysql_col_offset
+				+ templ->mysql_col_len;
+		}
 		templ->type = index->table->cols[i].type.mtype;
 		templ->mysql_type = (ulint)field->type();
 
@@ -3009,6 +3027,7 @@ skip_field:
 	}
 
 	prebuilt->n_template = n_requested_fields;
+	prebuilt->mysql_prefix_len = mysql_prefix_len;
 
 	if (index != clust_index && prebuilt->need_to_access_clustered) {
 		/* Change rec_field_no's to correspond to the clustered index
@@ -3080,7 +3099,7 @@ ha_innobase::write_row(
 		being blocked by a MySQL table lock TL_WRITE_ALLOW_READ. */
 
 		dict_table_t*	src_table;
-		ibool		mode;
+		ulint		mode;
 
 		num_write_row = 0;
 
@@ -5991,7 +6010,7 @@ ha_innobase::external_lock(
 
 				ulint	error;
 				error = row_lock_table_for_mysql(prebuilt,
-							NULL, LOCK_TABLE_EXP);
+							NULL, 0);
 
 				if (error != DB_SUCCESS) {
 					error = convert_error_code_to_mysql(
@@ -6011,9 +6030,6 @@ ha_innobase::external_lock(
 	trx->n_mysql_tables_in_use--;
 	prebuilt->mysql_has_locked = FALSE;
 
-	if (trx->n_lock_table_exp) {
-		row_unlock_tables_for_mysql(trx);
-	}
 
 	/* If the MySQL lock count drops to zero we know that the current SQL
 	statement has ended */
@@ -6055,7 +6071,7 @@ user issued query LOCK TABLES..WHERE ENGINE = InnoDB. */
 int
 ha_innobase::transactional_table_lock(
 /*==================================*/
-			        /* out: 0 */
+			        /* out: error code */
 	THD*	thd,		/* in: handle to the user thread */
 	int 	lock_type)	/* in: lock type */
 {
@@ -6119,8 +6135,7 @@ ha_innobase::transactional_table_lock(
 	if (thd->in_lock_tables && thd->variables.innodb_table_locks) {
 		ulint	error = DB_SUCCESS;
 
-		error = row_lock_table_for_mysql(prebuilt,NULL,
-						LOCK_TABLE_TRANSACTIONAL);
+		error = row_lock_table_for_mysql(prebuilt, NULL, 0);
 
 		if (error != DB_SUCCESS) {
 			error = convert_error_code_to_mysql((int) error, user_thd);
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
index 4c0f5209af91da9cc86ce0454b0be61058820db1..90cae3998ede27ae4adcfea723dfa1a507035b5c 100644
--- a/sql/ha_innodb.h
+++ b/sql/ha_innodb.h
@@ -218,7 +218,7 @@ extern long innobase_log_file_size, innobase_log_buffer_size;
 extern long innobase_buffer_pool_size, innobase_additional_mem_pool_size;
 extern long innobase_buffer_pool_awe_mem_mb;
 extern long innobase_file_io_threads, innobase_lock_wait_timeout;
-extern long innobase_force_recovery, innobase_thread_concurrency;
+extern long innobase_force_recovery;
 extern long innobase_open_files;
 extern char *innobase_data_home_dir, *innobase_data_file_path;
 extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 9c44d2189549eba2bd06c8f9a91f0971d72d3026..5e6df9b61e1439c1cdd132fbb7eaaf2d510b2f6e 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -5238,7 +5238,7 @@ log and this option does nothing anymore.",
   {"innodb_thread_concurrency", OPT_INNODB_THREAD_CONCURRENCY,
    "Helps in performance tuning in heavily concurrent environments.",
    (gptr*) &srv_thread_concurrency, (gptr*) &srv_thread_concurrency,
-   0, GET_LONG, REQUIRED_ARG, 8, 1, 1000, 0, 1, 0},
+   0, GET_LONG, REQUIRED_ARG, 20, 1, 1000, 0, 1, 0},
   {"innodb_thread_sleep_delay", OPT_INNODB_THREAD_SLEEP_DELAY,
    "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0"
     " disable a sleep",