diff --git a/VC++Files/libmysqltest/mytest.c b/VC++Files/libmysqltest/mytest.c
index 9af8c486e40..a1dc13db39f 100644
--- a/VC++Files/libmysqltest/mytest.c
+++ b/VC++Files/libmysqltest/mytest.c
@@ -91,6 +91,7 @@ main( int argc, char * argv[] )
        mysql_real_connect( myData, NULL, NULL, NULL, NULL, MYSQL_PORT,
 			   NULL, 0 ) )
     {
+      myData->reconnect= 1;
       if ( mysql_select_db( myData, szDB ) < 0 ) {
 	printf( "Can't select the %s database !\n", szDB ) ;
 	mysql_close( myData ) ;
diff --git a/VC++Files/mysqlmanager/mysqlmanagerview.cpp b/VC++Files/mysqlmanager/mysqlmanagerview.cpp
index 1d4756e7d7a..f39e0a9963e 100644
--- a/VC++Files/mysqlmanager/mysqlmanagerview.cpp
+++ b/VC++Files/mysqlmanager/mysqlmanagerview.cpp
@@ -551,6 +551,7 @@ void CMySqlManagerView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
 					PostMessage(WM_COMMAND,IDM_TOOLS_SERVER_PROPERTIES);
                return;
             }
+            mysql.reconnect= 1;
             if (!(result=mysql_list_processes(&mysql)))
             {
                return;
@@ -576,6 +577,7 @@ void CMySqlManagerView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
                                     );
                return;
             }
+            mysql.reconnect= 1;
             if (!(result=mysql_list_dbs(&mysql,0)))
             {
             }
@@ -603,6 +605,7 @@ void CMySqlManagerView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
                                     );
                return;
             }
+            mysql.reconnect= 1;
             CResourceDatabase* pRes = (CResourceDatabase*) pResource;
             CString strDB = pResource->GetDisplayName();
             strDB.TrimRight();
@@ -641,6 +644,7 @@ void CMySqlManagerView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
                                     );
                return;
             }
+            mysql.reconnect= 1;
             HTREEITEM hParent = m_pTree->GetParentItem(hItem);
             memset( &item, 0, sizeof(TV_ITEM) );
             item.hItem = hParent;
@@ -714,6 +718,7 @@ void CMySqlManagerView::OnRefresh()
                {
                   return;
                }
+               mysql.reconnect= 1;
                memset( &item, 0, sizeof(TV_ITEM) );
                item.hItem = hParent;
                item.mask = TVIF_TEXT | TVIF_HANDLE | TVIF_CHILDREN | TVIF_PARAM ;
diff --git a/VC++Files/test1/mysql_thr.c b/VC++Files/test1/mysql_thr.c
index fac5c37a9af..c2743cb8e4c 100644
--- a/VC++Files/test1/mysql_thr.c
+++ b/VC++Files/test1/mysql_thr.c
@@ -167,6 +167,7 @@ pthread_handler_decl(test_thread,arg)
     perror("");
     goto end;
   }
+  mysql.reconnect= 1;
   if (mysql_query(&mysql,"select 1") < 0)
   {
     fprintf(stderr,"Query failed (%s)\n",mysql_error(&mysql));
diff --git a/VC++Files/winmysqladmin/main.cpp b/VC++Files/winmysqladmin/main.cpp
index dfb2004a780..150bc669c74 100644
--- a/VC++Files/winmysqladmin/main.cpp
+++ b/VC++Files/winmysqladmin/main.cpp
@@ -1337,6 +1337,7 @@ void __fastcall TForm1::IsMySQLInit(void)
           }
 
         }
+       MySQL->reconnect= 1;
 
       }
 
@@ -1348,6 +1349,7 @@ void __fastcall TForm1::IsMySQLInit(void)
       MySQL = mysql_init(MySQL);
       if(mysql_real_connect(MySQL,host,user,password , 0, 0, NULL, 0))
       IsConnect = true;
+      MySQL->reconnect= 1;
     }
   }
 }
diff --git a/client/mysql.cc b/client/mysql.cc
index 8e9dd84c8f0..cb3a56972fa 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -2792,6 +2792,8 @@ sql_real_connect(char *host,char *database,char *user,char *password,
   connected=1;
 #ifndef EMBEDDED_LIBRARY
   mysql.reconnect=info_flag ? 1 : 0; // We want to know if this happens
+#else
+  mysql.reconnect= 1;
 #endif
 #ifdef HAVE_READLINE
   build_completion_hash(rehash, 1);
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index 924af3a9977..21e8f6ab3e4 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -425,6 +425,7 @@ static my_bool sql_connect(MYSQL *mysql, uint wait)
     if (mysql_real_connect(mysql,host,user,opt_password,NullS,tcp_port,
 			   unix_port, 0))
     {
+      mysql->reconnect= 1;
       if (info)
       {
 	fputs("\n",stderr);
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 1c10ece92dd..7036deab2fe 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -753,6 +753,7 @@ static MYSQL* safe_connect()
     mysql_options(local_mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol);
   if (!mysql_real_connect(local_mysql, host, user, pass, 0, port, sock, 0))
     die("failed on connect: %s", mysql_error(local_mysql));
+  local_mysql->reconnect= 1;
 
   return local_mysql;
 }
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index c670b84db44..980046fe6e6 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -628,6 +628,7 @@ static int dbConnect(char *host, char *user, char *passwd)
     DBerror(&mysql_connection, "when trying to connect");
     return 1;
   }
+  mysql_connection.reconnect= 1;
   return 0;
 } /* dbConnect */
 
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index fae84be610a..3552f03fb27 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -388,6 +388,7 @@ static MYSQL *db_connect(char *host, char *database, char *user, char *passwd)
     ignore_errors=0;	  /* NO RETURN FROM db_error */
     db_error(&mysql_connection);
   }
+  mysql_connection.reconnect= 0;
   if (verbose)
     fprintf(stdout, "Selecting database %s\n", database);
   if (mysql_select_db(sock, database))
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index ee478058cdc..8171cb95268 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -125,6 +125,7 @@ int main(int argc, char **argv)
     fprintf(stderr,"%s: %s\n",my_progname,mysql_error(&mysql));
     exit(1);
   }
+  mysql.reconnect= 1;
 
   switch (argc)
   {
diff --git a/client/mysqltest.c b/client/mysqltest.c
index bc99d4d38f3..e28737030b8 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -1627,6 +1627,7 @@ int safe_connect(MYSQL* con, const char* host, const char* user,
     }
     sleep(CON_RETRY_SLEEP);
   }
+  con->reconnect= 1; /* TODO: change this to 0 in future versions */
   return con_error;
 }
 
diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c
index c911124e705..9da422e927f 100644
--- a/innobase/btr/btr0btr.c
+++ b/innobase/btr/btr0btr.c
@@ -567,7 +567,8 @@ btr_page_get_father_for_rec(
 	btr_cur_t	cursor;
 	rec_t*		node_ptr;
 	dict_index_t*	index;
-	ulint*		offsets;
+	ulint		offsets_[100] = { 100, };
+	ulint*		offsets	= offsets_;
 
 	ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
 							MTR_MEMO_X_LOCK));
@@ -591,7 +592,8 @@ btr_page_get_father_for_rec(
 				BTR_CONT_MODIFY_TREE, &cursor, 0, mtr);
 
 	node_ptr = btr_cur_get_rec(&cursor);
-	offsets = rec_get_offsets(node_ptr, index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(node_ptr, index, offsets,
+						ULINT_UNDEFINED, &heap);
 
 	if (btr_node_ptr_get_child_page_no(node_ptr, offsets) !=
                                                 buf_frame_get_page_no(page)) {
@@ -609,13 +611,13 @@ 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_reget_offsets(page_rec_get_next(
+		offsets = rec_get_offsets(page_rec_get_next(
 				page_get_infimum_rec(page)), index,
-				offsets, ULINT_UNDEFINED, heap);
+				offsets, ULINT_UNDEFINED, &heap);
 		page_rec_print(page_rec_get_next(page_get_infimum_rec(page)),
 					offsets);
-		offsets = rec_reget_offsets(node_ptr, index, offsets,
-					ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(node_ptr, index, offsets,
+					ULINT_UNDEFINED, &heap);
 		page_rec_print(node_ptr, offsets);
 
 		fputs(
@@ -1231,7 +1233,7 @@ btr_page_get_sure_split_rec(
 	ins_rec = btr_cur_get_rec(cursor);
 	rec = page_get_infimum_rec(page);
 
-	heap = mem_heap_create(100);
+	heap = NULL;
 	offsets = NULL;
 
 	/* We start to include records to the left half, and when the
@@ -1256,8 +1258,8 @@ btr_page_get_sure_split_rec(
 			/* Include tuple */
 			incl_data += insert_size;
 		} else {
-			offsets = rec_reget_offsets(rec, cursor->index,
-					offsets, ULINT_UNDEFINED, heap);
+			offsets = rec_get_offsets(rec, cursor->index,
+					offsets, ULINT_UNDEFINED, &heap);
 			incl_data += rec_offs_size(offsets);
 		}
 
@@ -1280,12 +1282,16 @@ btr_page_get_sure_split_rec(
 					next_rec = page_rec_get_next(rec);
 				}
 				if (next_rec != page_get_supremum_rec(page)) {
-					mem_heap_free(heap);
+					if (heap) {
+						mem_heap_free(heap);
+					}
 					return(next_rec);
 				}
                     	}
 
-			mem_heap_free(heap);
+			if (heap) {
+				mem_heap_free(heap);
+			}
 			return(rec);
 		}
 	}
@@ -1367,8 +1373,8 @@ btr_page_insert_fits(
 		/* In this loop we calculate the amount of reserved
 		space after rec is removed from page. */
 
-		offs = rec_reget_offsets(rec, cursor->index, offs,
-						ULINT_UNDEFINED, heap);
+		offs = rec_get_offsets(rec, cursor->index, offs,
+						ULINT_UNDEFINED, &heap);
 
 		total_data -= rec_offs_size(offs);
 		total_n_recs--;
@@ -1459,7 +1465,7 @@ btr_attach_half_pages(
 	ut_a(page_is_comp(page) == page_is_comp(new_page));
 
 	/* Create a memory heap where the data tuple is stored */
-	heap = mem_heap_create(100);
+	heap = mem_heap_create(1024);
 
 	/* Based on split direction, decide upper and lower pages */
 	if (direction == FSP_DOWN) {
@@ -1478,7 +1484,7 @@ btr_attach_half_pages(
 		btr_node_ptr_set_child_page_no(node_ptr,
 			rec_get_offsets(node_ptr,
 					UT_LIST_GET_FIRST(tree->tree_indexes),
-					ULINT_UNDEFINED, heap),
+					NULL, ULINT_UNDEFINED, &heap),
 			lower_page_no, mtr);
 		mem_heap_empty(heap);
 	} else {
@@ -1656,8 +1662,8 @@ func_start:
 	thus reducing the tree latch contention. */
 
 	if (split_rec) {
-		offsets = rec_reget_offsets(split_rec, cursor->index,
-						offsets, n_uniq, heap);
+		offsets = rec_get_offsets(split_rec, cursor->index, offsets,
+							n_uniq, &heap);
 
 		insert_will_fit = btr_page_insert_fits(cursor,
 					split_rec, offsets, tuple, heap);
@@ -1700,8 +1706,8 @@ func_start:
 		insert_page = right_page;
 
 	} else {
-		offsets = rec_reget_offsets(first_rec, cursor->index,
-						offsets, n_uniq, heap);
+		offsets = rec_get_offsets(first_rec, cursor->index,
+						offsets, n_uniq, &heap);
 
 		if (cmp_dtuple_rec(tuple, first_rec, offsets) >= 0) {
 
@@ -2091,14 +2097,18 @@ btr_compress(
 	if (is_left) {
 		btr_node_ptr_delete(tree, page, mtr);
 	} else {
-		mem_heap_t*	heap = mem_heap_create(100);
+		mem_heap_t*	heap		= NULL;
+		ulint		offsets_[100]	= { 100, };
 		/* Replace the address of the old child node (= page) with the 
 		address of the merge page to the right */
 
 		btr_node_ptr_set_child_page_no(node_ptr,
 				rec_get_offsets(node_ptr, cursor->index,
-				ULINT_UNDEFINED, heap), right_page_no, mtr);
-		mem_heap_free(heap);
+				offsets_, ULINT_UNDEFINED, &heap),
+				right_page_no, mtr);
+		if (heap) {
+			mem_heap_free(heap);
+		}
 		btr_node_ptr_delete(tree, merge_page, mtr);
 	}
 	
@@ -2312,8 +2322,8 @@ btr_print_recursive(
 	page_t*		page,	/* in: index page */
 	ulint		width,	/* in: print this many entries from start
 				and end */
-	mem_heap_t*	heap,	/* in: heap for rec_reget_offsets() */
-	ulint**		offsets,/* in/out: buffer for rec_reget_offsets() */
+	mem_heap_t**	heap,	/* in/out: heap for rec_get_offsets() */
+	ulint**		offsets,/* in/out: buffer for rec_get_offsets() */
 	mtr_t*		mtr)	/* in: mtr */
 {
 	page_cur_t	cursor;
@@ -2350,8 +2360,8 @@ btr_print_recursive(
 
 			node_ptr = page_cur_get_rec(&cursor);
 
-			*offsets = rec_reget_offsets(node_ptr, index,
-					*offsets, ULINT_UNDEFINED, heap);
+			*offsets = rec_get_offsets(node_ptr, index, *offsets,
+					ULINT_UNDEFINED, heap);
 			child = btr_node_ptr_get_child(node_ptr,
 					*offsets, &mtr2);
 			btr_print_recursive(tree, child, width,
@@ -2362,8 +2372,6 @@ btr_print_recursive(
 		page_cur_move_to_next(&cursor);
 		i++;
 	}
-
-	mem_heap_free(heap);
 }
 
 /******************************************************************
@@ -2378,8 +2386,10 @@ btr_print_tree(
 {
 	mtr_t		mtr;
 	page_t*		root;
-	mem_heap_t*	heap	= mem_heap_create(100);
-	ulint*		offsets	= NULL;
+	mem_heap_t*	heap	= NULL;
+	ulint		offsets_[100]
+				= { 100, };
+	ulint*		offsets	= offsets_;
 
 	fputs("--------------------------\n"
 		"INDEX TREE PRINT\n", stderr);
@@ -2388,8 +2398,10 @@ btr_print_tree(
 
 	root = btr_root_get(tree, &mtr);
 
-	btr_print_recursive(tree, root, width, heap, &offsets, &mtr);
-	mem_heap_free(heap);
+	btr_print_recursive(tree, root, width, &heap, &offsets, &mtr);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 
 	mtr_commit(&mtr);
 
@@ -2435,7 +2447,7 @@ btr_check_node_ptr(
 	ut_a(cmp_dtuple_rec(node_ptr_tuple, node_ptr,
 			rec_get_offsets(node_ptr,
 			dict_tree_find_index(tree, node_ptr),
-			ULINT_UNDEFINED, heap)) == 0);
+			NULL, ULINT_UNDEFINED, &heap)) == 0);
 
 	mem_heap_free(heap);
 
@@ -2476,8 +2488,10 @@ btr_index_rec_validate(
 	ulint		n;
 	ulint		i;
 	page_t*		page;
-	mem_heap_t*	heap;
-	ulint*		offsets;
+	mem_heap_t*	heap	= NULL;
+	ulint		offsets_[100]
+				= { 100, };
+	ulint*		offsets	= offsets_;
 
 	page = buf_frame_align(rec);
 	
@@ -2496,22 +2510,17 @@ btr_index_rec_validate(
 		fprintf(stderr, "InnoDB: has %lu fields, should have %lu\n",
 			(ulong) rec_get_n_fields_old(rec), (ulong) n);
 
-		if (!dump_on_error) {
+		if (dump_on_error) {
+			buf_page_print(page);
 
-			return(FALSE);
+			fputs("InnoDB: corrupt record ", stderr);
+			rec_print_old(stderr, rec);
+			putc('\n', stderr);
 		}
-
-		buf_page_print(page);
-
-		fputs("InnoDB: corrupt record ", stderr);
-		rec_print_old(stderr, rec);
-		putc('\n', stderr);
-
 		return(FALSE);
 	}
 
-	heap = mem_heap_create(100);
-	offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
 
 	for (i = 0; i < n; i++) {
 		dtype_t*	type = dict_index_get_nth_type(index, i);
@@ -2536,23 +2545,23 @@ btr_index_rec_validate(
 "InnoDB: field %lu len is %lu, should be %lu\n",
 				(ulong) i, (ulong) len, (ulong) dtype_get_fixed_size(type));
 
-			if (!dump_on_error) {
-				mem_heap_free(heap);
-				return(FALSE);
+			if (dump_on_error) {
+				buf_page_print(page);
+
+				fputs("InnoDB: corrupt record ", stderr);
+				rec_print_new(stderr, rec, offsets);
+				putc('\n', stderr);
+			}
+			if (heap) {
+				mem_heap_free(heap);
 			}
-
-			buf_page_print(page);
-
-			fputs("InnoDB: corrupt record ", stderr);
-			rec_print(stderr, rec, offsets);
-			putc('\n', stderr);
-
-			mem_heap_free(heap);
 			return(FALSE);
 		}
 	}
 
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	return(TRUE);			
 }
 
@@ -2677,8 +2686,8 @@ btr_validate_level(
 		page_cur_move_to_next(&cursor);
 
 		node_ptr = page_cur_get_rec(&cursor);
-		offsets = rec_reget_offsets(node_ptr, index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(node_ptr, index, offsets,
+					ULINT_UNDEFINED, &heap);
 		page = btr_node_ptr_get_child(node_ptr, offsets, &mtr);
 	}
 
@@ -2722,10 +2731,10 @@ loop:
 		rec = page_rec_get_prev(page_get_supremum_rec(page));
 		right_rec = page_rec_get_next(
 					page_get_infimum_rec(right_page));
-		offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
-		offsets2 = rec_reget_offsets(right_rec, index,
-					offsets2, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(rec, index,
+					offsets, ULINT_UNDEFINED, &heap);
+		offsets2 = rec_get_offsets(right_rec, index,
+					offsets2, ULINT_UNDEFINED, &heap);
 		if (cmp_rec_rec(rec, right_rec, offsets, offsets2,
 			dict_index_get_n_fields(index),
 			index) >= 0) {
@@ -2740,16 +2749,12 @@ loop:
 
 			fputs("InnoDB: record ", stderr);
 			rec = page_rec_get_prev(page_get_supremum_rec(page));
-			offsets	= rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
-			rec_print(stderr, rec, offsets);
+			rec_print(stderr, rec, index);
 			putc('\n', stderr);
 			fputs("InnoDB: record ", stderr);
 			rec = page_rec_get_next(page_get_infimum_rec(
 						right_page));
-			offsets	= rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
-			rec_print(stderr, rec, offsets);
+			rec_print(stderr, rec, index);
 			putc('\n', stderr);
 
 	  		ret = FALSE;
@@ -2768,8 +2773,8 @@ loop:
 	
 		node_ptr = btr_page_get_father_node_ptr(tree, page, &mtr);
 		father_page = buf_frame_align(node_ptr);
-		offsets	= rec_reget_offsets(node_ptr, index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets	= rec_get_offsets(node_ptr, index,
+					offsets, ULINT_UNDEFINED, &heap);
 
 		if (btr_node_ptr_get_child_page_no(node_ptr, offsets) !=
 						buf_frame_get_page_no(page)
@@ -2785,7 +2790,7 @@ loop:
 			buf_page_print(page);
 
 			fputs("InnoDB: node ptr ", stderr);
-			rec_print(stderr, node_ptr, offsets);
+			rec_print_new(stderr, node_ptr, offsets);
 
 			fprintf(stderr, "\n"
 				"InnoDB: node ptr child page n:o %lu\n",
@@ -2796,9 +2801,7 @@ loop:
 			rec = btr_page_get_father_for_rec(tree, page,
 				page_rec_get_prev(page_get_supremum_rec(page)),
 				&mtr);
-			offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
-			rec_print(stderr, rec, offsets);
+			rec_print(stderr, rec, index);
 			putc('\n', stderr);
 		   	ret = FALSE;
 
@@ -2806,8 +2809,8 @@ loop:
 		}
 
 		if (btr_page_get_level(page, &mtr) > 0) {
-			offsets	= rec_reget_offsets(node_ptr, index,
-					offsets, ULINT_UNDEFINED, heap);
+			offsets	= rec_get_offsets(node_ptr, index,
+					offsets, ULINT_UNDEFINED, &heap);
 		
 			node_ptr_tuple = dict_tree_build_node_ptr(
 					tree,
@@ -2829,11 +2832,9 @@ loop:
 				fputs("InnoDB: Error: node ptrs differ"
 					" on levels > 0\n"
 					"InnoDB: node ptr ", stderr);
-				rec_print(stderr, node_ptr, offsets);
+				rec_print_new(stderr, node_ptr, offsets);
 				fputs("InnoDB: first rec ", stderr);
-				offsets = rec_reget_offsets(first_rec, index,
-					offsets, ULINT_UNDEFINED, heap);
-				rec_print(stderr, first_rec, offsets);
+				rec_print(stderr, first_rec, index);
 				putc('\n', stderr);
 		   		ret = FALSE;
 
diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c
index f5e146172ed..a3083e0e545 100644
--- a/innobase/btr/btr0cur.c
+++ b/innobase/btr/btr0cur.c
@@ -274,8 +274,9 @@ btr_cur_search_to_nth_level(
 #ifdef BTR_CUR_ADAPT
 	btr_search_t*	info;
 #endif
-	mem_heap_t*	heap;
-	ulint*		offsets;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 	/* Currently, PAGE_CUR_LE is the only search mode used for searches
 	ending to upper levels */
 
@@ -395,8 +396,6 @@ btr_cur_search_to_nth_level(
 		break;
 	}
 
-	heap = mem_heap_create(100);
-	offsets = NULL;
 	/* Loop and search until we arrive at the desired level */
 
 	for (;;) {
@@ -431,7 +430,9 @@ retry_page_get:
 							cursor->thr)) {
 				/* Insertion to the insert buffer succeeded */
 				cursor->flag = BTR_CUR_INSERT_TO_IBUF;
-				mem_heap_free(heap);
+				if (heap) {
+					mem_heap_free(heap);
+				}
 				return;
 			}
 
@@ -517,13 +518,15 @@ retry_page_get:
 		guess = NULL;
 
 		node_ptr = page_cur_get_rec(page_cursor);
-		offsets = rec_reget_offsets(node_ptr, cursor->index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(node_ptr, cursor->index, offsets,
+						ULINT_UNDEFINED, &heap);
 		/* Go to the child node */
 		page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
 	}
 
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 
 	if (level == 0) {
 		cursor->low_match = low_match;
@@ -574,8 +577,9 @@ btr_cur_open_at_index_side(
 	rec_t*		node_ptr;
 	ulint		estimate;
 	ulint           savepoint;
-	mem_heap_t*	heap;
-	ulint*		offsets	= NULL;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	estimate = latch_mode & BTR_ESTIMATE;
 	latch_mode = latch_mode & ~BTR_ESTIMATE;
@@ -600,7 +604,6 @@ btr_cur_open_at_index_side(
 	page_no = dict_tree_get_page(tree);
 
 	height = ULINT_UNDEFINED;
-	heap = mem_heap_create(100);
 
 	for (;;) {
 		page = buf_page_get_gen(space, page_no, RW_NO_LATCH, NULL,
@@ -670,13 +673,15 @@ btr_cur_open_at_index_side(
 		height--;
 
 		node_ptr = page_cur_get_rec(page_cursor);
-		offsets = rec_reget_offsets(node_ptr, cursor->index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(node_ptr, cursor->index, offsets,
+						ULINT_UNDEFINED, &heap);
 		/* Go to the child node */
 		page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
 	}
 
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 }
 	
 /**************************************************************************
@@ -697,8 +702,9 @@ btr_cur_open_at_rnd_pos(
 	ulint		space;
 	ulint		height;
 	rec_t*		node_ptr;
-	mem_heap_t*	heap	= mem_heap_create(100);
-	ulint*		offsets	= NULL;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	tree = index->tree;
 	
@@ -747,13 +753,15 @@ btr_cur_open_at_rnd_pos(
 		height--;
 
 		node_ptr = page_cur_get_rec(page_cursor);
-		offsets = rec_reget_offsets(node_ptr, cursor->index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(node_ptr, cursor->index, offsets,
+						ULINT_UNDEFINED, &heap);
 		/* Go to the child node */
 		page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
 	}
 
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 }	
 
 /*==================== B-TREE INSERT =========================*/
@@ -1242,11 +1250,14 @@ btr_cur_upd_lock_and_undo(
 	err = DB_SUCCESS;
 
 	if (!(flags & BTR_NO_LOCKING_FLAG)) {
-		mem_heap_t*	heap = mem_heap_create(100);
+		mem_heap_t*	heap		= NULL;
+		ulint		offsets_[100]	= { 100, };
 		err = lock_clust_rec_modify_check_and_lock(flags, rec, index,
-			rec_get_offsets(rec, index, ULINT_UNDEFINED, heap),
-			thr);
-		mem_heap_free(heap);
+			rec_get_offsets(rec, index, offsets_,
+				ULINT_UNDEFINED, &heap), thr);
+		if (heap) {
+			mem_heap_free(heap);
+		}
 		if (err != DB_SUCCESS) {
 
 			return(err);
@@ -1374,7 +1385,7 @@ btr_cur_parse_update_in_place(
 	/* We do not need to reserve btr_search_latch, as the page is only
 	being recovered, and there cannot be a hash index to it. */
 
-	offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
 
 	if (!(flags & BTR_KEEP_SYS_FLAG)) {
 		row_upd_rec_sys_fields_in_recovery(rec, offsets,
@@ -1413,18 +1424,19 @@ btr_cur_update_in_place(
 	dulint		roll_ptr	= ut_dulint_zero;
 	trx_t*		trx;
 	ibool		was_delete_marked;
-	mem_heap_t*	heap;
-	const ulint*	offsets;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	rec = btr_cur_get_rec(cursor);
 	index = cursor->index;
 	trx = thr_get_trx(thr);
 	heap = mem_heap_create(100);
-	offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
 
 	if (btr_cur_print_record_ops && thr) {
 		btr_cur_trx_report(trx, index, "update ");
-		rec_print(stderr, rec, offsets);
+		rec_print_new(stderr, rec, offsets);
 	}
 
 	/* Do lock checking and undo logging */
@@ -1432,7 +1444,9 @@ btr_cur_update_in_place(
 							thr, &roll_ptr);
 	if (err != DB_SUCCESS) {
 
-		mem_heap_free(heap);
+		if (heap) {
+			mem_heap_free(heap);
+		}
 		return(err);
 	}
 
@@ -1477,7 +1491,9 @@ btr_cur_update_in_place(
 		btr_cur_unmark_extern_fields(rec, mtr, offsets);
 	}
 
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	return(DB_SUCCESS);
 }
 
@@ -1526,11 +1542,11 @@ btr_cur_optimistic_update(
 	index = cursor->index;
 	
 	heap = mem_heap_create(1024);
-	offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
 
 	if (btr_cur_print_record_ops && thr) {
 		btr_cur_trx_report(thr_get_trx(thr), index, "update ");
-		rec_print(stderr, rec, offsets);
+		rec_print_new(stderr, rec, offsets);
 	}
 
 	ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
@@ -1646,8 +1662,8 @@ btr_cur_optimistic_update(
 		/* The new inserted record owns its possible externally
 		stored fields */
 
-		offsets = rec_reget_offsets(rec, index,
-				offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 		btr_cur_unmark_extern_fields(rec, mtr, offsets);
 	}
 
@@ -1801,7 +1817,7 @@ btr_cur_pessimistic_update(
 	}
 	
 	heap = mem_heap_create(1024);
-	offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
 
 	trx = thr_get_trx(thr);
 	
@@ -1836,8 +1852,8 @@ 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));
-	offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+	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) >=
@@ -1877,8 +1893,8 @@ btr_cur_pessimistic_update(
 	ut_a(rec || optim_err != DB_UNDERFLOW);
 
 	if (rec) {
-		offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(rec, index, offsets,
+					ULINT_UNDEFINED, &heap);
 
 		lock_rec_restore_from_page_infimum(rec, page);
 		rec_set_field_extern_bits(rec, index,
@@ -1918,8 +1934,7 @@ btr_cur_pessimistic_update(
 	ut_a(dummy_big_rec == NULL);
 
 	rec_set_field_extern_bits(rec, index, ext_vect, n_ext_vect, mtr);
-	offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
 
 	if (!rec_get_deleted_flag(rec, rec_offs_comp(offsets))) {
 		/* The new inserted record owns its possible externally
@@ -2048,12 +2063,15 @@ btr_cur_parse_del_mark_set_clust_rec(
 		rec = page + offset;
 	
 		if (!(flags & BTR_KEEP_SYS_FLAG)) {
-			mem_heap_t*	heap = mem_heap_create(100);
+			mem_heap_t*	heap		= NULL;
+			ulint		offsets_[100]	= { 100, };
 			row_upd_rec_sys_fields_in_recovery(rec,
-					rec_get_offsets(rec, index,
-					ULINT_UNDEFINED, heap),
+					rec_get_offsets(rec, index, offsets_,
+					ULINT_UNDEFINED, &heap),
 					pos, trx_id, roll_ptr);
-			mem_heap_free(heap);
+			if (heap) {
+				mem_heap_free(heap);
+			}
 		}
 
 		/* We do not need to reserve btr_search_latch, as the page
@@ -2089,17 +2107,17 @@ btr_cur_del_mark_set_clust_rec(
 	ulint		err;
 	rec_t*		rec;
 	trx_t*		trx;
-	mem_heap_t*	heap;
-	const ulint*	offsets;
-	
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
+
 	rec = btr_cur_get_rec(cursor);
 	index = cursor->index;
-	heap = mem_heap_create(100);
-	offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
 
 	if (btr_cur_print_record_ops && thr) {
 		btr_cur_trx_report(thr_get_trx(thr), index, "del mark ");
-		rec_print(stderr, rec, offsets);
+		rec_print_new(stderr, rec, offsets);
 	}
 
 	ut_ad(index->type & DICT_CLUSTERED);
@@ -2110,7 +2128,9 @@ btr_cur_del_mark_set_clust_rec(
 
 	if (err != DB_SUCCESS) {
 
-		mem_heap_free(heap);
+		if (heap) {
+			mem_heap_free(heap);
+		}
 		return(err);
 	}
 
@@ -2119,7 +2139,9 @@ btr_cur_del_mark_set_clust_rec(
 						&roll_ptr);
 	if (err != DB_SUCCESS) {
 
-		mem_heap_free(heap);
+		if (heap) {
+			mem_heap_free(heap);
+		}
 		return(err);
 	}
 
@@ -2143,7 +2165,9 @@ btr_cur_del_mark_set_clust_rec(
 
 	btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx,
 							roll_ptr, mtr);
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	return(DB_SUCCESS);
 }
 
@@ -2246,12 +2270,9 @@ btr_cur_del_mark_set_sec_rec(
 	rec = btr_cur_get_rec(cursor);
 
 	if (btr_cur_print_record_ops && thr) {
-		mem_heap_t*	heap = mem_heap_create(100);
 		btr_cur_trx_report(thr_get_trx(thr), cursor->index,
 				"del mark ");
-		rec_print(stderr, rec, rec_get_offsets(rec, cursor->index,
-						ULINT_UNDEFINED, heap));
-		mem_heap_free(heap);
+		rec_print(stderr, rec, cursor->index);
 	}
 
 	err = lock_sec_rec_modify_check_and_lock(flags, rec, cursor->index,
@@ -2375,9 +2396,10 @@ btr_cur_optimistic_delete(
 {
 	page_t*		page;
 	ulint		max_ins_size;
-	mem_heap_t*	heap;
 	rec_t*		rec;
-	const ulint*	offsets;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	ut_ad(mtr_memo_contains(mtr, buf_block_align(btr_cur_get_page(cursor)),
 							MTR_MEMO_PAGE_X_FIX));
@@ -2387,9 +2409,9 @@ btr_cur_optimistic_delete(
 	
 	ut_ad(btr_page_get_level(page, mtr) == 0);
 
-	heap = mem_heap_create(100);
 	rec = btr_cur_get_rec(cursor);
-	offsets = rec_get_offsets(rec, cursor->index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, cursor->index, offsets,
+					ULINT_UNDEFINED, &heap);
 
 	if (!rec_offs_any_extern(offsets)
 			&& btr_cur_can_delete_without_compress(
@@ -2406,11 +2428,15 @@ btr_cur_optimistic_delete(
 
 		ibuf_update_free_bits_low(cursor->index, page, max_ins_size,
 									mtr);
-		mem_heap_free(heap);
+		if (heap) {
+			mem_heap_free(heap);
+		}
 		return(TRUE);
 	}
 
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	return(FALSE);
 }
 
@@ -2487,8 +2513,9 @@ btr_cur_pessimistic_delete(
 			: !rec_get_1byte_offs_flag(rec)) {
 		btr_rec_free_externally_stored_fields(cursor->index,
 			rec, rec_get_offsets(rec, cursor->index,
-					ULINT_UNDEFINED, heap),
+					NULL, ULINT_UNDEFINED, &heap),
 			in_rollback, mtr);
+		mem_heap_empty(heap);
 	}
 
 	if ((page_get_n_recs(page) < 2)
@@ -2772,13 +2799,14 @@ btr_estimate_number_of_different_key_vals(
 	ulint		j;
 	ulint		add_on;
 	mtr_t		mtr;
-	mem_heap_t*	heap;
-	ulint*		offsets1 = 0;
-	ulint*		offsets2 = 0;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets1_[100]	= { 100, };
+	ulint		offsets2_[100]	= { 100, };
+	ulint*		offsets1	= offsets1_;
+	ulint*		offsets2	= offsets2_;
 
 	n_cols = dict_index_get_n_unique(index);
 
-	heap = mem_heap_create(100);
 	n_diff = mem_alloc((n_cols + 1) * sizeof(ib_longlong));
 
 	for (j = 0; j <= n_cols; j++) {
@@ -2813,10 +2841,10 @@ btr_estimate_number_of_different_key_vals(
 			rec_t*	next_rec = page_rec_get_next(rec);
 			matched_fields = 0;
 			matched_bytes = 0;
-			offsets1 = rec_reget_offsets(rec, index,
-					offsets1, ULINT_UNDEFINED, heap);
-			offsets2 = rec_reget_offsets(next_rec, index,
-						offsets2, n_cols, heap);
+			offsets1 = rec_get_offsets(rec, index, offsets1,
+						ULINT_UNDEFINED, &heap);
+			offsets2 = rec_get_offsets(next_rec, index, offsets2,
+						n_cols, &heap);
 
 			cmp_rec_rec_with_match(rec, next_rec,
 						offsets1, offsets2,
@@ -2856,8 +2884,8 @@ btr_estimate_number_of_different_key_vals(
 			}
 		}
 
-		offsets1 = rec_reget_offsets(rec, index,
-					offsets1, ULINT_UNDEFINED, heap);
+		offsets1 = rec_get_offsets(rec, index, offsets1,
+						ULINT_UNDEFINED, &heap);
 		total_external_size +=
 				btr_rec_get_externally_stored_len(rec,
 								offsets1);
@@ -2901,7 +2929,9 @@ btr_estimate_number_of_different_key_vals(
 	}
 		
 	mem_free(n_diff);
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 }
 
 /*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/
diff --git a/innobase/btr/btr0pcur.c b/innobase/btr/btr0pcur.c
index 7df8e53cd07..ad7613e0655 100644
--- a/innobase/btr/btr0pcur.c
+++ b/innobase/btr/btr0pcur.c
@@ -262,9 +262,10 @@ btr_pcur_restore_position(
 
 				heap = mem_heap_create(256);
 				offsets1 = rec_get_offsets(cursor->old_rec,
-						index, ULINT_UNDEFINED, heap);
-				offsets2 = rec_get_offsets(rec,
-						index, ULINT_UNDEFINED, heap);
+						index, NULL,
+						cursor->old_n_fields, &heap);
+				offsets2 = rec_get_offsets(rec, index, NULL,
+						cursor->old_n_fields, &heap);
 
 				ut_ad(cmp_rec_rec(cursor->old_rec,
 					rec, offsets1, offsets2,
@@ -310,7 +311,7 @@ btr_pcur_restore_position(
 	    && 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor),
 			rec_get_offsets(btr_pcur_get_rec(cursor),
 				btr_pcur_get_btr_cur(cursor)->index,
-				ULINT_UNDEFINED, heap))) {
+				NULL, ULINT_UNDEFINED, &heap))) {
 
 		/* We have to store the NEW value for the modify clock, since
 		the cursor can now be on a different page! But we can retain
diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c
index c18fa9a923d..dc712f650e7 100644
--- a/innobase/btr/btr0sea.c
+++ b/innobase/btr/btr0sea.c
@@ -419,7 +419,9 @@ btr_search_update_hash_ref(
 	    && (block->curr_n_fields == info->n_fields)
 	    && (block->curr_n_bytes == info->n_bytes)
 	    && (block->curr_side == info->side)) {
-		mem_heap_t*	heap;
+		mem_heap_t*	heap		= NULL;
+		ulint		offsets_[100]	= { 100, };
+
 	    	rec = btr_cur_get_rec(cursor);
 
 	    	if (!page_rec_is_user_rec(rec)) {
@@ -428,11 +430,13 @@ btr_search_update_hash_ref(
 	    	}
 	    
 		tree_id = ((cursor->index)->tree)->id;
-		heap = mem_heap_create(100);
 		fold = rec_fold(rec, rec_get_offsets(rec, cursor->index,
-				ULINT_UNDEFINED, heap), block->curr_n_fields,
+				offsets_, ULINT_UNDEFINED, &heap),
+				block->curr_n_fields,
 				block->curr_n_bytes, tree_id);
-		mem_heap_free(heap);
+		if (heap) {
+			mem_heap_free(heap);
+		}
 #ifdef UNIV_SYNC_DEBUG
 		ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
 #endif /* UNIV_SYNC_DEBUG */
@@ -547,8 +551,10 @@ btr_search_check_guess(
 	ulint		match;
 	ulint		bytes;
 	int		cmp;
-	mem_heap_t*	heap	= mem_heap_create(100);
-	ulint*		offsets	= NULL;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
+	ibool		success		= FALSE;
 
 	n_unique = dict_index_get_n_unique_in_tree(cursor->index);
 	
@@ -560,47 +566,43 @@ btr_search_check_guess(
 	match = 0;
 	bytes = 0;
 
-	offsets = rec_get_offsets(rec, cursor->index, n_unique, heap);
+	offsets = rec_get_offsets(rec, cursor->index, offsets,
+						n_unique, &heap);
 	cmp = page_cmp_dtuple_rec_with_match(tuple, rec,
 						offsets, &match, &bytes);
 
 	if (mode == PAGE_CUR_GE) {
 		if (cmp == 1) {
-			mem_heap_free(heap);
-			return(FALSE);
+			goto exit_func;
 		}
 
 		cursor->up_match = match;
 
 		if (match >= n_unique) {
-			mem_heap_free(heap);
-			return(TRUE);
+			success = TRUE;
+			goto exit_func;
 		}	
 	} else if (mode == PAGE_CUR_LE) {
 		if (cmp == -1) {
-			mem_heap_free(heap);
-			return(FALSE);
+			goto exit_func;
 		}
 
 		cursor->low_match = match;
 
 	} else if (mode == PAGE_CUR_G) {
 		if (cmp != -1) {
-			mem_heap_free(heap);
-			return(FALSE);
+			goto exit_func;
 		}
 	} else if (mode == PAGE_CUR_L) {
 		if (cmp != 1) {
-			mem_heap_free(heap);
-			return(FALSE);
+			goto exit_func;
 		}
 	}
 
 	if (can_only_compare_to_cursor_rec) {
 	        /* Since we could not determine if our guess is right just by
 	        looking at the record under the cursor, return FALSE */
-		mem_heap_free(heap);
-	        return(FALSE);
+		goto exit_func;
 	}
 
 	match = 0;
@@ -613,28 +615,21 @@ btr_search_check_guess(
 		prev_rec = page_rec_get_prev(rec);
 
 		if (prev_rec == page_get_infimum_rec(page)) {
-			mem_heap_free(heap);
-	    		return(btr_page_get_prev(page, mtr) == FIL_NULL);
+			success = btr_page_get_prev(page, mtr) == FIL_NULL;
+			goto exit_func;
 		}
 
-		offsets = rec_reget_offsets(prev_rec, cursor->index,
-						offsets, n_unique, heap);
+		offsets = rec_get_offsets(prev_rec, cursor->index, offsets,
+						n_unique, &heap);
 		cmp = page_cmp_dtuple_rec_with_match(tuple, prev_rec,
 					offsets, &match, &bytes);
-		mem_heap_free(heap);
 		if (mode == PAGE_CUR_GE) {
-			if (cmp != 1) {
-
-				return(FALSE);
-			}
+			success = cmp == 1;
 		} else {
-			if (cmp == -1) {
-
-				return(FALSE);
-			}
+			success = cmp != -1;
 		}
 
-		return(TRUE);
+		goto exit_func;
 	}
 		
 	ut_ad(rec != page_get_supremum_rec(page));
@@ -642,39 +637,30 @@ btr_search_check_guess(
 	next_rec = page_rec_get_next(rec);
 
 	if (next_rec == page_get_supremum_rec(page)) {
-		mem_heap_free(heap);
-
     		if (btr_page_get_next(page, mtr) == FIL_NULL) {
 
 			cursor->up_match = 0;
-
-			return(TRUE);
+			success = TRUE;
 		}
 
-		return(FALSE);
+		goto exit_func;
 	}
 
-	offsets = rec_reget_offsets(next_rec, cursor->index,
-						offsets, n_unique, heap);
+	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);
-	mem_heap_free(heap);
-
 	if (mode == PAGE_CUR_LE) {
-		if (cmp != -1) {
-
-			return(FALSE);
-		}
-
+		success = cmp == -1;
 		cursor->up_match = match;
 	} else {
-		if (cmp == 1) {
-
-			return(FALSE);
-		}
+		success = cmp != 1;
 	}
-
-	return(TRUE);
+exit_func:
+	if (heap) {
+		mem_heap_free(heap);
+	}
+	return(success);
 }
 
 /**********************************************************************
@@ -997,14 +983,14 @@ btr_search_drop_page_hash_index(
 	
 	prev_fold = 0;
 
-	heap = mem_heap_create(100);
+	heap = NULL;
 	offsets = NULL;
 
 	while (rec != sup) {
 		/* FIXME: in a mixed tree, not all records may have enough
 		ordering fields: */
-		offsets = rec_reget_offsets(rec, block->index,
-				offsets, n_fields + (n_bytes > 0), heap);
+		offsets = rec_get_offsets(rec, block->index,
+				offsets, n_fields + (n_bytes > 0), &heap);
 		fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
 
 		if (fold == prev_fold && prev_fold != 0) {
@@ -1022,7 +1008,9 @@ next_rec:
 		prev_fold = fold;
 	}
 
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 
 	rw_lock_x_lock(&btr_search_latch);
 
@@ -1109,8 +1097,9 @@ btr_search_build_page_hash_index(
 	ulint*		folds;
 	rec_t**		recs;
 	ulint		i;
-	mem_heap_t*	heap;
-	ulint*		offsets;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	ut_ad(index);
 
@@ -1161,7 +1150,6 @@ btr_search_build_page_hash_index(
 
 	folds = mem_alloc(n_recs * sizeof(ulint));
 	recs = mem_alloc(n_recs * sizeof(rec_t*));
-	heap = mem_heap_create(100);
 
 	n_cached = 0;
 
@@ -1172,7 +1160,8 @@ btr_search_build_page_hash_index(
 	rec = page_get_infimum_rec(page);
 	rec = page_rec_get_next(rec);
 
-	offsets = rec_get_offsets(rec, index, n_fields + (n_bytes > 0), heap);
+	offsets = rec_get_offsets(rec, index, offsets,
+					n_fields + (n_bytes > 0), &heap);
 
 	if (rec != sup) {
 		ut_a(n_fields <= rec_offs_n_fields(offsets));
@@ -1208,8 +1197,8 @@ btr_search_build_page_hash_index(
 		 	break;
 		}
 
-		offsets = rec_reget_offsets(next_rec, index,
-				offsets, n_fields + (n_bytes > 0), heap);
+		offsets = rec_get_offsets(next_rec, index, offsets,
+					n_fields + (n_bytes > 0), &heap);
 		next_fold = rec_fold(next_rec, offsets, n_fields,
 						n_bytes, tree_id);
 
@@ -1260,7 +1249,9 @@ exit_func:
 
 	mem_free(folds);
 	mem_free(recs);
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 }
 
 /************************************************************************
@@ -1350,7 +1341,8 @@ btr_search_update_hash_on_delete(
 	ulint		fold;
 	dulint		tree_id;
 	ibool		found;
-	mem_heap_t*	heap;
+	ulint		offsets_[100]	= { 100, };
+	mem_heap_t*	heap		= NULL;
 
 	rec = btr_cur_get_rec(cursor);
 
@@ -1371,11 +1363,12 @@ btr_search_update_hash_on_delete(
 	table = btr_search_sys->hash_index;
 
 	tree_id = cursor->index->tree->id;
-	heap = mem_heap_create(100);
-	fold = rec_fold(rec, rec_get_offsets(rec, cursor->index,
-				ULINT_UNDEFINED, heap), block->curr_n_fields,
+	fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, offsets_,
+				ULINT_UNDEFINED, &heap), block->curr_n_fields,
 				block->curr_n_bytes, tree_id);
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	rw_lock_x_lock(&btr_search_latch);
 
 	found = ha_search_and_delete_if_found(table, fold, rec);
@@ -1457,9 +1450,10 @@ btr_search_update_hash_on_insert(
 	ulint		n_fields;
 	ulint		n_bytes;
 	ulint		side;
-	ibool		locked	= FALSE;
-	mem_heap_t*	heap;
-	ulint*		offsets;
+	ibool		locked		= FALSE;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	table = btr_search_sys->hash_index;
 
@@ -1490,21 +1484,20 @@ btr_search_update_hash_on_insert(
 	next_rec = page_rec_get_next(ins_rec);
 
 	page = buf_frame_align(rec);
-	heap = mem_heap_create(100);
-	offsets = rec_get_offsets(ins_rec, cursor->index,
-					ULINT_UNDEFINED, heap);
+	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)) {
-		offsets = rec_reget_offsets(next_rec, cursor->index,
-				offsets, n_fields + (n_bytes > 0), heap);
+		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)) {
-		offsets = rec_reget_offsets(rec, cursor->index,
-				offsets, n_fields + (n_bytes > 0), heap);
+		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);
 	} else {
 		if (side == BTR_SEARCH_LEFT_SIDE) {
@@ -1575,7 +1568,9 @@ check_next_rec:
 	}	
 		
 function_exit:
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	if (locked) {
 		rw_lock_x_unlock(&btr_search_latch);
 	}
@@ -1595,8 +1590,9 @@ btr_search_validate(void)
 	ulint		n_page_dumps	= 0;
 	ibool		ok		= TRUE;
 	ulint		i;
-	mem_heap_t*	heap		= mem_heap_create(100);
-	ulint*		offsets		= NULL;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 	
 	rw_lock_x_lock(&btr_search_latch);
 
@@ -1606,10 +1602,10 @@ btr_search_validate(void)
 		while (node != NULL) {
 			block = buf_block_align(node->data);
 			page = buf_frame_align(node->data);
-			offsets = rec_reget_offsets((rec_t*) node->data,
+			offsets = rec_get_offsets((rec_t*) node->data,
 					block->index, offsets,
 					block->curr_n_fields
-					+ (block->curr_n_bytes > 0), heap);
+					+ (block->curr_n_bytes > 0), &heap);
 
 			if (!block->is_hashed
 			    || node->fold != rec_fold((rec_t*)(node->data),
@@ -1635,7 +1631,8 @@ btr_search_validate(void)
 					  		  btr_page_get_index_id(page)));
 
 				fputs("InnoDB: Record ", stderr);
-				rec_print(stderr, (rec_t*)node->data, offsets);
+				rec_print_new(stderr, (rec_t*)node->data,
+						offsets);
 				fprintf(stderr, "\nInnoDB: on that page."
 "Page mem address %p, is hashed %lu, n fields %lu, n bytes %lu\n"
 "side %lu\n",
@@ -1659,7 +1656,9 @@ btr_search_validate(void)
 	}
 
 	rw_lock_x_unlock(&btr_search_latch);
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 
 	return(ok);
 }
diff --git a/innobase/include/rem0rec.h b/innobase/include/rem0rec.h
index d450df82311..ab89b912523 100644
--- a/innobase/include/rem0rec.h
+++ b/innobase/include/rem0rec.h
@@ -67,6 +67,16 @@ rec_get_n_fields_old(
 			/* out: number of data fields */
 	rec_t*	rec);	/* in: physical record */
 /**********************************************************
+The following function is used to get the number of fields
+in a record. */
+UNIV_INLINE
+ulint
+rec_get_n_fields(
+/*=============*/
+				/* out: number of data fields */
+	rec_t*		rec,	/* in: physical record */
+	dict_index_t*	index);	/* in: record descriptor */
+/**********************************************************
 The following function is used to get the number of records
 owned by the previous directory record. */
 UNIV_INLINE
@@ -188,45 +198,28 @@ rec_get_1byte_offs_flag(
 	rec_t*	rec);	/* in: physical record */
 /**********************************************************
 The following function determines the offsets to each field
-in the record.  The offsets are returned in an array of
-ulint, with [0] being the number of fields (n), [1] being the
-extra size (if REC_OFFS_COMPACT is set, the record is in the new
-format), and [2]..[n+1] being the offsets past the end of
-fields 0..n, or to the beginning of fields 1..n+1.  When the
-high-order bit of the offset at [n+1] is set (REC_OFFS_SQL_NULL),
-the field n is NULL.  When the second high-order bit of the offset
-at [n+1] is set (REC_OFFS_EXTERNAL), the field n is being stored
-externally. */
+in the record.  It can reuse a previously allocated array. */
 
 ulint*
-rec_get_offsets(
-/*============*/
-				/* out: the offsets */
-	rec_t*		rec,	/* in: physical record */
-	dict_index_t*	index,	/* in: record descriptor */
-	ulint		n_fields,/* in: maximum number of initialized fields
-				(ULINT_UNDEFINED if all fields) */
-	mem_heap_t*	heap);	/* in: memory heap */
-/**********************************************************
-The following function determines the offsets to each field
-in the record.  It differs from rec_get_offsets() by trying to
-reuse a previously returned array. */
-
-ulint*
-rec_reget_offsets(
-/*==============*/
+rec_get_offsets_func(
+/*=================*/
 				/* out: the new offsets */
 	rec_t*		rec,	/* in: physical record */
 	dict_index_t*	index,	/* in: record descriptor */
-	ulint*		offsets,/* in: array of offsets
-				from rec_get_offsets()
-				or rec_reget_offsets(), or NULL */
+	ulint*		offsets,/* in: array consisting of offsets[0]
+				allocated elements, or an array from
+				rec_get_offsets(), or NULL */
 	ulint		n_fields,/* in: maximum number of initialized fields
 				(ULINT_UNDEFINED if all fields) */
-	mem_heap_t*	heap);	/* in: memory heap */
+	mem_heap_t**	heap,	/* in/out: memory heap */
+	const char*	file,	/* in: file name where called */
+	ulint		line);	/* in: line number where called */
+
+#define rec_get_offsets(rec,index,offsets,n,heap)	\
+	rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__)
 
 /****************************************************************
-Validates offsets returned by rec_get_offsets() or rec_reget_offsets(). */
+Validates offsets returned by rec_get_offsets(). */
 UNIV_INLINE
 ibool
 rec_offs_validate(
@@ -234,8 +227,7 @@ rec_offs_validate(
 				/* out: TRUE if valid */
 	rec_t*		rec,	/* in: record or NULL */
 	dict_index_t*	index,	/* in: record descriptor or NULL */
-	const ulint*	offsets);/* in: array returned by rec_get_offsets()
-				or rec_reget_offsets() */
+	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
 /****************************************************************
 Updates debug data in offsets, in order to avoid bogus
 rec_offs_validate() failures. */
@@ -243,10 +235,9 @@ UNIV_INLINE
 void
 rec_offs_make_valid(
 /*================*/
-	const rec_t*	rec,	/* in: record */
-	const dict_index_t* index,/* in: record descriptor */
-	ulint*		offsets);/* in: array returned by rec_get_offsets()
-				or rec_reget_offsets() */
+	rec_t*		rec,	/* in: record */
+	dict_index_t*	index,/* in: record descriptor */
+	ulint*		offsets);/* in: array returned by rec_get_offsets() */
 
 /****************************************************************
 The following function is used to get a pointer to the nth
@@ -551,7 +542,15 @@ rec_print_old(
 /*==========*/
 	FILE*		file,	/* in: file where to print */
 	rec_t*		rec);	/* in: physical record */
+/*******************************************************************
+Prints a physical record. */
 
+void
+rec_print_new(
+/*==========*/
+	FILE*		file,	/* in: file where to print */
+	rec_t*		rec,	/* in: physical record */
+	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
 /*******************************************************************
 Prints a physical record. */
 
@@ -560,7 +559,7 @@ rec_print(
 /*======*/
 	FILE*		file,	/* in: file where to print */
 	rec_t*		rec,	/* in: physical record */
-	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
+	dict_index_t*	index);	/* in: record descriptor */
 
 #define REC_INFO_BITS		6	/* This is single byte bit-field */
 
diff --git a/innobase/include/rem0rec.ic b/innobase/include/rem0rec.ic
index 8443b5fa07d..db938aa9fa5 100644
--- a/innobase/include/rem0rec.ic
+++ b/innobase/include/rem0rec.ic
@@ -681,9 +681,11 @@ rec_2_get_field_end_info(
 }
 
 #ifdef UNIV_DEBUG
-# define REC_OFFS_HEADER_SIZE	3
+/* Length of the rec_get_offsets() header */
+# define REC_OFFS_HEADER_SIZE	4
 #else /* UNIV_DEBUG */
-# define REC_OFFS_HEADER_SIZE	1
+/* Length of the rec_get_offsets() header */
+# define REC_OFFS_HEADER_SIZE	2
 #endif /* UNIV_DEBUG */
 
 /* Get the base address of offsets.  The extra_size is stored at
@@ -691,8 +693,40 @@ this position, and following positions hold the end offsets of
 the fields. */
 #define rec_offs_base(offsets) (offsets + REC_OFFS_HEADER_SIZE)
 
+/************************************************************** 
+The following function returns the number of allocated elements
+for an array of offsets. */
+UNIV_INLINE
+ulint
+rec_offs_get_n_alloc(
+/*=================*/
+				/* out: number of elements */
+	const ulint*	offsets)/* in: array for rec_get_offsets() */
+{
+	ulint	n_alloc;
+	ut_ad(offsets);
+	n_alloc = offsets[0];
+	ut_ad(n_alloc > 0);
+	return(n_alloc);
+}
+
+/************************************************************** 
+The following function sets the number of allocated elements
+for an array of offsets. */
+UNIV_INLINE
+void
+rec_offs_set_n_alloc(
+/*=================*/
+	ulint*	offsets,	/* in: array for rec_get_offsets() */
+	ulint	n_alloc)	/* in: number of elements */
+{
+	ut_ad(offsets);
+	ut_ad(n_alloc > 0);
+	offsets[0] = n_alloc;
+}
+
 /****************************************************************
-Validates offsets returned by rec_get_offsets() or rec_reget_offsets(). */
+Validates offsets returned by rec_get_offsets(). */
 UNIV_INLINE
 ibool
 rec_offs_validate(
@@ -705,16 +739,16 @@ rec_offs_validate(
 	ulint	i	= rec_offs_n_fields(offsets);
 	ulint	last	= ULINT_MAX;
 	ibool	comp	= (*rec_offs_base(offsets) & REC_OFFS_COMPACT) != 0;
-	ut_a(offsets);
+
 	if (rec) {
-		ut_ad((ulint) rec == offsets[1]);
+		ut_ad((ulint) rec == offsets[2]);
 		if (!comp) {
 			ut_a(rec_get_n_fields_old(rec) >= i);
 		}
 	}
 	if (index) {
 		ulint max_n_fields;
-		ut_ad((ulint) index == offsets[2]);
+		ut_ad((ulint) index == offsets[3]);
 		max_n_fields = ut_max(
 				dict_index_get_n_fields(index),
 				dict_index_get_n_unique_in_tree(index) + 1);
@@ -734,7 +768,9 @@ rec_offs_validate(
 				ut_error;
 			}
 		}
-		ut_a(i <= max_n_fields);
+		/* index->n_def == 0 for dummy indexes if !comp */
+		ut_a(!comp || index->n_def);
+		ut_a(!index->n_def || i <= max_n_fields);
 	}
 	while (i--) {
 		ulint	curr = rec_offs_base(offsets)[1 + i] & REC_OFFS_MASK;
@@ -750,17 +786,17 @@ UNIV_INLINE
 void
 rec_offs_make_valid(
 /*================*/
-	const rec_t*	rec __attribute__((unused)),
+	rec_t*		rec __attribute__((unused)),
 				/* in: record */
-	const dict_index_t* index __attribute__((unused)),
+	dict_index_t*	index __attribute__((unused)),
 				/* in: record descriptor */
 	ulint*		offsets __attribute__((unused)))
-				/* in: array returned by rec_get_offsets()
-				or rec_reget_offsets() */
+				/* in: array returned by rec_get_offsets() */
 {
 #ifdef UNIV_DEBUG
-	offsets[1] = (ulint) rec;
-	offsets[2] = (ulint) index;
+	ut_ad(rec_get_n_fields(rec, index) >= rec_offs_n_fields(offsets));
+	offsets[2] = (ulint) rec;
+	offsets[3] = (ulint) index;
 #endif /* UNIV_DEBUG */
 }
 
@@ -1146,12 +1182,31 @@ rec_offs_n_fields(
 {
 	ulint	n_fields;
 	ut_ad(offsets);
-	n_fields = offsets[0];
+	n_fields = offsets[1];
 	ut_ad(n_fields > 0);
 	ut_ad(n_fields <= REC_MAX_N_FIELDS);
+	ut_ad(n_fields + REC_OFFS_HEADER_SIZE
+		<= rec_offs_get_n_alloc(offsets));
 	return(n_fields);
 }
 
+/************************************************************** 
+The following function sets the number of fields in offsets. */
+UNIV_INLINE
+void
+rec_offs_set_n_fields(
+/*==================*/
+	ulint*	offsets,	/* in: array returned by rec_get_offsets() */
+	ulint	n_fields)	/* in: number of fields */
+{
+	ut_ad(offsets);
+	ut_ad(n_fields > 0);
+	ut_ad(n_fields <= REC_MAX_N_FIELDS);
+	ut_ad(n_fields + REC_OFFS_HEADER_SIZE
+		<= rec_offs_get_n_alloc(offsets));
+	offsets[1] = n_fields;
+}
+
 /**************************************************************
 The following function returns the data size of a physical
 record, that is the sum of field lengths. SQL null fields
diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c
index 1ff16bce45a..b24fbf7bd01 100644
--- a/innobase/lock/lock0lock.c
+++ b/innobase/lock/lock0lock.c
@@ -424,7 +424,7 @@ lock_check_trx_id_sanity(
 					/* out: TRUE if ok */
 	dulint		trx_id,		/* in: trx id */
 	rec_t*		rec,		/* in: user record */
-	dict_index_t*	index,		/* in: clustered index */
+	dict_index_t*	index,		/* in: index */
 	const ulint*	offsets,	/* in: rec_get_offsets(rec, index) */
 	ibool		has_kernel_mutex)/* in: TRUE if the caller owns the
 					kernel mutex */
@@ -445,7 +445,7 @@ lock_check_trx_id_sanity(
 		fputs("  InnoDB: Error: transaction id associated"
 			" with record\n",
 			stderr);
-		rec_print(stderr, rec, offsets);
+		rec_print_new(stderr, rec, offsets);
 		fputs("InnoDB: in ", stderr);
 		dict_index_name_print(stderr, NULL, index);
 		fprintf(stderr, "\n"
@@ -4093,10 +4093,9 @@ lock_rec_print(
 	ulint		page_no;
 	ulint		i;
 	mtr_t		mtr;
-	mem_heap_t*	heap;
-	ulint*		offsets		= NULL;
-
-	heap = mem_heap_create(100);
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&kernel_mutex));
@@ -4177,9 +4176,9 @@ lock_rec_print(
 			if (page) {
 				rec_t*	rec
 					= page_find_rec_with_heap_no(page, i);
-				offsets = rec_reget_offsets(rec, lock->index,
-					offsets, ULINT_UNDEFINED, heap);
-				rec_print(file, rec, offsets);
+				offsets = rec_get_offsets(rec, lock->index,
+					offsets, ULINT_UNDEFINED, &heap);
+				rec_print_new(file, rec, offsets);
 			}
 
 			putc('\n', file);
@@ -4187,9 +4186,11 @@ lock_rec_print(
 	}
 
 	mtr_commit(&mtr);
-	mem_heap_free(heap);
-}						
-				
+	if (heap) {
+		mem_heap_free(heap);
+	}
+}
+
 /*************************************************************************
 Calculates the number of record lock structs in the record lock hash table. */
 static
@@ -4582,12 +4583,13 @@ lock_rec_validate_page(
 	page_t*	page;
 	lock_t*	lock;
 	rec_t*	rec;
-	ulint	nth_lock	= 0;
-	ulint	nth_bit		= 0;
+	ulint	nth_lock		= 0;
+	ulint	nth_bit			= 0;
 	ulint	i;
 	mtr_t	mtr;
-	mem_heap_t*	heap	= mem_heap_create(100);
-	ulint*	offsets		= NULL;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(!mutex_own(&kernel_mutex));
@@ -4627,8 +4629,8 @@ loop:
 
 			index = lock->index;
 			rec = page_find_rec_with_heap_no(page, i);
-			offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+			offsets = rec_get_offsets(rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 
 			fprintf(stderr,
 				"Validating %lu %lu\n", (ulong) space, (ulong) page_no);
@@ -4655,7 +4657,9 @@ function_exit:
 
 	mtr_commit(&mtr);
 
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	return(TRUE);
 }						
 				
@@ -4831,11 +4835,15 @@ lock_rec_insert_check_and_lock(
 
 #ifdef UNIV_DEBUG
 	{
-		mem_heap_t*	heap	= mem_heap_create(100);
-		const ulint*	offsets	= rec_get_offsets(next_rec, index,
-						ULINT_UNDEFINED, heap);
+		mem_heap_t*	heap		= NULL;
+		ulint		offsets_[100]	= { 100, };
+		const ulint*	offsets		= rec_get_offsets(
+						next_rec, index, offsets_,
+						ULINT_UNDEFINED, &heap);
 		ut_ad(lock_rec_queue_validate(next_rec, index, offsets));
-		mem_heap_free(heap);
+		if (heap) {
+			mem_heap_free(heap);
+		}
 	}
 #endif /* UNIV_DEBUG */
 
@@ -4974,11 +4982,14 @@ lock_sec_rec_modify_check_and_lock(
 
 #ifdef UNIV_DEBUG
 	{
-		mem_heap_t*	heap	= mem_heap_create(100);
-		const ulint*	offsets	= rec_get_offsets(rec, index,
-						ULINT_UNDEFINED, heap);
+		mem_heap_t*	heap		= NULL;
+		ulint		offsets_[100]	= { 100, };
+		const ulint*	offsets		= rec_get_offsets(
+			rec, index, offsets_, ULINT_UNDEFINED, &heap);
 		ut_ad(lock_rec_queue_validate(rec, index, offsets));
-		mem_heap_free(heap);
+		if (heap) {
+			mem_heap_free(heap);
+		}
 	}
 #endif /* UNIV_DEBUG */
 
@@ -5087,7 +5098,6 @@ lock_clust_rec_read_check_and_lock(
 	ut_ad(page_rec_is_user_rec(rec) || page_rec_is_supremum(rec));
 	ut_ad(gap_mode == LOCK_ORDINARY || gap_mode == LOCK_GAP
 					|| gap_mode == LOCK_REC_NOT_GAP);
-	ut_ad(index->type & DICT_CLUSTERED);
 	ut_ad(rec_offs_validate(rec, index, offsets));
 
 	if (flags & BTR_NO_LOCKING_FLAG) {
diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c
index 8def8474d9a..53c3c573b8e 100644
--- a/innobase/page/page0cur.c
+++ b/innobase/page/page0cur.c
@@ -29,6 +29,7 @@ UNIV_INLINE
 ibool
 page_cur_try_search_shortcut(
 /*=========================*/
+				/* out: TRUE on success */
 	page_t*		page,	/* in: index page */
 	dict_index_t*	index,	/* in: record descriptor */
 	dtuple_t*	tuple,	/* in: data tuple */
@@ -56,14 +57,15 @@ page_cur_try_search_shortcut(
 #ifdef UNIV_SEARCH_DEBUG
 	page_cur_t cursor2;
 #endif
-	mem_heap_t*	heap;
-	ulint*		offsets;
+	ibool		success		= FALSE;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 	ut_ad(dtuple_check_typed(tuple));
 
 	rec = page_header_get_ptr(page, PAGE_LAST_INSERT);
-	heap = mem_heap_create(100);
-	offsets = rec_get_offsets(rec, index,
-				dtuple_get_n_fields(tuple), heap);
+	offsets = rec_get_offsets(rec, index, offsets,
+				dtuple_get_n_fields(tuple), &heap);
 
 	ut_ad(rec);
 	ut_ad(page_rec_is_user_rec(rec));
@@ -78,21 +80,17 @@ page_cur_try_search_shortcut(
 	cmp = page_cmp_dtuple_rec_with_match(tuple, rec, offsets, &low_match,
 								&low_bytes);
 	if (cmp == -1) {
-
-		mem_heap_free(heap);
-		return(FALSE);
+		goto exit_func;
 	}
 
 	next_rec = page_rec_get_next(rec);
-	offsets = rec_reget_offsets(next_rec, index, offsets,
-				dtuple_get_n_fields(tuple), heap);
+	offsets = rec_get_offsets(next_rec, index, offsets,
+				dtuple_get_n_fields(tuple), &heap);
 
 	cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets,
 						&up_match, &up_bytes);
 	if (cmp != -1) {
-
-		mem_heap_free(heap);
-		return(FALSE);
+		goto exit_func;
 	}
 
 	cursor->rec = rec;
@@ -127,8 +125,12 @@ page_cur_try_search_shortcut(
 #ifdef UNIV_SEARCH_PERF_STAT
 	page_cur_short_succ++;
 #endif
-	mem_heap_free(heap);
-	return(TRUE);
+	success = TRUE;
+exit_func:
+	if (heap) {
+		mem_heap_free(heap);
+	}
+	return(success);
 }
 
 #endif
@@ -226,8 +228,9 @@ page_cur_search_with_match(
 	ulint	dbg_matched_fields;
 	ulint	dbg_matched_bytes;
 #endif
-	mem_heap_t*	heap;
-	ulint*	offsets	= NULL;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	ut_ad(page && tuple && iup_matched_fields && iup_matched_bytes
 	      && ilow_matched_fields && ilow_matched_bytes && cursor);
@@ -262,8 +265,6 @@ page_cur_search_with_match(
 /*#endif */
 #endif	
 
-	heap = mem_heap_create(100);
-
 	/* The following flag does not work for non-latin1 char sets because
 	cmp_full_field does not tell how many bytes matched */
 	ut_a(mode != PAGE_CUR_LE_OR_EXTENDS); 
@@ -298,8 +299,8 @@ page_cur_search_with_match(
 				low_matched_fields, low_matched_bytes,
 				up_matched_fields, up_matched_bytes);
 
-		offsets = rec_reget_offsets(mid_rec, index, offsets,
-					dtuple_get_n_fields_cmp(tuple), heap);
+		offsets = rec_get_offsets(mid_rec, index, offsets,
+					dtuple_get_n_fields_cmp(tuple), &heap);
 
 		cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets,
 						&cur_matched_fields,
@@ -310,8 +311,8 @@ page_cur_search_with_match(
 			low_matched_bytes = cur_matched_bytes;
 
 		} else if (cmp == -1) {
-			offsets = rec_reget_offsets(mid_rec, index,
-				offsets, dtuple_get_n_fields_cmp(tuple), heap);
+			offsets = rec_get_offsets(mid_rec, index, offsets,
+					dtuple_get_n_fields_cmp(tuple), &heap);
 
 			if (mode == PAGE_CUR_LE_OR_EXTENDS
 			    && page_cur_rec_field_extends(tuple, mid_rec,
@@ -353,8 +354,8 @@ page_cur_search_with_match(
 				low_matched_fields, low_matched_bytes,
 				up_matched_fields, up_matched_bytes);
 
-		offsets = rec_reget_offsets(mid_rec, index,
-				offsets, dtuple_get_n_fields_cmp(tuple), heap);
+		offsets = rec_get_offsets(mid_rec, index, offsets,
+					dtuple_get_n_fields_cmp(tuple), &heap);
 
 		cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets,
 						&cur_matched_fields,
@@ -365,8 +366,8 @@ page_cur_search_with_match(
 			low_matched_bytes = cur_matched_bytes;
 
 		} else if (cmp == -1) {
-			offsets = rec_reget_offsets(mid_rec, index,
-				offsets, dtuple_get_n_fields_cmp(tuple), heap);
+			offsets = rec_get_offsets(mid_rec, index, offsets,
+					dtuple_get_n_fields_cmp(tuple), &heap);
 
 			if (mode == PAGE_CUR_LE_OR_EXTENDS
 			    && page_cur_rec_field_extends(tuple, mid_rec,
@@ -398,8 +399,8 @@ page_cur_search_with_match(
 	dbg_matched_fields = 0;
 	dbg_matched_bytes = 0;
 
-	offsets = rec_reget_offsets(low_rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(low_rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 	dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, low_rec, offsets,
 						&dbg_matched_fields,
 						&dbg_matched_bytes);
@@ -422,8 +423,8 @@ page_cur_search_with_match(
 	dbg_matched_fields = 0;
 	dbg_matched_bytes = 0;
 
-	offsets = rec_reget_offsets(up_rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(up_rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 	dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, up_rec, offsets,
 						&dbg_matched_fields,
 						&dbg_matched_bytes);
@@ -453,7 +454,9 @@ page_cur_search_with_match(
 	*iup_matched_bytes   = up_matched_bytes;
 	*ilow_matched_fields = low_matched_fields;
 	*ilow_matched_bytes  = low_matched_bytes;
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 }
 
 /***************************************************************
@@ -519,22 +522,26 @@ page_cur_insert_rec_write_log(
 	ut_a(rec_size < UNIV_PAGE_SIZE);
 
 	{
-		mem_heap_t*	heap;
+		mem_heap_t*	heap		= NULL;
+		ulint		cur_offs_[100]	= { 100, };
+		ulint		ins_offs_[100]	= { 100, };
+
 		ulint*		cur_offs;
 		ulint*		ins_offs;
 
-		heap = mem_heap_create(100);
-		cur_offs = rec_get_offsets(cursor_rec, index,
-						ULINT_UNDEFINED, heap);
-		ins_offs = rec_get_offsets(insert_rec, index,
-						ULINT_UNDEFINED, heap);
+		cur_offs = rec_get_offsets(cursor_rec, index, cur_offs_,
+						ULINT_UNDEFINED, &heap);
+		ins_offs = rec_get_offsets(insert_rec, index, ins_offs_,
+						ULINT_UNDEFINED, &heap);
 
 		extra_size = rec_offs_extra_size(ins_offs);
 		cur_extra_size = rec_offs_extra_size(cur_offs);
 		ut_ad(rec_size == rec_offs_size(ins_offs));
 		cur_rec_size = rec_offs_size(cur_offs);
 
-		mem_heap_free(heap);
+		if (heap) {
+			mem_heap_free(heap);
+		}
 	}
 
 	ins_ptr = insert_rec - extra_size;
@@ -668,8 +675,9 @@ page_cur_parse_insert_rec(
 	byte*   ptr2 = ptr;
 	ulint	info_bits = 0; /* remove warning */
 	page_cur_t cursor;
-	mem_heap_t* heap;
-	ulint*	offsets;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	if (!is_short) {
 		/* Read the cursor rec offset as a 2-byte ulint */
@@ -756,8 +764,8 @@ page_cur_parse_insert_rec(
 		cursor_rec = page + offset;
 	}
 
-	heap = mem_heap_create(100);
-	offsets = rec_get_offsets(cursor_rec, index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(cursor_rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 
 	if (extra_info_yes == 0) {
 		info_bits = rec_get_info_bits(cursor_rec, index->table->comp);
@@ -816,6 +824,10 @@ page_cur_parse_insert_rec(
 		mem_free(buf);
 	}
 
+	if (heap) {
+		mem_heap_free(heap);
+	}
+
 	return(ptr + end_seg_len);
 }	
 
@@ -850,8 +862,9 @@ page_cur_insert_rec_low(
 					inserted record */
 	rec_t*		owner_rec;
 	ulint		n_owned;
-	mem_heap_t*	heap;
-	ulint*		offsets;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 	ibool		comp		= index->table->comp;
 
 	ut_ad(cursor && mtr);
@@ -865,14 +878,12 @@ page_cur_insert_rec_low(
 
 	ut_ad(cursor->rec != page_get_supremum_rec(page));	
 
-	heap = mem_heap_create(100);
-
 	/* 1. Get the size of the physical record in the page */
 	if (tuple != NULL) {
-		offsets = NULL;
 		rec_size = rec_get_converted_size(index, tuple);
 	} else {
-		offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 		rec_size = rec_offs_size(offsets);
 	}
 
@@ -880,7 +891,9 @@ page_cur_insert_rec_low(
 	insert_buf = page_mem_alloc(page, rec_size, index, &heap_no);
 
 	if (insert_buf == NULL) {
-		mem_heap_free(heap);
+		if (heap) {
+			mem_heap_free(heap);
+		}
 		return(NULL);
 	}
 
@@ -888,13 +901,15 @@ page_cur_insert_rec_low(
 	if (tuple != NULL) {
 		insert_rec = rec_convert_dtuple_to_rec(insert_buf,
 							index, tuple);
+		offsets = rec_get_offsets(insert_rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 	} else {
 		insert_rec = rec_copy(insert_buf, rec, offsets);
+		ut_ad(rec_offs_validate(rec, index, offsets));
+		rec_offs_make_valid(insert_rec, index, offsets);
 	}
 
 	ut_ad(insert_rec);
-	offsets = rec_reget_offsets(insert_rec, index,
-					offsets, ULINT_UNDEFINED, heap);
 	ut_ad(rec_size == rec_offs_size(offsets));
 	
 	/* 4. Insert the record in the linked list of records */
@@ -966,7 +981,9 @@ page_cur_insert_rec_low(
 	page_cur_insert_rec_write_log(insert_rec, rec_size, current_rec,
 				index, mtr);
 	
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	return(insert_rec);
 }
 
@@ -1068,9 +1085,10 @@ page_copy_rec_list_end_to_created_page(
 	ulint	log_mode;
 	byte*	log_ptr;
 	ulint	log_data_len;
-	ibool	comp	= page_is_comp(page);
-	mem_heap_t* heap;
-	ulint*	offsets	= NULL;
+	ibool		comp		= page_is_comp(page);
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 	
 	ut_ad(page_dir_get_n_heap(new_page) == 2);
 	ut_ad(page != new_page);
@@ -1117,8 +1135,8 @@ page_copy_rec_list_end_to_created_page(
 
 	/* should be do ... until, comment by Jani */
 	while (rec != page_get_supremum_rec(page)) {
-		offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(rec, index, offsets,
+					ULINT_UNDEFINED, &heap);
 		insert_rec = rec_copy(heap_top, rec, offsets);
 
 		rec_set_next_offs(prev_rec, comp, insert_rec - new_page);
@@ -1170,7 +1188,9 @@ page_copy_rec_list_end_to_created_page(
 		slot_index--;
 	}
 
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 
 	log_data_len = dyn_array_get_data_size(&(mtr->log)) - log_data_len;
 
diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c
index 38b1e503c8f..67c7bd936d1 100644
--- a/innobase/page/page0page.c
+++ b/innobase/page/page0page.c
@@ -227,10 +227,12 @@ page_mem_alloc(
 	rec = page_header_get_ptr(page, PAGE_FREE);
 
 	if (rec) {
-		mem_heap_t*	heap
-			= mem_heap_create(100);
-		const ulint*	offsets
-			= rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
+		mem_heap_t*	heap		= NULL;
+		ulint		offsets_[100]	= { 100, };
+		ulint*		offsets		= offsets_;
+
+		offsets = rec_get_offsets(rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 
 		if (rec_offs_size(offsets) >= need) {
 			page_header_set_ptr(page, PAGE_FREE,
@@ -245,11 +247,15 @@ page_mem_alloc(
 			*heap_no = rec_get_heap_no(rec, page_is_comp(page));
 
 			block = rec_get_start(rec, offsets);
-			mem_heap_free(heap);
+			if (heap) {
+				mem_heap_free(heap);
+			}
 			return(block);
 		}
 
-		mem_heap_free(heap);
+		if (heap) {
+			mem_heap_free(heap);
+		}
 	}
 
 	/* Could not find space from the free list, try top of heap */
@@ -374,7 +380,8 @@ page_create(
 
 	rec_set_n_owned(infimum_rec, comp, 1);
 	rec_set_heap_no(infimum_rec, comp, 0);
-	offsets = rec_get_offsets(infimum_rec, index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(infimum_rec, index, NULL,
+						ULINT_UNDEFINED, &heap);
 
 	heap_top = rec_get_end(infimum_rec, offsets);
 
@@ -396,8 +403,8 @@ page_create(
 	rec_set_n_owned(supremum_rec, comp, 1);
 	rec_set_heap_no(supremum_rec, comp, 1);
 
-	offsets = rec_reget_offsets(supremum_rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(supremum_rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 	heap_top = rec_get_end(supremum_rec, offsets);
 
 	ut_ad(heap_top ==
@@ -711,8 +718,9 @@ page_delete_rec_list_end(
 	last_rec = page_rec_get_prev(sup);
 
 	if ((size == ULINT_UNDEFINED) || (n_recs == ULINT_UNDEFINED)) {
-		mem_heap_t*	heap	= mem_heap_create(100);
-		ulint*		offsets	= NULL;
+		mem_heap_t*	heap		= NULL;
+		ulint		offsets_[100]	= { 100, };
+		ulint*		offsets		= offsets_;
 		/* Calculate the sum of sizes and the number of records */
 		size = 0;
 		n_recs = 0;
@@ -720,8 +728,8 @@ page_delete_rec_list_end(
 
 		while (rec2 != sup) {
 			ulint	s;
-			offsets = rec_reget_offsets(rec2, index,
-					offsets, ULINT_UNDEFINED, heap);
+			offsets = rec_get_offsets(rec2, index, offsets,
+						ULINT_UNDEFINED, &heap);
 			s = rec_offs_size(offsets);
 			ut_ad(rec2 - page + s - rec_offs_extra_size(offsets)
 				< UNIV_PAGE_SIZE);
@@ -732,7 +740,9 @@ page_delete_rec_list_end(
 			rec2 = page_rec_get_next(rec2);
 		}
 
-		mem_heap_free(heap);
+		if (heap) {
+			mem_heap_free(heap);
+		}
 	}
 
 	ut_ad(size < UNIV_PAGE_SIZE);
@@ -1213,7 +1223,7 @@ page_rec_print(
 	ibool	comp	= page_is_comp(buf_frame_align(rec));
 
 	ut_a(comp == rec_offs_comp(offsets));
-	rec_print(stderr, rec, offsets);
+	rec_print_new(stderr, rec, offsets);
 	fprintf(stderr,
      		"            n_owned: %lu; heap_no: %lu; next rec: %lu\n",
 		(ulong) rec_get_n_owned(rec, comp),
@@ -1276,11 +1286,11 @@ page_print_list(
 	page_cur_t	cur;
 	ulint		count;
 	ulint		n_recs;
-	mem_heap_t*	heap;
-	ulint*		offsets	= NULL;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	ut_a(page_is_comp(page) == index->table->comp);
-	heap = mem_heap_create(100);
 
 	fprintf(stderr,
 		"--------------------------------\n"
@@ -1292,8 +1302,8 @@ page_print_list(
 	page_cur_set_before_first(page, &cur);
 	count = 0;
 	for (;;) {
-		offsets = rec_reget_offsets(cur.rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(cur.rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 		page_rec_print(cur.rec, offsets);
 
 		if (count == pr_n) {
@@ -1314,8 +1324,8 @@ page_print_list(
 		page_cur_move_to_next(&cur);
 
 		if (count + pr_n >= n_recs) {	
-			offsets = rec_reget_offsets(cur.rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+			offsets = rec_get_offsets(cur.rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 			page_rec_print(cur.rec, offsets);
 		}
 		count++;	
@@ -1326,7 +1336,9 @@ page_print_list(
 		"--------------------------------\n",
 		(ulong) (count + 1));
 
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 }	
 
 /*******************************************************************
@@ -1680,7 +1692,7 @@ page_validate(
 		goto func_exit2;
 	}
 
-	heap = mem_heap_create(UNIV_PAGE_SIZE);
+	heap = mem_heap_create(UNIV_PAGE_SIZE + 200);
 	
 	/* The following buffer is used to check that the
 	records in the page record heap do not overlap */
@@ -1720,8 +1732,8 @@ page_validate(
 
 	for (;;) {
 		rec = cur.rec;
-		offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 
 		if (comp && page_rec_is_user_rec(rec)
 				&& rec_get_node_ptr_flag(rec)
@@ -1744,9 +1756,9 @@ page_validate(
 					(ulong) buf_frame_get_page_no(page));
 				dict_index_name_print(stderr, NULL, index);
 				fputs("\nInnoDB: previous record ", stderr);
-				rec_print(stderr, old_rec, old_offsets);
+				rec_print_new(stderr, old_rec, old_offsets);
 				fputs("\nInnoDB: record ", stderr);
-				rec_print(stderr, rec, offsets);
+				rec_print_new(stderr, rec, offsets);
 				putc('\n', stderr);
 				
 				goto func_exit;
@@ -1852,8 +1864,8 @@ page_validate(
 	rec = page_header_get_ptr(page, PAGE_FREE);
 
 	while (rec != NULL) {
-		offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 		if (!page_rec_validate(rec, offsets)) {
 
 			goto func_exit;
diff --git a/innobase/rem/rem0rec.c b/innobase/rem/rem0rec.c
index e4fa213480f..74876ad9402 100644
--- a/innobase/rem/rem0rec.c
+++ b/innobase/rem/rem0rec.c
@@ -284,86 +284,25 @@ rec_init_offsets(
 
 /**********************************************************
 The following function determines the offsets to each field
-in the record.  The offsets are returned in an array of
-ulint, with [0] being the number of fields (n), [1] being the
-extra size (if REC_OFFS_COMPACT is set, the record is in the new
-format), and [2]..[n+1] being the offsets past the end of
-fields 0..n, or to the beginning of fields 1..n+1.  When the
-high-order bit of the offset at [n+1] is set (REC_OFFS_SQL_NULL),
-the field n is NULL.  When the second high-order bit of the offset
-at [n+1] is set (REC_OFFS_EXTERNAL), the field n is being stored
-externally. */
+in the record.  It can reuse a previously returned array. */
 
 ulint*
-rec_get_offsets(
-/*============*/
-				/* out: the offsets */
-	rec_t*		rec,	/* in: physical record */
-	dict_index_t*	index,	/* in: record descriptor */
-	ulint		n_fields,/* in: maximum number of initialized fields
-				(ULINT_UNDEFINED if all fields) */
-	mem_heap_t*	heap)	/* in: memory heap */
-{
-	ulint*	offsets;
-	ulint	n;
-
-	ut_ad(rec);
-	ut_ad(index);
-	ut_ad(heap);
-
-	if (index->table->comp) {
-		switch (rec_get_status(rec)) {
-		case REC_STATUS_ORDINARY:
-			n = dict_index_get_n_fields(index);
-			break;
-		case REC_STATUS_NODE_PTR:
-			n = dict_index_get_n_unique_in_tree(index) + 1;
-			break;
-		case REC_STATUS_INFIMUM:
-		case REC_STATUS_SUPREMUM:
-			/* infimum or supremum record */
-			n = 1;
-			break;
-		default:
-			ut_error;
-			return(NULL);
-		}
-	} else {
-		n = rec_get_n_fields_old(rec);
-	}
-
-	if (n_fields < n) {
-		n = n_fields;
-	}
-
-	offsets = mem_heap_alloc(heap,
-		(n + (1 + REC_OFFS_HEADER_SIZE)) * sizeof(ulint));
-
-	offsets[0] = n;
-
-	rec_init_offsets(rec, index, offsets);
-	return(offsets);
-}
-
-/**********************************************************
-The following function determines the offsets to each field
-in the record.  It differs from rec_get_offsets() by trying to
-reuse a previously returned array. */
-
-ulint*
-rec_reget_offsets(
-/*==============*/
+rec_get_offsets_func(
+/*=================*/
 				/* out: the new offsets */
 	rec_t*		rec,	/* in: physical record */
 	dict_index_t*	index,	/* in: record descriptor */
-	ulint*		offsets,/* in: array of offsets
-				from rec_get_offsets()
-				or rec_reget_offsets(), or NULL */
+	ulint*		offsets,/* in: array consisting of offsets[0]
+				allocated elements, or an array from
+				rec_get_offsets(), or NULL */
 	ulint		n_fields,/* in: maximum number of initialized fields
 				(ULINT_UNDEFINED if all fields) */
-	mem_heap_t*	heap)	/* in: memory heap */
+	mem_heap_t**	heap,	/* in/out: memory heap */
+	const char*	file,	/* in: file name where called */
+	ulint		line)	/* in: line number where called */
 {
 	ulint	n;
+	ulint	size;
 
 	ut_ad(rec);
 	ut_ad(index);
@@ -394,13 +333,18 @@ rec_reget_offsets(
 		n = n_fields;
 	}
 
-	if (!offsets || rec_offs_n_fields(offsets) < n) {
-		offsets = mem_heap_alloc(heap,
-			(n + (1 + REC_OFFS_HEADER_SIZE)) * sizeof(ulint));
+	size = (n + (1 + REC_OFFS_HEADER_SIZE)) * sizeof(ulint);
+
+	if (!offsets || rec_offs_get_n_alloc(offsets) < size) {
+		if (!*heap) {
+			*heap = mem_heap_create_func(size,
+				NULL, MEM_HEAP_DYNAMIC, file, line);
+		}
+		offsets = mem_heap_alloc(*heap, size);
+		rec_offs_set_n_alloc(offsets, size);
 	}
 
-	offsets[0] = n;
-
+	rec_offs_set_n_fields(offsets, n);
 	rec_init_offsets(rec, index, offsets);
 	return(offsets);
 }
@@ -722,14 +666,16 @@ rec_get_size(
 	rec_t*		rec,	/* in: physical record */
 	dict_index_t*	index)	/* in: record descriptor */
 {
-	mem_heap_t*	heap
-			= mem_heap_create(100);
-	ulint*		offsets
-			= rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
-	ulint		size
-			= rec_offs_size(offsets);
+	mem_heap_t*	heap	= NULL;
+	ulint		offsets_[100 + REC_OFFS_HEADER_SIZE]
+				= { 100, };
+	ulint*		offsets	= rec_get_offsets(rec, index, offsets_,
+				ULINT_UNDEFINED, &heap);
+	ulint		size	= rec_offs_size(offsets);
 
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	return(size);
 }
 
@@ -1032,10 +978,15 @@ rec_convert_dtuple_to_rec(
 
 #ifdef UNIV_DEBUG
 	{
-		mem_heap_t*	heap = mem_heap_create(100);
-		ut_ad(rec_validate(rec,
-			rec_get_offsets(rec, index, ULINT_UNDEFINED, heap)));
-		mem_heap_free(heap);
+		mem_heap_t*	heap	= NULL;
+		ulint		offsets_[100 + REC_OFFS_HEADER_SIZE]
+					= { 100, };
+		const ulint*	offsets	= rec_get_offsets(rec, index,
+					offsets_, ULINT_UNDEFINED, &heap);
+		ut_ad(rec_validate(rec, offsets));
+		if (heap) {
+			mem_heap_free(heap);
+		}
 	}
 #endif /* UNIV_DEBUG */
 	return(rec);
@@ -1059,9 +1010,11 @@ rec_copy_prefix_to_dtuple(
 	ulint		len;
 	byte*		buf = NULL;
 	ulint		i;
-	ulint*		offsets;
+	ulint		offsets_[100 + REC_OFFS_HEADER_SIZE]
+				= { 100, };
+	ulint*		offsets	= offsets_;
 
-	offsets = rec_get_offsets(rec, index, n_fields, heap);
+	offsets = rec_get_offsets(rec, index, offsets, n_fields, &heap);
 
 	ut_ad(rec_validate(rec, offsets));
 	ut_ad(dtuple_check_typed(tuple));
@@ -1406,8 +1359,8 @@ rec_print_old(
 Prints a physical record. */
 
 void
-rec_print(
-/*======*/
+rec_print_new(
+/*==========*/
 	FILE*		file,	/* in: file where to print */
 	rec_t*		rec,	/* in: physical record */
 	const ulint*	offsets)/* in: array returned by rec_get_offsets() */
@@ -1416,6 +1369,8 @@ rec_print(
 	ulint		len;
 	ulint		i;
 
+	ut_ad(rec_offs_validate(rec, NULL, offsets));
+
 	if (!rec_offs_comp(offsets)) {
 		rec_print_old(file, rec);
 		return;
@@ -1453,3 +1408,30 @@ rec_print(
 
 	rec_validate(rec, offsets);
 }
+
+/*******************************************************************
+Prints a physical record. */
+
+void
+rec_print(
+/*======*/
+	FILE*		file,	/* in: file where to print */
+	rec_t*		rec,	/* in: physical record */
+	dict_index_t*	index)	/* in: record descriptor */
+{
+	ut_ad(index);
+
+	if (!index->table->comp) {
+		rec_print_old(file, rec);
+		return;
+	} else {
+		mem_heap_t*	heap	= NULL;
+		ulint		offsets_[100 + REC_OFFS_HEADER_SIZE]
+					= { 100, };
+		rec_print_new(file, rec, rec_get_offsets(rec, index, offsets_,
+						ULINT_UNDEFINED, &heap));
+		if (heap) {
+			mem_heap_free(heap);
+		}
+	}
+}
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c
index a87a08fa3fe..969c3341be3 100644
--- a/innobase/row/row0ins.c
+++ b/innobase/row/row0ins.c
@@ -590,16 +590,8 @@ row_ins_foreign_report_err(
 	fputs(", in index ", ef);
 	ut_print_name(ef, trx, foreign->foreign_index->name);
 	if (rec) {
-		mem_heap_t*	heap;
-		ulint*		offsets;
-
-		heap = mem_heap_create(100);
-		offsets = rec_get_offsets(rec, foreign->foreign_index,
-					ULINT_UNDEFINED, heap);
-
 		fputs(", there is a record:\n", ef);
-		rec_print(ef, rec, offsets);
-		mem_heap_free(heap);
+		rec_print(ef, rec, foreign->foreign_index);
 	} else {
 		fputs(", the record is not available\n", ef);
 	}
@@ -654,16 +646,7 @@ row_ins_foreign_report_add_err(
 	}
 
 	if (rec) {
-		mem_heap_t*	heap;
-		ulint*		offsets;
-
-		heap = mem_heap_create(100);
-		offsets = rec_get_offsets(rec, foreign->foreign_index,
-					ULINT_UNDEFINED, heap);
-
-		rec_print(ef, rec, offsets);
-
-		mem_heap_free(heap);
+		rec_print(ef, rec, foreign->foreign_index);
 	}
 	putc('\n', ef);
 
@@ -734,7 +717,8 @@ row_ins_foreign_check_on_constraint(
 	ulint		i;
 	trx_t*		trx;
 	mem_heap_t*	tmp_heap	= NULL;
-	ulint*		offsets;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	ut_a(thr && foreign && pcur && mtr);
 
@@ -880,14 +864,10 @@ row_ins_foreign_check_on_constraint(
 
 			fputs("\n"
 				"InnoDB: record ", stderr);
-			offsets = rec_get_offsets(rec, index,
-						ULINT_UNDEFINED, tmp_heap);
-			rec_print(stderr, rec, offsets);
+			rec_print(stderr, rec, index);
 			fputs("\n"
 				"InnoDB: clustered record ", stderr);
-			offsets = rec_reget_offsets(clust_rec, clust_index,
-					offsets, ULINT_UNDEFINED, tmp_heap);
-			rec_print(stderr, clust_rec, offsets);
+			rec_print(stderr, clust_rec, clust_index);
 			fputs("\n"
 "InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr);
 
@@ -906,11 +886,8 @@ row_ins_foreign_check_on_constraint(
 		we already have a normal shared lock on the appropriate
 		gap if the search criterion was not unique */
 
-		if (!tmp_heap) {
-			tmp_heap = mem_heap_create(256);
-		}
-		offsets = rec_get_offsets(clust_rec, clust_index,
-						ULINT_UNDEFINED, tmp_heap);
+		offsets = rec_get_offsets(clust_rec, clust_index, offsets,
+						ULINT_UNDEFINED, &tmp_heap);
 		err = lock_clust_rec_read_check_and_lock(0, clust_rec,
 			clust_index, offsets, LOCK_X, LOCK_REC_NOT_GAP, thr);
 	}
@@ -1152,11 +1129,10 @@ row_ins_check_foreign_constraint(
 	ulint		err;
 	ulint		i;
 	mtr_t		mtr;
-	trx_t*		trx = thr_get_trx(thr);
-	mem_heap_t*	heap;
-	ulint*		offsets		= NULL;
-
-	heap = mem_heap_create(100);
+	trx_t*		trx		= thr_get_trx(thr);
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 run_again:
 #ifdef UNIV_SYNC_DEBUG
@@ -1168,8 +1144,7 @@ run_again:
 	if (trx->check_foreigns == FALSE) {
 		/* The user has suppressed foreign key checks currently for
 		this session */
-		mem_heap_free(heap);
-		return(DB_SUCCESS);
+		goto exit_func;
 	}
 
 	/* If any of the foreign key fields in entry is SQL NULL, we
@@ -1180,8 +1155,7 @@ run_again:
 		if (UNIV_SQL_NULL == dfield_get_len(
                                          dtuple_get_nth_field(entry, i))) {
 
-			mem_heap_free(heap);
-			return(DB_SUCCESS);
+			goto exit_func;
 		}
 	}
 
@@ -1205,8 +1179,7 @@ run_again:
 			another, and the user has problems predicting in
 			which order they are performed. */
 
-			mem_heap_free(heap);
-		        return(DB_SUCCESS);
+			goto exit_func;
 		}
 	}
 
@@ -1219,8 +1192,6 @@ run_again:
 	}
 
 	if (check_table == NULL) {
-		mem_heap_free(heap);
-
 		if (check_ref) {
 			FILE*	ef = dict_foreign_err_file;
 			mutex_enter(&dict_foreign_err_mutex);
@@ -1242,10 +1213,10 @@ run_again:
 			fputs(" does not currently exist!\n", ef);
 			mutex_exit(&dict_foreign_err_mutex);
 
-			return(DB_NO_REFERENCED_ROW);
+			err = DB_NO_REFERENCED_ROW;
 		}
 
-		return(DB_SUCCESS);
+		goto exit_func;
 	}
 
 	ut_a(check_table && check_index);
@@ -1291,8 +1262,8 @@ run_again:
 			goto next_rec;
 		}
 		
-		offsets = rec_reget_offsets(rec, check_index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(rec, check_index,
+					offsets, ULINT_UNDEFINED, &heap);
 
 		if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
 
@@ -1424,7 +1395,10 @@ do_possible_lock_wait:
 		err = trx->error_state;
 	}
 
-	mem_heap_free(heap);
+exit_func:
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	return(err);
 }
 
@@ -1565,8 +1539,9 @@ row_ins_scan_sec_index_for_duplicate(
 	ibool		moved;
 	mtr_t		mtr;
 	trx_t*		trx;
-	mem_heap_t*	heap;
-	ulint*		offsets		= NULL;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	n_unique = dict_index_get_n_unique(index);
 
@@ -1582,7 +1557,6 @@ row_ins_scan_sec_index_for_duplicate(
 		}
 	}
 
-	heap = mem_heap_create(100);
 	mtr_start(&mtr);
 
 	/* Store old value on n_fields_cmp */
@@ -1608,8 +1582,8 @@ row_ins_scan_sec_index_for_duplicate(
 		trx = thr_get_trx(thr);      
 		ut_ad(trx);
 
-		offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(rec, index, offsets,
+					ULINT_UNDEFINED, &heap);
 
 		if (innobase_query_is_replace()) {
 
@@ -1662,7 +1636,9 @@ next_rec:
 		}
 	}
 
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	mtr_commit(&mtr);
 
 	/* Restore old value */
@@ -1692,7 +1668,11 @@ row_ins_duplicate_error_in_clust(
 	rec_t*	rec;
 	page_t*	page;
 	ulint	n_unique;
-	trx_t*	trx	= thr_get_trx(thr);
+	trx_t*	trx		= thr_get_trx(thr);
+	mem_heap_t*heap		= NULL;
+	ulint	offsets_[100]	= { 100, };
+	ulint*	offsets		= offsets_;
+
 
 	UT_NOT_USED(mtr);
 	
@@ -1720,12 +1700,8 @@ row_ins_duplicate_error_in_clust(
 		page = buf_frame_align(rec);
 
 		if (rec != page_get_infimum_rec(page)) {
-			mem_heap_t*	heap;
-			ulint*		offsets;
-
-			heap = mem_heap_create(100);
-			offsets = rec_get_offsets(rec, cursor->index,
-							ULINT_UNDEFINED, heap);
+			offsets = rec_get_offsets(rec, cursor->index, offsets,
+						ULINT_UNDEFINED, &heap);
 
 			/* We set a lock on the possible duplicate: this
 			is needed in logical logging of MySQL to make
@@ -1750,17 +1726,15 @@ row_ins_duplicate_error_in_clust(
 			} 
 
 			if (err != DB_SUCCESS) {
-				mem_heap_free(heap);
-				return(err);
+				goto func_exit;
 			}
 
 			if (row_ins_dupl_error_with_rec(rec, entry,
 						cursor->index, offsets)) {
 				trx->error_info = cursor->index;
-				mem_heap_free(heap);
-				return(DB_DUPLICATE_KEY);
+				err = DB_DUPLICATE_KEY;
+				goto func_exit;
 			}
-			mem_heap_free(heap);
 		}
 	}
 
@@ -1770,12 +1744,8 @@ row_ins_duplicate_error_in_clust(
 		page = buf_frame_align(rec);
 
 		if (rec != page_get_supremum_rec(page)) {
-			mem_heap_t*	heap;
-			ulint*		offsets;
-
-			heap = mem_heap_create(100);
-			offsets = rec_get_offsets(rec, cursor->index,
-							ULINT_UNDEFINED, heap);
+			offsets = rec_get_offsets(rec, cursor->index, offsets,
+						ULINT_UNDEFINED, &heap);
 
 			/* The manual defines the REPLACE semantics that it 
 			is either an INSERT or DELETE(s) for duplicate key
@@ -1795,15 +1765,14 @@ row_ins_duplicate_error_in_clust(
 			}
 
 			if (err != DB_SUCCESS) {
-				mem_heap_free(heap);
-				return(err);
+				goto func_exit;
 			}
 
 			if (row_ins_dupl_error_with_rec(rec, entry,
 						cursor->index, offsets)) {
 				trx->error_info = cursor->index;
-				mem_heap_free(heap);
-				return(DB_DUPLICATE_KEY);
+				err = DB_DUPLICATE_KEY;
+				goto func_exit;
 			}
 			mem_heap_free(heap);
 		}
@@ -1812,7 +1781,9 @@ row_ins_duplicate_error_in_clust(
 						/* This should never happen */
 	}
 
-	return(DB_SUCCESS);
+	err = DB_SUCCESS;
+func_exit:
+	return(err);
 }
 
 /*******************************************************************
@@ -1894,8 +1865,9 @@ row_ins_index_entry_low(
 	ulint		n_unique;
 	big_rec_t*	big_rec			= NULL;
 	mtr_t		mtr;
-	mem_heap_t*	heap			= mem_heap_create(100);
-	ulint*		offsets			= NULL;
+	mem_heap_t*	heap			= NULL;
+	ulint		offsets_[100]		= { 100, };
+	ulint*		offsets			= offsets_;
 	
 	log_free_check();
 
@@ -2023,8 +1995,8 @@ function_exit:
 		btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
 					BTR_MODIFY_TREE, &cursor, 0, &mtr);
 		rec = btr_cur_get_rec(&cursor);
-		offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(rec, index, offsets,
+					ULINT_UNDEFINED, &heap);
 
 		err = btr_store_big_rec_extern_fields(index, rec,
 						offsets, big_rec, &mtr);
@@ -2038,7 +2010,9 @@ function_exit:
 		mtr_commit(&mtr);
 	}
 
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	return(err);
 }
 
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 8a3846e046c..e959c28f6bb 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -3221,18 +3221,19 @@ row_scan_and_check_index(
 	ulint*		n_rows)		/* out: number of entries seen in the
 					current consistent read */
 {
-	mem_heap_t*	heap;
-	dtuple_t*	prev_entry = NULL;
+	dtuple_t*	prev_entry	= NULL;
 	ulint		matched_fields;
 	ulint		matched_bytes;
 	byte*		buf;
 	ulint		ret;
 	rec_t*		rec;
-	ibool		is_ok	= TRUE;
+	ibool		is_ok		= TRUE;
 	int		cmp;
 	ibool		contains_null;
 	ulint		i;
-	ulint*		offsets	= NULL;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	*n_rows = 0;
 	
@@ -3274,8 +3275,8 @@ loop:
 		matched_fields = 0;
 		matched_bytes = 0;
 
-		offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 		cmp = cmp_dtuple_rec_with_match(prev_entry, rec, offsets,
 						&matched_fields,
 						&matched_bytes);
@@ -3305,7 +3306,7 @@ loop:
 			dtuple_print(stderr, prev_entry);
 			fputs("\n"
 				"InnoDB: record ", stderr);
-			rec_print(stderr, rec, offsets);
+			rec_print_new(stderr, rec, offsets);
 			putc('\n', stderr);
 			is_ok = FALSE;
 		} else if ((index->type & DICT_UNIQUE)
@@ -3319,7 +3320,7 @@ loop:
 	}
 
 	mem_heap_empty(heap);
-	offsets = NULL;
+	offsets = offsets_;
 	
 	prev_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap);
 
diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c
index 109d0f3b976..8897a1a872f 100644
--- a/innobase/row/row0purge.c
+++ b/innobase/row/row0purge.c
@@ -100,7 +100,8 @@ row_purge_remove_clust_if_poss_low(
 	ulint		err;
 	mtr_t		mtr;
 	rec_t*		rec;
-	mem_heap_t*	heap;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
 
 	index = dict_table_get_first_index(node->table);
 	
@@ -120,19 +121,22 @@ row_purge_remove_clust_if_poss_low(
 	}
 
 	rec = btr_pcur_get_rec(pcur);
-	heap = mem_heap_create(100);
 
 	if (0 != ut_dulint_cmp(node->roll_ptr,
 		row_get_rec_roll_ptr(rec, index, rec_get_offsets(
-				rec, index, ULINT_UNDEFINED, heap)))) {
-		mem_heap_free(heap);
+			rec, index, offsets_, ULINT_UNDEFINED, &heap)))) {
+		if (heap) {
+			mem_heap_free(heap);
+		}
 		/* Someone else has modified the record later: do not remove */
 		btr_pcur_commit_specify_mtr(pcur, &mtr);
 
 		return(TRUE);
 	}
 
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 
 	if (mode == BTR_MODIFY_LEAF) {
 		success = btr_cur_optimistic_delete(btr_cur, &mtr);
diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c
index 9cf285a519d..43d0cd41b0a 100644
--- a/innobase/row/row0row.c
+++ b/innobase/row/row0row.c
@@ -202,17 +202,16 @@ row_build(
 	ulint		row_len;
 	byte*		buf; 
 	ulint		i;
-	mem_heap_t*	tmp_heap;
+	mem_heap_t*	tmp_heap	= NULL;
+	ulint		offsets_[100]	= { 100, };
 
 	ut_ad(index && rec && heap);
 	ut_ad(index->type & DICT_CLUSTERED);
 
 	if (!offsets) {
-		tmp_heap = mem_heap_create(100);
-		offsets = rec_get_offsets(rec, index,
-					ULINT_UNDEFINED, tmp_heap);
+		offsets = rec_get_offsets(rec, index, offsets_,
+					ULINT_UNDEFINED, &tmp_heap);
 	} else {
-		tmp_heap = NULL;
 		ut_ad(rec_offs_validate(rec, index, offsets));
 	}
 
@@ -296,13 +295,14 @@ row_rec_to_index_entry(
 	ulint		len;
 	ulint		rec_len;
 	byte*		buf;
-	mem_heap_t*	tmp_heap;
-	ulint*		offsets;
+	mem_heap_t*	tmp_heap	= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	ut_ad(rec && heap && index);
 	
-	tmp_heap = mem_heap_create(100);
-	offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, tmp_heap);
+	offsets = rec_get_offsets(rec, index, offsets,
+					ULINT_UNDEFINED, &tmp_heap);
 
 	if (type == ROW_COPY_DATA) {
 		/* Take a copy of rec to heap */
@@ -334,7 +334,9 @@ row_rec_to_index_entry(
 	}
 
 	ut_ad(dtuple_check_typed(entry));
-	mem_heap_free(tmp_heap);
+	if (tmp_heap) {
+		mem_heap_free(tmp_heap);
+	}
 
 	return(entry);
 }
@@ -374,13 +376,14 @@ row_build_row_ref(
 	byte*		buf;
 	ulint		clust_col_prefix_len;
 	ulint		i;
-	mem_heap_t*	tmp_heap;
-	ulint*		offsets;
-	
+	mem_heap_t*	tmp_heap	= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
+
 	ut_ad(index && rec && heap);
 
-	tmp_heap = mem_heap_create(100);
-	offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, tmp_heap);
+	offsets = rec_get_offsets(rec, index, offsets,
+					ULINT_UNDEFINED, &tmp_heap);
 
 	if (type == ROW_COPY_DATA) {
 		/* Take a copy of rec to heap */
@@ -433,7 +436,9 @@ row_build_row_ref(
 	}
 
 	ut_ad(dtuple_check_typed(ref));
-	mem_heap_free(tmp_heap);
+	if (tmp_heap) {
+		mem_heap_free(tmp_heap);
+	}
 
 	return(ref);
 }
@@ -464,8 +469,9 @@ row_build_row_ref_in_tuple(
 	ulint		pos;
 	ulint		clust_col_prefix_len;
 	ulint		i;
-	mem_heap_t*	heap;
-	ulint*		offsets;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	ut_a(ref && index && rec);
 	
@@ -486,8 +492,7 @@ row_build_row_ref_in_tuple(
 		goto notfound;
 	}
 
-	heap = mem_heap_create(100);
-	offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
 
 	ref_len = dict_index_get_n_unique(clust_index);
 
@@ -526,7 +531,9 @@ row_build_row_ref_in_tuple(
 	}
 
 	ut_ad(dtuple_check_typed(ref));
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 }
 
 /***********************************************************************
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index 2b40b62e5bc..a3d844d1dac 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -78,14 +78,19 @@ row_sel_sec_rec_is_for_clust_rec(
         ulint           n;
         ulint           i;
 	dtype_t*	cur_type;
-	mem_heap_t*	heap;
-	ulint*		clust_offs;
-	ulint*		sec_offs;
+	mem_heap_t*	heap		= NULL;
+	ulint		clust_offsets_[100]
+					= { 100, };
+	ulint		sec_offsets_[10]
+					= { 10, };
+	ulint*		clust_offs	= clust_offsets_;
+	ulint*		sec_offs	= sec_offsets_;
+	ibool		is_equal	= TRUE;
 
-	heap = mem_heap_create(100);
-	clust_offs = rec_get_offsets(clust_rec, clust_index,
-						 ULINT_UNDEFINED, heap);
-	sec_offs = rec_get_offsets(sec_rec, sec_index, ULINT_UNDEFINED, heap);
+	clust_offs = rec_get_offsets(clust_rec, clust_index, clust_offs,
+						ULINT_UNDEFINED, &heap);
+	sec_offs = rec_get_offsets(sec_rec, sec_index, sec_offs,
+						ULINT_UNDEFINED, &heap);
 
         n = dict_index_get_n_ordering_defined_by_user(sec_index);
 
@@ -113,13 +118,16 @@ row_sel_sec_rec_is_for_clust_rec(
                 if (0 != cmp_data_data(dict_col_get_type(col),
                                         clust_field, clust_len,
                                         sec_field, sec_len)) {
-			mem_heap_free(heap);
-                        return(FALSE);
+			is_equal = FALSE;
+			goto func_exit;
                 }
         }
 
-	mem_heap_free(heap);
-        return(TRUE);
+func_exit:
+	if (heap) {
+		mem_heap_free(heap);
+	}
+	return(is_equal);
 }
 
 /*************************************************************************
@@ -612,13 +620,13 @@ row_sel_get_clust_rec(
 	rec_t*		clust_rec;
 	rec_t*		old_vers;
 	ulint		err;
-	mem_heap_t*	heap;
-	ulint*		offsets;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
-	heap = mem_heap_create(100);
 	offsets = rec_get_offsets(rec,
 				btr_pcur_get_btr_cur(&plan->pcur)->index,
-				ULINT_UNDEFINED, heap);
+				offsets, ULINT_UNDEFINED, &heap);
 	
 	row_build_row_ref_fast(plan->clust_ref, plan->clust_map, rec, offsets);
 
@@ -654,8 +662,8 @@ row_sel_get_clust_rec(
 		goto func_exit;
 	}
 
-	offsets = rec_reget_offsets(clust_rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(clust_rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 
 	if (!node->read_view) {
 		/* Try to place a lock on the index record */
@@ -677,8 +685,7 @@ row_sel_get_clust_rec(
 
 		if (err != DB_SUCCESS) {
 
-			mem_heap_free(heap);
-			return(err);
+			goto err_exit;
 		}
 	} else {
 		/* This is a non-locking consistent read: if necessary, fetch
@@ -693,8 +700,7 @@ row_sel_get_clust_rec(
 					clust_rec, &old_vers, mtr);
 			if (err != DB_SUCCESS) {
 
-				mem_heap_free(heap);
-				return(err);
+				goto err_exit;
 			}
 
 			clust_rec = old_vers;
@@ -731,9 +737,12 @@ row_sel_get_clust_rec(
 					UT_LIST_GET_FIRST(plan->columns));
 func_exit:
 	*out_rec = clust_rec;
-
-	mem_heap_free(heap);
-	return(DB_SUCCESS);
+	err = DB_SUCCESS;
+err_exit:
+	if (heap) {
+		mem_heap_free(heap);
+	}
+	return(err);
 }
 
 /*************************************************************************
@@ -975,8 +984,10 @@ row_sel_try_search_shortcut(
 {
 	dict_index_t*	index;
 	rec_t*		rec;
-	mem_heap_t*	heap;
-	ulint*		offsets;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
+	ulint		ret;
 
 	index = plan->index;
 
@@ -1010,43 +1021,46 @@ row_sel_try_search_shortcut(
 	/* This is a non-locking consistent read: if necessary, fetch
 	a previous version of the record */
 			
-	heap = mem_heap_create(100);
-	offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
 
 	if (index->type & DICT_CLUSTERED) {
 		if (!lock_clust_rec_cons_read_sees(rec, index, offsets,
 							node->read_view)) {
-			mem_heap_free(heap);
-			return(SEL_RETRY);
+			ret = SEL_RETRY;
+			goto func_exit;
 		}
 	} else if (!lock_sec_rec_cons_read_sees(rec, index, node->read_view)) {
 
-		mem_heap_free(heap);
-		return(SEL_RETRY);
+		ret = SEL_RETRY;
+		goto func_exit;
 	}
 
 	/* Test deleted flag. Fetch the columns needed in test conditions. */
 
 	row_sel_fetch_columns(index, rec, offsets,
 				UT_LIST_GET_FIRST(plan->columns));
-	mem_heap_free(heap);
 
 	if (rec_get_deleted_flag(rec, plan->table->comp)) {
 
-		return(SEL_EXHAUSTED);
+		ret = SEL_EXHAUSTED;
+		goto func_exit;
 	}
 
 	/* Test the rest of search conditions */
 	
 	if (!row_sel_test_other_conds(plan)) {
 
-		return(SEL_EXHAUSTED);
+		ret = SEL_EXHAUSTED;
+		goto func_exit;
 	}
 
 	ut_ad(plan->pcur.latch_mode == node->latch_mode);
 
 	plan->n_rows_fetched++;
-
+func_exit:
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	return(SEL_FOUND);
 }
 
@@ -1095,8 +1109,9 @@ row_sel(
 					to the next non-clustered record */
 	ulint		found_flag;
 	ulint		err;
-	mem_heap_t*	heap				= mem_heap_create(100);
-	ulint*		offsets				= NULL;
+	mem_heap_t*	heap				= NULL;
+	ulint		offsets_[100]			= { 100, };
+	ulint*		offsets				= offsets_;
 
 	ut_ad(thr->run_node == node);
 
@@ -1253,8 +1268,8 @@ rec_loop:
 
 			rec_t*	next_rec = page_rec_get_next(rec);
 			ulint	lock_type;
-			offsets = rec_reget_offsets(next_rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+			offsets = rec_get_offsets(next_rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 
 			if (srv_locks_unsafe_for_binlog) {
 				lock_type = LOCK_REC_NOT_GAP;
@@ -1295,8 +1310,8 @@ rec_loop:
 		not used. */
 
 		ulint	lock_type;
-		offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 
 		if (srv_locks_unsafe_for_binlog) {
 			lock_type = LOCK_REC_NOT_GAP;
@@ -1369,8 +1384,7 @@ rec_loop:
 	/* PHASE 3: Get previous version in a consistent read */
 
 	cons_read_requires_clust_rec = FALSE;
-	offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
 
 	if (consistent_read) {
 		/* This is a non-locking consistent read: if necessary, fetch
@@ -1403,8 +1417,8 @@ rec_loop:
 				}
 
 				rec = old_vers;
-				offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+				offsets = rec_get_offsets(rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 			}
 		} else if (!lock_sec_rec_cons_read_sees(rec, index,
 							node->read_view)) {
@@ -1635,8 +1649,8 @@ next_table_no_mtr:
 			rw_lock_s_unlock(&btr_search_latch);
 		}
 
-		mem_heap_free(heap);
-		return(DB_SUCCESS);
+		err = DB_SUCCESS;
+		goto func_exit;
 	}
 
 	node->fetch_table++;
@@ -1669,7 +1683,7 @@ table_exhausted:
 
 table_exhausted_no_mtr:
 	if (node->fetch_table == 0) {
-		mem_heap_free(heap);
+		err = DB_SUCCESS;
 
 		if (node->is_aggregate && !node->aggregate_already_fetched) {
 
@@ -1683,7 +1697,7 @@ table_exhausted_no_mtr:
 				rw_lock_s_unlock(&btr_search_latch);
 			}
 		
-			return(DB_SUCCESS);
+			goto func_exit;
 		}
 
 		node->state = SEL_NODE_NO_MORE_ROWS;
@@ -1694,7 +1708,7 @@ table_exhausted_no_mtr:
 			rw_lock_s_unlock(&btr_search_latch);
 		}
 		
-		return(DB_SUCCESS);
+		goto func_exit;
 	}
 
 	node->fetch_table--;
@@ -1718,8 +1732,8 @@ stop_for_a_while:
 	mtr_commit(&mtr);
 		
 	ut_ad(sync_thread_levels_empty_gen(TRUE));
-	mem_heap_free(heap);
-	return(DB_SUCCESS);
+	err = DB_SUCCESS;
+	goto func_exit;
 
 commit_mtr_for_a_while:
 	/* Stores the cursor position and commits &mtr; this is used if
@@ -1754,7 +1768,10 @@ lock_wait_or_error:
 		
 	ut_ad(sync_thread_levels_empty_gen(TRUE));
 
-	mem_heap_free(heap);
+func_exit:
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	return(err);
 }
 
@@ -2197,7 +2214,7 @@ row_sel_store_row_id_to_prebuilt(
 		fprintf(stderr, "\n"
 "InnoDB: Field number %lu, record:\n",
 			(ulong) dict_index_get_sys_col_pos(index, DATA_ROW_ID));
-		rec_print(stderr, index_rec, offsets);
+		rec_print_new(stderr, index_rec, offsets);
 		putc('\n', stderr);
 		ut_error;
 	}
@@ -2496,8 +2513,9 @@ row_sel_get_clust_rec_for_mysql(
 	rec_t*		old_vers;
 	ulint		err;
 	trx_t*		trx;
-	mem_heap_t*	heap		= mem_heap_create(100);
-	ulint*		offsets		= NULL;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	*out_rec = NULL;
 	trx = thr_get_trx(thr);
@@ -2537,14 +2555,10 @@ row_sel_get_clust_rec_for_mysql(
 			dict_index_name_print(stderr, trx, sec_index);
 			fputs("\n"
 				"InnoDB: sec index record ", stderr);
-			offsets = rec_get_offsets(rec, sec_index,
-							ULINT_UNDEFINED, heap);
-			rec_print(stderr, rec, offsets);
+			rec_print(stderr, rec, sec_index);
 			fputs("\n"
 				"InnoDB: clust index record ", stderr);
-			offsets = rec_reget_offsets(clust_rec, clust_index,
-					offsets, ULINT_UNDEFINED, heap);
-			rec_print(stderr, clust_rec, offsets);
+			rec_print(stderr, clust_rec, clust_index);
 			putc('\n', stderr);
 			trx_print(stderr, trx);
 
@@ -2557,8 +2571,8 @@ row_sel_get_clust_rec_for_mysql(
 		goto func_exit;
 	}
 
-	offsets = rec_get_offsets(clust_rec, clust_index,
-					ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(clust_rec, clust_index, offsets,
+					ULINT_UNDEFINED, &heap);
 
 	if (prebuilt->select_lock_type != LOCK_NONE) {
 		/* Try to place a lock on the index record; we are searching
@@ -2571,8 +2585,7 @@ row_sel_get_clust_rec_for_mysql(
 					LOCK_REC_NOT_GAP, thr);
 		if (err != DB_SUCCESS) {
 
-			mem_heap_free(heap);
-			return(err);
+			goto err_exit;
 		}
 	} else {
 		/* This is a non-locking consistent read: if necessary, fetch
@@ -2594,8 +2607,7 @@ row_sel_get_clust_rec_for_mysql(
 						
 			if (err != DB_SUCCESS) {
 
-				mem_heap_free(heap);
-				return(err);
+				goto err_exit;
 			}
 
 			clust_rec = old_vers;
@@ -2637,8 +2649,12 @@ func_exit:
 		btr_pcur_store_position(prebuilt->clust_pcur, mtr);
 	}
 
-	mem_heap_free(heap);
-	return(DB_SUCCESS);
+	err = DB_SUCCESS;
+err_exit:
+	if (heap) {
+		mem_heap_free(heap);
+	}
+	return(err);
 }
 
 /************************************************************************
@@ -2809,8 +2825,8 @@ row_sel_try_search_shortcut_for_mysql(
 				/* out: SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */
 	rec_t**		out_rec,/* out: record if found */
 	row_prebuilt_t*	prebuilt,/* in: prebuilt struct */
-	ulint**		offsets,/* in/out: for rec_reget_offsets(*out_rec) */
-	mem_heap_t*	heap,	/* in: heap for rec_reget_offsets() */
+	ulint**		offsets,/* in/out: for rec_get_offsets(*out_rec) */
+	mem_heap_t**	heap,	/* in/out: heap for rec_get_offsets() */
 	mtr_t*		mtr)	/* in: started mtr */
 {
 	dict_index_t*	index		= prebuilt->index;
@@ -2849,8 +2865,8 @@ row_sel_try_search_shortcut_for_mysql(
 	/* This is a non-locking consistent read: if necessary, fetch
 	a previous version of the record */
 
-	*offsets = rec_reget_offsets(rec, index,
-					*offsets, ULINT_UNDEFINED, heap);
+	*offsets = rec_get_offsets(rec, index, *offsets,
+					ULINT_UNDEFINED, heap);
 
 	if (!lock_clust_rec_cons_read_sees(rec, index,
 				*offsets, trx->read_view)) {
@@ -2915,7 +2931,6 @@ row_search_for_mysql(
 	ibool		moved;
 	ibool		cons_read_requires_clust_rec;
 	ibool		was_lock_wait;
-	ulint		ret;
 	ulint		shortcut;
 	ibool		unique_search			= FALSE;
 	ibool		unique_search_from_clust_index	= FALSE;
@@ -2931,8 +2946,9 @@ row_search_for_mysql(
 	ulint		cnt				= 0;
 	ulint		next_offs;
 	mtr_t		mtr;
-	mem_heap_t*	heap;
-	ulint*		offsets				= NULL;
+	mem_heap_t*	heap				= NULL;
+	ulint		offsets_[100]			= { 100, };
+	ulint*		offsets				= offsets_;
 	
 	ut_ad(index && pcur && search_tuple);
 	ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
@@ -3023,9 +3039,8 @@ row_search_for_mysql(
 			prebuilt->n_rows_fetched++;
 
 			srv_n_rows_read++;
-			trx->op_info = "";
-
-			return(DB_SUCCESS);
+			err = DB_SUCCESS;
+			goto func_exit;
 		}
 
 		if (prebuilt->fetch_cache_first > 0
@@ -3034,9 +3049,9 @@ row_search_for_mysql(
 		    	/* The previous returned row was popped from the fetch
 		    	cache, but the cache was not full at the time of the
 		    	popping: no more rows can exist in the result set */
-		    
-			trx->op_info = "";
-		    	return(DB_RECORD_NOT_FOUND);
+
+			err = DB_RECORD_NOT_FOUND;
+			goto func_exit;
 		}
 		
 		prebuilt->n_rows_fetched++;
@@ -3080,13 +3095,12 @@ row_search_for_mysql(
 
 		if (direction != 0 && !prebuilt->used_in_HANDLER) {
         
-			trx->op_info = "";
-			return(DB_RECORD_NOT_FOUND);
+			err = DB_RECORD_NOT_FOUND;
+			goto func_exit;
 		}
 	}
 
 	mtr_start(&mtr);
-	heap = mem_heap_create(100);
 
 	/*-------------------------------------------------------------*/
 	/* PHASE 2: Try fast adaptive hash index search if possible */
@@ -3132,7 +3146,7 @@ row_search_for_mysql(
 			}
 #endif
 			shortcut = row_sel_try_search_shortcut_for_mysql(&rec,
-					prebuilt, &offsets, heap, &mtr);
+					prebuilt, &offsets, &heap, &mtr);
 			if (shortcut == SEL_FOUND) {
 #ifdef UNIV_SEARCH_DEBUG
 				ut_a(0 == cmp_dtuple_rec(search_tuple,
@@ -3163,12 +3177,10 @@ row_search_for_mysql(
 					trx->has_search_latch = FALSE;
 				}    	
 				
-				trx->op_info = "";
-				
 				/* NOTE that we do NOT store the cursor
 				position */
-				mem_heap_free(heap);
-				return(DB_SUCCESS);
+				err = DB_SUCCESS;
+				goto func_exit;
 			
 			} else if (shortcut == SEL_EXHAUSTED) {
 
@@ -3186,13 +3198,11 @@ row_search_for_mysql(
 					trx->has_search_latch = FALSE;
 				}
 
-				trx->op_info = "";
-
 				/* NOTE that we do NOT store the cursor
 				position */
 
-				mem_heap_free(heap);
-				return(DB_RECORD_NOT_FOUND);
+				err = DB_RECORD_NOT_FOUND;
+				goto func_exit;
 			}
 shortcut_fails_too_big_rec:
 			mtr_commit(&mtr);
@@ -3334,9 +3344,9 @@ 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 == FALSE) {
-				offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+			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);
@@ -3406,8 +3416,7 @@ rec_loop:
 		}
 	}
 
-	offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
 
 	if (srv_force_recovery > 0) {
 		if (!rec_validate(rec, offsets)
@@ -3464,7 +3473,7 @@ rec_loop:
 
 			btr_pcur_store_position(pcur, &mtr);
 
-			ret = DB_RECORD_NOT_FOUND;
+			err = DB_RECORD_NOT_FOUND;
 			/* ut_print_name(stderr, index->name);
 			fputs(" record not found 3\n", stderr); */
 			
@@ -3498,7 +3507,7 @@ rec_loop:
 
 			btr_pcur_store_position(pcur, &mtr);
 
-			ret = DB_RECORD_NOT_FOUND;
+			err = DB_RECORD_NOT_FOUND;
 			/* ut_print_name(stderr, index->name);
 			fputs(" record not found 4\n", stderr); */
 
@@ -3644,11 +3653,11 @@ rec_loop:
 
 	if (prebuilt->need_to_access_clustered) {
 		ut_ad(rec == clust_rec || index == clust_index);
-		offsets = rec_reget_offsets(rec, clust_index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(rec, clust_index, offsets,
+						ULINT_UNDEFINED, &heap);
 	} else {
-		offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 	}
 
 	/* We found a qualifying row */
@@ -3694,8 +3703,8 @@ rec_loop:
 		}
 
 		if (prebuilt->clust_index_was_generated) {
-			offsets = rec_reget_offsets(index_rec, index, offsets,
-							ULINT_UNDEFINED, heap);
+			offsets = rec_get_offsets(index_rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 			row_sel_store_row_id_to_prebuilt(prebuilt, index_rec,
 							index, offsets);
 		}
@@ -3717,7 +3726,7 @@ got_row:
 		btr_pcur_store_position(pcur, &mtr);
 	}
 
-	ret = DB_SUCCESS;
+	err = DB_SUCCESS;
 
 	goto normal_return;
 
@@ -3756,9 +3765,9 @@ next_rec:
 		btr_pcur_store_position(pcur, &mtr);
 
 		if (match_mode != 0) {
-			ret = DB_RECORD_NOT_FOUND;
+			err = DB_RECORD_NOT_FOUND;
 		} else {
-			ret = DB_END_OF_INDEX;
+			err = DB_END_OF_INDEX;
 		}
 
 		goto normal_return;
@@ -3797,10 +3806,7 @@ lock_wait_or_error:
 /*	fputs("Using ", stderr);
 	dict_index_name_print(stderr, index);
 	fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */
-	trx->op_info = "";
-
-	mem_heap_free(heap);
-	return(err);
+	goto func_exit;
 
 normal_return:
 	/*-------------------------------------------------------------*/
@@ -3811,20 +3817,22 @@ normal_return:
 	if (prebuilt->n_fetch_cached > 0) {
 		row_sel_pop_cached_row_for_mysql(buf, prebuilt);
 
-		ret = DB_SUCCESS;
+		err = DB_SUCCESS;
 	}
 
 /*	fputs("Using ", stderr);
 	dict_index_name_print(stderr, index);
 	fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */
-	if (ret == DB_SUCCESS) {
+	if (err == DB_SUCCESS) {
 		srv_n_rows_read++;
 	}
 
+func_exit:
 	trx->op_info = "";
-
-	mem_heap_free(heap);
-	return(ret);
+	if (heap) {
+		mem_heap_free(heap);
+	}
+	return(err);
 }
 
 /***********************************************************************
diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c
index ee9066a0d6f..1cade0f304f 100644
--- a/innobase/row/row0umod.c
+++ b/innobase/row/row0umod.c
@@ -430,7 +430,6 @@ row_undo_mod_del_unmark_sec_and_undo_update(
 	found = row_search_index_entry(index, entry, mode, &pcur, &mtr);
 
 	if (!found) {
-		heap = mem_heap_create(100);
 		fputs("InnoDB: error in sec index entry del undo in\n"
 			"InnoDB: ", stderr);
 		dict_index_name_print(stderr, trx, index);
@@ -439,14 +438,11 @@ row_undo_mod_del_unmark_sec_and_undo_update(
 		dtuple_print(stderr, entry);
 		fputs("\n"
 			"InnoDB: record ", stderr);
-		rec_print(stderr, btr_pcur_get_rec(&pcur),
-				rec_get_offsets(btr_pcur_get_rec(&pcur),
-				index, ULINT_UNDEFINED, heap));
+		rec_print(stderr, btr_pcur_get_rec(&pcur), index);
 		putc('\n', stderr);
 		trx_print(stderr, trx);
 		fputs("\n"
 "InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr);
-		mem_heap_free(heap);
 	} else {
 		btr_cur_t*	btr_cur = btr_pcur_get_btr_cur(&pcur);
 
diff --git a/innobase/row/row0undo.c b/innobase/row/row0undo.c
index 42f5ef94854..d994eab9873 100644
--- a/innobase/row/row0undo.c
+++ b/innobase/row/row0undo.c
@@ -151,8 +151,9 @@ row_undo_search_clust_to_pcur(
 	mtr_t		mtr;
 	ibool		ret;
 	rec_t*		rec;
-	mem_heap_t*	heap;
-	const ulint*	offsets;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	mtr_start(&mtr);
 
@@ -163,8 +164,8 @@ row_undo_search_clust_to_pcur(
 
 	rec = btr_pcur_get_rec(&(node->pcur));
 
-	heap = mem_heap_create(100);
-	offsets = rec_get_offsets(rec, clust_index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, clust_index, offsets,
+						ULINT_UNDEFINED, &heap);
 
 	if (!found || 0 != ut_dulint_cmp(node->roll_ptr,
 			row_get_rec_roll_ptr(rec, clust_index, offsets))) {
@@ -188,6 +189,9 @@ row_undo_search_clust_to_pcur(
 
 	btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
 
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	return(ret);
 }
 	
diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c
index e080d0ba577..e4013633bed 100644
--- a/innobase/row/row0upd.c
+++ b/innobase/row/row0upd.c
@@ -700,6 +700,7 @@ row_upd_build_sec_rec_difference_binary(
 	upd_t*		update;
 	ulint		n_diff;
 	ulint		i;
+	ulint		offsets_[10]	= { 10, };
 	const ulint*	offsets;
 
 	/* This function is used only for a secondary index */
@@ -708,7 +709,8 @@ row_upd_build_sec_rec_difference_binary(
 	update = upd_create(dtuple_get_n_fields(entry), heap);
 
 	n_diff = 0;
-	offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, index, offsets_,
+						ULINT_UNDEFINED, &heap);
 
 	for (i = 0; i < dtuple_get_n_fields(entry); i++) {
 
@@ -775,6 +777,7 @@ row_upd_build_difference_binary(
 	ulint		trx_id_pos;
 	ibool		extern_bit;
 	ulint		i;
+	ulint		offsets_[100]	= { 100, };
 	const ulint*	offsets;
 
 	/* This function is used only for a clustered index */
@@ -787,7 +790,8 @@ row_upd_build_difference_binary(
 	roll_ptr_pos = dict_index_get_sys_col_pos(index, DATA_ROLL_PTR);
 	trx_id_pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID);
 
-	offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, index, offsets_,
+				ULINT_UNDEFINED, &heap);
 
 	for (i = 0; i < dtuple_get_n_fields(entry); i++) {
 
@@ -1182,7 +1186,8 @@ row_upd_store_row(
 	dict_index_t*	clust_index;
 	upd_t*		update;
 	rec_t*		rec;
-	mem_heap_t*	heap;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
 	const ulint*	offsets;
 
 	ut_ad(node->pcur->latch_mode != BTR_NO_LATCHES);
@@ -1196,8 +1201,8 @@ row_upd_store_row(
 
 	rec = btr_pcur_get_rec(node->pcur);
 	
-	heap = mem_heap_create(100);
-	offsets = rec_get_offsets(rec, clust_index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, clust_index, offsets_,
+						ULINT_UNDEFINED, &heap);
 	node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets,
 								node->heap);
 	node->ext_vec = mem_heap_alloc(node->heap, sizeof(ulint)
@@ -1210,7 +1215,9 @@ row_upd_store_row(
 	
 	node->n_ext_vec = btr_push_update_extern_fields(node->ext_vec,
 						offsets, update);
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 }
 
 /***************************************************************
@@ -1263,8 +1270,7 @@ row_upd_sec_index_entry(
 		dtuple_print(stderr, entry);
 		fputs("\n"
 			"InnoDB: record ", stderr);
-		rec_print(stderr, rec,
-			rec_get_offsets(rec, index, ULINT_UNDEFINED, heap));
+		rec_print(stderr, rec, index);
 		putc('\n', stderr);
 
 		trx_print(stderr, trx);
@@ -1364,7 +1370,7 @@ row_upd_clust_rec_by_insert(
 				a foreign key constraint */
 	mtr_t*		mtr)	/* in: mtr; gets committed here */
 {
-	mem_heap_t*	heap;
+	mem_heap_t*	heap	= NULL;
 	btr_pcur_t*	pcur;
 	btr_cur_t*	btr_cur;
 	trx_t*		trx;
@@ -1379,15 +1385,14 @@ row_upd_clust_rec_by_insert(
 	table = node->table;
 	pcur = node->pcur;
 	btr_cur	= btr_pcur_get_btr_cur(pcur);
-	heap = mem_heap_create(500);
 	
 	if (node->state != UPD_NODE_INSERT_CLUSTERED) {
+		ulint	offsets_[100]	= { 100, };
 
 		err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG,
 						btr_cur, TRUE, thr, mtr);
 		if (err != DB_SUCCESS) {
 			mtr_commit(mtr);
-			mem_heap_free(heap);
 			return(err);
 		}
 
@@ -1398,8 +1403,8 @@ row_upd_clust_rec_by_insert(
 
 		btr_cur_mark_extern_inherited_fields(btr_cur_get_rec(btr_cur),
 				rec_get_offsets(btr_cur_get_rec(btr_cur),
-				dict_table_get_first_index(table),
-				ULINT_UNDEFINED, heap), node->update, mtr);
+				dict_table_get_first_index(table), offsets_,
+				ULINT_UNDEFINED, &heap), node->update, mtr);
 		if (check_ref) {
 			/* NOTE that the following call loses
 			the position of pcur ! */
@@ -1408,7 +1413,9 @@ row_upd_clust_rec_by_insert(
 							index, thr, mtr);
 			if (err != DB_SUCCESS) {
 				mtr_commit(mtr);
-
+				if (heap) {
+					mem_heap_free(heap);
+				}
 				return(err);
 			}
 		}
@@ -1417,6 +1424,9 @@ row_upd_clust_rec_by_insert(
 
 	mtr_commit(mtr);
 
+	if (!heap) {
+		heap = mem_heap_create(500);
+	}
 	node->state = UPD_NODE_INSERT_CLUSTERED;
 
 	entry = row_build_index_entry(node->row, index, heap);
@@ -1516,17 +1526,20 @@ row_upd_clust_rec(
 	mtr_commit(mtr);
 
 	if (err == DB_SUCCESS && big_rec) {
-		mem_heap_t*	heap;
+		mem_heap_t*	heap		= NULL;
+		ulint		offsets_[100]	= { 100, };
 		rec_t*		rec;
 		mtr_start(mtr);
 
-		heap = mem_heap_create(100);
 		rec = btr_cur_get_rec(btr_cur);
 		ut_a(btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr));
 		err = btr_store_big_rec_extern_fields(index, rec,
-			rec_get_offsets(rec, index, ULINT_UNDEFINED, heap),
+			rec_get_offsets(rec, index, offsets_,
+				ULINT_UNDEFINED, &heap),
 			big_rec, mtr);
-		mem_heap_free(heap);
+		if (heap) {
+			mem_heap_free(heap);
+		}
 		mtr_commit(mtr);
 	}
 
@@ -1611,7 +1624,8 @@ row_upd_clust_step(
 	mtr_t*		mtr;
 	mtr_t		mtr_buf;
 	rec_t*		rec;
-	mem_heap_t*	heap;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
 	const ulint*	offsets;
 
 	index = dict_table_get_first_index(node->table);
@@ -1670,33 +1684,31 @@ row_upd_clust_step(
 	} 
 
 	rec = btr_pcur_get_rec(pcur);
-	heap = mem_heap_create(100);
-	offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, index, offsets_,
+						ULINT_UNDEFINED, &heap);
 
 	if (!node->has_clust_rec_x_lock) {
 		err = lock_clust_rec_modify_check_and_lock(0,
 						rec, index, offsets, thr);
 		if (err != DB_SUCCESS) {
 			mtr_commit(mtr);
-			mem_heap_free(heap);
-			return(err);
+			goto exit_func;
 		}
 	}
 
 	/* NOTE: the following function calls will also commit mtr */
 
 	if (node->is_delete) {
-		mem_heap_free(heap);
 		err = row_upd_del_mark_clust_rec(node, index, thr, check_ref,
 									mtr);
-		if (err != DB_SUCCESS) {
-
-			return(err);
+		if (err == DB_SUCCESS) {
+			node->state = UPD_NODE_UPDATE_ALL_SEC;
+			node->index = dict_table_get_next_index(index);
+		}
+	exit_func:
+		if (heap) {
+			mem_heap_free(heap);
 		}
-
-		node->state = UPD_NODE_UPDATE_ALL_SEC;
-		node->index = dict_table_get_next_index(index);
-
 		return(err);
 	}
 	
@@ -1710,13 +1722,14 @@ row_upd_clust_step(
 					UT_LIST_GET_FIRST(node->columns));
 		row_upd_eval_new_vals(node->update);
 	}
-		
-	mem_heap_free(heap);
 
+	if (heap) {
+		mem_heap_free(heap);
+	}
+		
 	if (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) {
 
 		err = row_upd_clust_rec(node, index, thr, mtr);
-
 		return(err);
 	}
 	
@@ -1968,7 +1981,8 @@ row_upd_in_place_in_select(
 	btr_pcur_t*	pcur;
 	btr_cur_t*	btr_cur;
 	ulint		err;
-	mem_heap_t*	heap;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
 
 	ut_ad(sel_node->select_will_do_update);
 	ut_ad(sel_node->latch_mode == BTR_MODIFY_LEAF);
@@ -1984,11 +1998,13 @@ row_upd_in_place_in_select(
 	/* Copy the necessary columns from clust_rec and calculate the new
 	values to set */
 
-	heap = mem_heap_create(100);
 	row_upd_copy_columns(btr_pcur_get_rec(pcur), rec_get_offsets(
-		btr_pcur_get_rec(pcur), btr_cur->index, ULINT_UNDEFINED, heap),
+			btr_pcur_get_rec(pcur), btr_cur->index, offsets_,
+			ULINT_UNDEFINED, &heap),
 		UT_LIST_GET_FIRST(node->columns));
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	row_upd_eval_new_vals(node->update);
 
 	ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur),
diff --git a/innobase/row/row0vers.c b/innobase/row/row0vers.c
index 5281dbd67d7..9ccaf32f2c2 100644
--- a/innobase/row/row0vers.c
+++ b/innobase/row/row0vers.c
@@ -100,32 +100,25 @@ row_vers_impl_x_locked_off_kernel(
 	}
 
 	heap = mem_heap_create(1024);
-	clust_offsets = rec_get_offsets(clust_rec, clust_index,
-					ULINT_UNDEFINED, heap);
+	clust_offsets = rec_get_offsets(clust_rec, clust_index, NULL,
+					ULINT_UNDEFINED, &heap);
 	trx_id = row_get_rec_trx_id(clust_rec, clust_index, clust_offsets);
 
 	mtr_s_lock(&(purge_sys->latch), &mtr);
 
 	mutex_enter(&kernel_mutex);
 	
+	trx = NULL;
 	if (!trx_is_active(trx_id)) {
 		/* The transaction that modified or inserted clust_rec is no
 		longer active: no implicit lock on rec */
-		
-		mem_heap_free(heap);
-		mtr_commit(&mtr);
-
-		return(NULL);
+		goto exit_func;
 	}
 
 	if (!lock_check_trx_id_sanity(trx_id, clust_rec, clust_index,
 					clust_offsets, TRUE)) {
 		/* Corruption noticed: try to avoid a crash by returning */
-		
-		mem_heap_free(heap);
-		mtr_commit(&mtr);
-
-		return(NULL);
+		goto exit_func;
 	}
 
 	comp = index->table->comp;
@@ -166,7 +159,8 @@ row_vers_impl_x_locked_off_kernel(
 
 		if (prev_version) {
 			clust_offsets = rec_get_offsets(prev_version,
-					clust_index, ULINT_UNDEFINED, heap);
+					clust_index, NULL,
+					ULINT_UNDEFINED, &heap);
 			row = row_build(ROW_COPY_POINTERS, clust_index,
 					prev_version, clust_offsets, heap);
 			entry = row_build_index_entry(row, index, heap);
@@ -250,6 +244,7 @@ row_vers_impl_x_locked_off_kernel(
 		version = prev_version;
 	}/* for (;;) */
 
+exit_func:
 	mtr_commit(&mtr);
 	mem_heap_free(heap);
 
@@ -330,8 +325,8 @@ row_vers_old_has_index_entry(
 	comp = index->table->comp;
 	ut_ad(comp == page_is_comp(buf_frame_align(rec)));
 	heap = mem_heap_create(1024);
-	clust_offsets = rec_get_offsets(rec, clust_index,
-					ULINT_UNDEFINED, heap);
+	clust_offsets = rec_get_offsets(rec, clust_index, NULL,
+					ULINT_UNDEFINED, &heap);
 
 	if (also_curr && !rec_get_deleted_flag(rec, comp)) {
 		row = row_build(ROW_COPY_POINTERS, clust_index,
@@ -371,7 +366,7 @@ row_vers_old_has_index_entry(
 		}
 
 		clust_offsets = rec_get_offsets(prev_version, clust_index,
-						ULINT_UNDEFINED, heap);
+						NULL, ULINT_UNDEFINED, &heap);
 
 		if (!rec_get_deleted_flag(prev_version, comp)) {
 			row = row_build(ROW_COPY_POINTERS, clust_index,
@@ -438,7 +433,7 @@ row_vers_build_for_consistent_read(
 #endif /* UNIV_SYNC_DEBUG */
 
 	heap = mem_heap_create(1024);
-	offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
+	offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
 
 	ut_ad(!read_view_sees_trx_id(view,
 				row_get_rec_trx_id(rec, index, offsets)));
@@ -466,8 +461,8 @@ row_vers_build_for_consistent_read(
 			break;
 		}
 
-		offsets = rec_get_offsets(prev_version, index,
-					ULINT_UNDEFINED, heap);
+		offsets = rec_get_offsets(prev_version, index, NULL,
+					ULINT_UNDEFINED, &heap);
 		prev_trx_id = row_get_rec_trx_id(prev_version, index, offsets);
 
 		if (read_view_sees_trx_id(view, prev_trx_id)) {
diff --git a/innobase/trx/trx0rec.c b/innobase/trx/trx0rec.c
index 484d4f62744..12a0512da53 100644
--- a/innobase/trx/trx0rec.c
+++ b/innobase/trx/trx0rec.c
@@ -1010,8 +1010,9 @@ trx_undo_report_row_operation(
 	ibool		is_insert;
 	trx_rseg_t*	rseg;
 	mtr_t		mtr;
-	mem_heap_t*	heap;
-	ulint*		offsets		= NULL;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[100]	= { 100, };
+	ulint*		offsets		= offsets_;
 
 	ut_a(index->type & DICT_CLUSTERED);
 
@@ -1066,8 +1067,6 @@ trx_undo_report_row_operation(
 	
 	mtr_start(&mtr);
 
-	heap = mem_heap_create(100);
-
 	for (;;) {
 		undo_page = buf_page_get_gen(undo->space, page_no,
 						RW_X_LATCH, undo->guess_page,
@@ -1084,8 +1083,8 @@ trx_undo_report_row_operation(
 							index, clust_entry,
 							&mtr);
 		} else {
-			offsets = rec_reget_offsets(rec, index,
-					offsets, ULINT_UNDEFINED, heap);
+			offsets = rec_get_offsets(rec, index, offsets,
+						ULINT_UNDEFINED, &heap);
 			offset = trx_undo_page_report_modify(undo_page, trx,
 				index, rec, offsets, update, cmpl_info, &mtr);
 		}
@@ -1129,7 +1128,9 @@ trx_undo_report_row_operation(
 
 			mutex_exit(&(trx->undo_mutex));
 			mtr_commit(&mtr);
-			mem_heap_free(heap);
+			if (heap) {
+				mem_heap_free(heap);
+			}
 			return(DB_OUT_OF_FILE_SPACE);
 		}
 	}
@@ -1146,7 +1147,9 @@ trx_undo_report_row_operation(
 
 	*roll_ptr = trx_undo_build_roll_ptr(is_insert, rseg->id, page_no,
 								offset);
-	mem_heap_free(heap);
+	if (heap) {
+		mem_heap_free(heap);
+	}
 	return(DB_SUCCESS);
 }
 
@@ -1266,7 +1269,6 @@ trx_undo_prev_version_build(
 	ibool		dummy_extern;
 	byte*		buf;
 	ulint		err;
-	ulint*		index_offsets	= NULL;
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
 #endif /* UNIV_SYNC_DEBUG */
@@ -1282,12 +1284,10 @@ trx_undo_prev_version_build(
 			"InnoDB: Submit a detailed bug report to"
 			" http://bugs.mysql.com\n"
 			"InnoDB: index record ", index->name);
-		index_offsets = rec_get_offsets(index_rec, index,
-						ULINT_UNDEFINED, heap);
-		rec_print(stderr, index_rec, index_offsets);
+		rec_print(stderr, index_rec, index);
 		fputs("\n"
 			"InnoDB: record version ", stderr);
-		rec_print(stderr, rec, offsets);
+		rec_print_new(stderr, rec, offsets);
 		putc('\n', stderr);
    		return(DB_ERROR);
    	}	
@@ -1353,12 +1353,10 @@ trx_undo_prev_version_build(
 		ut_print_buf(stderr, undo_rec, 150);
 		fputs("\n"
 			"InnoDB: index record ", stderr);
-		index_offsets = rec_get_offsets(index_rec, index,
-						ULINT_UNDEFINED, heap);
-		rec_print(stderr, index_rec, index_offsets);
+		rec_print(stderr, index_rec, index);
 		fputs("\n"
 			"InnoDB: record version ", stderr);
-		rec_print(stderr, rec, offsets);
+		rec_print_new(stderr, rec, offsets);
 		fprintf(stderr, "\n"
 	"InnoDB: Record trx id %lu %lu, update rec trx id %lu %lu\n"
 	"InnoDB: Roll ptr in rec %lu %lu, in update rec %lu %lu\n",
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index dc0ef57e910..fbaa22cff14 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -317,6 +317,7 @@ my_bool STDCALL mysql_master_send_query(MYSQL *mysql, const char *q,
   DBUG_ENTER("mysql_master_send_query");
   if (!master->net.vio && !mysql_real_connect(master,0,0,0,0,0,0,0))
     DBUG_RETURN(1);
+  master->reconnect= 1;
   mysql->last_used_con = master;
   DBUG_RETURN(simple_command(master, COM_QUERY, q, length, 1));
 }
@@ -351,6 +352,7 @@ my_bool STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q,
   if (!slave_to_use->net.vio && !mysql_real_connect(slave_to_use, 0,0,0,
 						    0,0,0,0))
     DBUG_RETURN(1);
+  slave_to_use->reconnect= 1;
   DBUG_RETURN(simple_command(slave_to_use, COM_QUERY, q, length, 1));
 }
 
@@ -448,6 +450,7 @@ static my_bool get_slaves_from_master(MYSQL* mysql)
     expand_error(mysql, CR_PROBE_MASTER_CONNECT);
     DBUG_RETURN(1);
   }
+  mysql->reconnect= 1;
 
   if (mysql_query(mysql, "SHOW SLAVE HOSTS") ||
       !(res = mysql_store_result(mysql)))
@@ -615,6 +618,7 @@ mysql_connect(MYSQL *mysql,const char *host,
       if (mysql->free_me)
 	my_free((gptr) mysql,MYF(0));
     }
+    mysql->reconnect= 1;
     DBUG_RETURN(res);
   }
 }
diff --git a/libmysqld/examples/builder-sample/emb_samples.cpp b/libmysqld/examples/builder-sample/emb_samples.cpp
index 4dfde111f84..411de26149b 100644
--- a/libmysqld/examples/builder-sample/emb_samples.cpp
+++ b/libmysqld/examples/builder-sample/emb_samples.cpp
@@ -109,6 +109,7 @@ bool __fastcall TForm1::connect_server()
    ret_value = true;
    is_server_started = true;
   }
+  MySQL->reconnect= 1;
   return ret_value;
 }
 //---------------------------------------------------------------------------
diff --git a/ndb/test/ndbapi/flex_bench_mysql.cpp b/ndb/test/ndbapi/flex_bench_mysql.cpp
index c8d4d85bedf..ad84390a9e5 100644
--- a/ndb/test/ndbapi/flex_bench_mysql.cpp
+++ b/ndb/test/ndbapi/flex_bench_mysql.cpp
@@ -397,6 +397,7 @@ NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535)
         ndbout << "Connect failed" <<endl;
         returnValue = NDBT_FAILED;
       }
+      mysql.reconnect= 1;
     }
     if(returnValue == NDBT_OK){
       mysql_set_server_option(&mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON);
@@ -712,6 +713,7 @@ static void* flexBenchThread(void* pArg)
       ndbout << "failed" << endl;
       NdbThread_Exit(0) ;
     }
+    mysql.reconnect= 1;
     ndbout << "ok" << endl;
 
     int r;
diff --git a/ndb/tools/restore/consumer_restorem.cpp b/ndb/tools/restore/consumer_restorem.cpp
index 6a9ec07148a..ce1738ea686 100644
--- a/ndb/tools/restore/consumer_restorem.cpp
+++ b/ndb/tools/restore/consumer_restorem.cpp
@@ -80,6 +80,7 @@ BackupRestore::init()
 	ndbout_c("Connect failed: %s", mysql_error(&mysql));
 	returnValue = false;
       }
+      mysql.reconnect= 1;
       ndbout << "Connected to MySQL!!!" <<endl;
     }
 
diff --git a/server-tools/instance-manager/instance.cc b/server-tools/instance-manager/instance.cc
index 2c041e31119..42909a134ac 100644
--- a/server-tools/instance-manager/instance.cc
+++ b/server-tools/instance-manager/instance.cc
@@ -106,6 +106,7 @@ bool Instance::is_running()
                            NullS, port,
                            socket, 0))
     {
+      mysql.reconnect= 1;
       is_connected= TRUE;
       pthread_mutex_unlock(&LOCK_instance);
       return TRUE;
diff --git a/sql-common/client.c b/sql-common/client.c
index aa50b9fe27b..fd65ed01462 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1587,8 +1587,24 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
     port=mysql->options.port;
   if (!unix_socket)
     unix_socket=mysql->options.unix_socket;
+  
+  /*
+    By default we don't reconnect because it could silently corrupt data (after
+    reconnection you potentially lose table locks, user variables, session
+    variables (transactions but they are specifically dealt with in
+    mysql_reconnect()).
+    This is a change: < 5.0.3 mysql->reconnect was set to 1 by default.
+    How this change impacts existing apps:
+    - existing apps which relyed on the default will see a behaviour change;
+    they will have to set reconnect=1 after mysql_real_connect().
+    - existing apps which explicitely asked for reconnection (the only way they
+    could do it was by setting mysql.reconnect to 1 after mysql_real_connect())
+    will not see a behaviour change.
+    - existing apps which explicitely asked for no reconnection
+    (mysql.reconnect=0) will not see a behaviour change.
+  */
+  mysql->reconnect= 0;
 
-  mysql->reconnect=1;				/* Reconnect as default */
   mysql->server_status=SERVER_STATUS_AUTOCOMMIT;
 
   /*
@@ -2161,6 +2177,7 @@ my_bool mysql_reconnect(MYSQL *mysql)
     strmov(mysql->net.sqlstate, tmp_mysql.net.sqlstate);
     DBUG_RETURN(1);
   }
+  tmp_mysql.reconnect= 1;
   tmp_mysql.free_me= mysql->free_me;
   /* Don't free options as these are now used in tmp_mysql */
   bzero((char*) &mysql->options,sizeof(mysql->options));
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index f759be59ffb..b7575f3a44e 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -709,6 +709,7 @@ int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi)
   if (!mysql_real_connect(mysql, mi->host, mi->user, mi->password, 0,
 			mi->port, 0, 0))
     DBUG_RETURN(1);
+  mysql->reconnect= 1;
   DBUG_RETURN(0);
 }
 
diff --git a/sql/slave.cc b/sql/slave.cc
index 1e38d92ebc5..9ddbe7d05de 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -4394,6 +4394,7 @@ replication resumed in log '%s' at position %s", mi->user,
     thd->set_active_vio(mysql->net.vio);
 #endif      
   }
+  mysql->reconnect= 1;
   DBUG_PRINT("exit",("slave_was_killed: %d", slave_was_killed));
   DBUG_RETURN(slave_was_killed);
 }
diff --git a/tests/client_test.c b/tests/client_test.c
index e6a530f786a..979c1563c02 100644
--- a/tests/client_test.c
+++ b/tests/client_test.c
@@ -243,6 +243,7 @@ static void client_connect()
     fprintf(stdout, "\n Check the connection options using --help or -?\n");
     exit(1);
   }
+  mysql->reconnect= 1;
 
   if (!opt_silent)
     fprintf(stdout, " OK");
@@ -1057,6 +1058,7 @@ static my_bool thread_query(char *query)
     error= 1;
     goto end;
   }
+  l_mysql->reconnect= 1;
   if (mysql_query(l_mysql, (char *)query))
   {
      fprintf(stderr, "Query failed (%s)\n", mysql_error(l_mysql));
@@ -4481,6 +4483,7 @@ static void test_stmt_close()
     myerror("connection failed");
     exit(1);
   }
+  lmysql->reconnect= 1;
   if (!opt_silent)
     fprintf(stdout, " OK");
 
@@ -5372,6 +5375,7 @@ DROP TABLE IF EXISTS test_multi_tab";
     fprintf(stdout, "\n connection failed(%s)", mysql_error(mysql_local));
     exit(1);
   }
+  mysql_local->reconnect= 1;
 
   rc= mysql_query(mysql_local, query);
   myquery(rc);
@@ -5480,6 +5484,7 @@ static void test_prepare_multi_statements()
     fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local));
     exit(1);
   }
+  mysql_local->reconnect= 1;
   strmov(query, "select 1; select 'another value'");
   stmt= mysql_simple_prepare(mysql_local, query);
   check_stmt_r(stmt);
@@ -7012,6 +7017,7 @@ static void test_prepare_grant()
       mysql_close(lmysql);
       exit(1);
     }
+    lmysql->reconnect= 1;
     if (!opt_silent)
       fprintf(stdout, " OK");
 
@@ -7457,6 +7463,7 @@ static void test_drop_temp()
       mysql_close(lmysql);
       exit(1);
     }
+    lmysql->reconnect= 1;
     if (!opt_silent)
       fprintf(stdout, " OK");
 
diff --git a/tests/connect_test.c b/tests/connect_test.c
index fd81ad635ad..c68ade9f78f 100644
--- a/tests/connect_test.c
+++ b/tests/connect_test.c
@@ -46,6 +46,7 @@ int main(int argc, char **argv)
     perror("");
     exit(1);
   }
+  sock->reconnect= 1;
 
   if (mysql_select_db(sock,"test"))
   {
diff --git a/tests/deadlock_test.c b/tests/deadlock_test.c
index 65a0df5c215..ab8158e0cd8 100644
--- a/tests/deadlock_test.c
+++ b/tests/deadlock_test.c
@@ -227,6 +227,7 @@ int main()
      !mysql_real_connect(&sel, host, user, pass, db, 0,0,0 ) ||
      !mysql_real_connect(&del_ins, host, user, pass, db, 0,0,0 ))
     die("Error in mysql_real_connect(): %s", mysql_error(&lock));
+  lock.reconnect= sel.reconnect= del_ins.reconnect= 1;
 
   permute(order, num_queries);
   printf("count = %d\n", count);
diff --git a/tests/insert_test.c b/tests/insert_test.c
index 052c12bfdf0..2b659e9eecb 100644
--- a/tests/insert_test.c
+++ b/tests/insert_test.c
@@ -40,6 +40,7 @@ int main(int argc, char **argv)
     perror("");
     exit(1);
   }
+  mysql.reconnect= 1;
 
   num = atoi(argv[2]);
   count = 0;
diff --git a/tests/list_test.c b/tests/list_test.c
index 06bf16d2751..1d50e703133 100644
--- a/tests/list_test.c
+++ b/tests/list_test.c
@@ -43,6 +43,7 @@ int main(int argc, char **argv)
     perror("");
     exit(1);
   }
+  mysql.reconnect= 1;
 
   if (mysql_select_db(sock,argv[1]) < 0)
   {
diff --git a/tests/select_test.c b/tests/select_test.c
index ee2a9192865..64c4fec5167 100644
--- a/tests/select_test.c
+++ b/tests/select_test.c
@@ -44,6 +44,7 @@ int main(int argc, char **argv)
     perror("");
     exit(1);
   }
+  mysql.reconnect= 1;
 
   count = 0;
   num = atoi(argv[2]);
diff --git a/tests/showdb_test.c b/tests/showdb_test.c
index df2b3037c00..08229fc51ee 100644
--- a/tests/showdb_test.c
+++ b/tests/showdb_test.c
@@ -45,6 +45,7 @@ int main(int argc, char **argv)
     perror("");
     exit(1);
   }
+  mysql.reconnect= 1;
 
   count = 0;
   num = atoi(argv[2]);
diff --git a/tests/ssl_test.c b/tests/ssl_test.c
index b18e493c267..85f490cb02e 100644
--- a/tests/ssl_test.c
+++ b/tests/ssl_test.c
@@ -51,6 +51,7 @@ int main(int argc, char **argv)
     perror("");
     exit(1);
   }
+  mysql.reconnect= 1;
   count = 0;
   num = atoi(argv[2]);
   while (count < num)
diff --git a/tests/thread_test.c b/tests/thread_test.c
index 06f335fe1a6..f8577857d0a 100644
--- a/tests/thread_test.c
+++ b/tests/thread_test.c
@@ -55,6 +55,7 @@ unsigned __stdcall test_thread(void *arg __attribute__((unused)))
     perror("");
     goto end;
   }
+  mysql.reconnect= 1;
   if (verbose) { putchar('*'); fflush(stdout); }
   for (count=0 ; count < number_of_tests ; count++)
   {
diff --git a/tools/mysqlmanager.c b/tools/mysqlmanager.c
index bb0a76d6c49..1be0242c505 100644
--- a/tools/mysqlmanager.c
+++ b/tools/mysqlmanager.c
@@ -877,7 +877,10 @@ static void manager_exec_connect(struct manager_exec* e)
   {
     if (mysql_real_connect(&e->mysql,e->con_host,e->con_user,e->con_pass,0,
 			   e->con_port,e->con_sock,0))
+    {
+      e->mysql.reconnect= 1;
       return;
+    }
     sleep(1);
   }
   e->error="Could not connect to MySQL server withing the number of tries";