From 65eed561cb9079cb5ab23752fa7dd86cb12094ab Mon Sep 17 00:00:00 2001
From: Satya B <satya.bn@sun.com>
Date: Thu, 8 Oct 2009 17:48:19 +0530
Subject: [PATCH] Applying InnoDB Plugin 1.0.5 snapshot , part 5

From revision r5733 to r5747

Detailed revision comments:

r5733 | sunny | 2009-09-02 02:05:15 -0500 (Wed, 02 Sep 2009) | 6 lines
branches/zip: Fix a regression introduced by the fix for bug#26316. We check
whether a transaction holds any AUTOINC locks before we acquire the kernel
mutex and release those locks.

Fix for rb://153. Approved by Marko.

r5734 | sunny | 2009-09-02 02:08:45 -0500 (Wed, 02 Sep 2009) | 2 lines
branches/zip: Update ChangeLog with r5733 changes.

r5735 | marko | 2009-09-02 02:43:09 -0500 (Wed, 02 Sep 2009) | 2 lines
branches/zip: univ.i: Do not undefine PACKAGE or VERSION.
InnoDB source code does not refer to these macros.
r5736 | marko | 2009-09-02 02:53:19 -0500 (Wed, 02 Sep 2009) | 1 line
branches/zip: Enclose some timestamp functions in #ifndef UNIV_HOTBACKUP.
r5743 | marko | 2009-09-03 01:36:12 -0500 (Thu, 03 Sep 2009) | 3 lines
branches/zip: log_reserve_and_write_fast(): Remove the redundant
output parameter "success".
Success is also indicated by a nonzero return value.
r5744 | marko | 2009-09-03 03:28:35 -0500 (Thu, 03 Sep 2009) | 1 line
branches/zip: ut_align(): Make ptr const, like in ut_align_down().
r5745 | marko | 2009-09-03 03:38:22 -0500 (Thu, 03 Sep 2009) | 2 lines
branches/zip: log_check_log_recs(): Enclose in #ifdef UNIV_LOG_DEBUG.
Add const qualifiers.
r5746 | marko | 2009-09-03 03:55:36 -0500 (Thu, 03 Sep 2009) | 2 lines
branches/zip: log_reserve_and_write_fast(): Do not cache the log_sys pointer
in a local variable.
r5747 | marko | 2009-09-03 05:46:38 -0500 (Thu, 03 Sep 2009) | 2 lines
branches/zip: recv_scan_log_recs(): Replace while with do...while,
because the termination condition will always hold on the first iteration.
---
 storage/innodb_plugin/ChangeLog           |  8 +++++
 storage/innodb_plugin/include/lock0lock.h |  8 +++++
 storage/innodb_plugin/include/log0log.h   |  5 ++-
 storage/innodb_plugin/include/log0log.ic  | 42 +++++++++++------------
 storage/innodb_plugin/include/row0mysql.h |  4 ++-
 storage/innodb_plugin/include/univ.i      |  9 ++---
 storage/innodb_plugin/include/ut0byte.h   |  4 +--
 storage/innodb_plugin/include/ut0byte.ic  |  4 +--
 storage/innodb_plugin/include/ut0ut.h     |  2 ++
 storage/innodb_plugin/lock/lock0lock.c    | 14 ++++++++
 storage/innodb_plugin/log/log0log.c       |  8 +++--
 storage/innodb_plugin/log/log0recv.c      |  6 ++--
 storage/innodb_plugin/mtr/mtr0mtr.c       |  5 ++-
 storage/innodb_plugin/page/page0zip.c     | 14 ++++++++
 storage/innodb_plugin/row/row0mysql.c     | 12 ++++---
 storage/innodb_plugin/ut/ut0ut.c          |  2 ++
 16 files changed, 98 insertions(+), 49 deletions(-)

diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog
index df71a1c25a5..15d951cb5d1 100644
--- a/storage/innodb_plugin/ChangeLog
+++ b/storage/innodb_plugin/ChangeLog
@@ -1,3 +1,11 @@
+2009-09-02	The InnoDB Team
+
+	* include/lock0lock.h, include/row0mysql.h, lock/lock0lock.c,
+	row/row0mysql.c:
+	Fix a regression introduced by the fix for MySQL bug#26316. We check
+	whether a transaction holds any AUTOINC locks before we acquire
+       	the kernel mutex and release those locks.
+
 2009-08-27	The InnoDB Team
 
 	* dict/dict0dict.c, include/dict0dict.h,
diff --git a/storage/innodb_plugin/include/lock0lock.h b/storage/innodb_plugin/include/lock0lock.h
index fa5db831d4f..aeabe39e1a9 100644
--- a/storage/innodb_plugin/include/lock0lock.h
+++ b/storage/innodb_plugin/include/lock0lock.h
@@ -630,6 +630,14 @@ lock_number_of_rows_locked(
 /*=======================*/
 	trx_t*	trx);	/*!< in: transaction */
 /*******************************************************************//**
+Check if a transaction holds any autoinc locks.
+@return TRUE if the transaction holds any AUTOINC locks. */
+UNIV_INTERN
+ibool
+lock_trx_holds_autoinc_locks(
+/*=========================*/
+	const trx_t*	trx);		/*!< in: transaction */
+/*******************************************************************//**
 Release all the transaction's autoinc locks. */
 UNIV_INTERN
 void
diff --git a/storage/innodb_plugin/include/log0log.h b/storage/innodb_plugin/include/log0log.h
index 5897067798d..299b4a05b40 100644
--- a/storage/innodb_plugin/include/log0log.h
+++ b/storage/innodb_plugin/include/log0log.h
@@ -118,10 +118,9 @@ UNIV_INLINE
 ib_uint64_t
 log_reserve_and_write_fast(
 /*=======================*/
-	byte*		str,	/*!< in: string */
+	const void*	str,	/*!< in: string */
 	ulint		len,	/*!< in: string length */
-	ib_uint64_t*	start_lsn,/*!< out: start lsn of the log record */
-	ibool*		success);/*!< out: TRUE if success */
+	ib_uint64_t*	start_lsn);/*!< out: start lsn of the log record */
 /***********************************************************************//**
 Releases the log mutex. */
 UNIV_INLINE
diff --git a/storage/innodb_plugin/include/log0log.ic b/storage/innodb_plugin/include/log0log.ic
index d071985982a..4d2f64af695 100644
--- a/storage/innodb_plugin/include/log0log.ic
+++ b/storage/innodb_plugin/include/log0log.ic
@@ -27,6 +27,7 @@ Created 12/9/1995 Heikki Tuuri
 #include "mach0data.h"
 #include "mtr0mtr.h"
 
+#ifdef UNIV_LOG_DEBUG
 /******************************************************//**
 Checks by parsing that the catenated log segment for a single mtr is
 consistent. */
@@ -34,11 +35,12 @@ UNIV_INTERN
 ibool
 log_check_log_recs(
 /*===============*/
-	byte*		buf,		/*!< in: pointer to the start of
+	const byte*	buf,		/*!< in: pointer to the start of
 					the log segment in the
 					log_sys->buf log buffer */
 	ulint		len,		/*!< in: segment length in bytes */
 	ib_uint64_t	buf_start_lsn);	/*!< in: buffer start lsn */
+#endif /* UNIV_LOG_DEBUG */
 
 /************************************************************//**
 Gets a log block flush bit.
@@ -305,53 +307,49 @@ UNIV_INLINE
 ib_uint64_t
 log_reserve_and_write_fast(
 /*=======================*/
-	byte*		str,	/*!< in: string */
+	const void*	str,	/*!< in: string */
 	ulint		len,	/*!< in: string length */
-	ib_uint64_t*	start_lsn,/*!< out: start lsn of the log record */
-	ibool*		success)/*!< out: TRUE if success */
+	ib_uint64_t*	start_lsn)/*!< out: start lsn of the log record */
 {
-	log_t*		log	= log_sys;
 	ulint		data_len;
 	ib_uint64_t	lsn;
 
-	*success = TRUE;
-
-	mutex_enter(&(log->mutex));
+	mutex_enter(&log_sys->mutex);
 
-	data_len = len + log->buf_free % OS_FILE_LOG_BLOCK_SIZE;
+	data_len = len + log_sys->buf_free % OS_FILE_LOG_BLOCK_SIZE;
 
 	if (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
 
 		/* The string does not fit within the current log block
 		or the log block would become full */
 
-		*success = FALSE;
-
-		mutex_exit(&(log->mutex));
+		mutex_exit(&log_sys->mutex);
 
 		return(0);
 	}
 
-	*start_lsn = log->lsn;
+	*start_lsn = log_sys->lsn;
 
-	ut_memcpy(log->buf + log->buf_free, str, len);
+	ut_memcpy(log_sys->buf + log_sys->buf_free, str, len);
 
-	log_block_set_data_len((byte*) ut_align_down(log->buf + log->buf_free,
+	log_block_set_data_len((byte*) ut_align_down(log_sys->buf
+						     + log_sys->buf_free,
 						     OS_FILE_LOG_BLOCK_SIZE),
 			       data_len);
 #ifdef UNIV_LOG_DEBUG
-	log->old_buf_free = log->buf_free;
-	log->old_lsn = log->lsn;
+	log_sys->old_buf_free = log_sys->buf_free;
+	log_sys->old_lsn = log_sys->lsn;
 #endif
-	log->buf_free += len;
+	log_sys->buf_free += len;
 
-	ut_ad(log->buf_free <= log->buf_size);
+	ut_ad(log_sys->buf_free <= log_sys->buf_size);
 
-	lsn = log->lsn += len;
+	lsn = log_sys->lsn += len;
 
 #ifdef UNIV_LOG_DEBUG
-	log_check_log_recs(log->buf + log->old_buf_free,
-			   log->buf_free - log->old_buf_free, log->old_lsn);
+	log_check_log_recs(log_sys->buf + log_sys->old_buf_free,
+			   log_sys->buf_free - log_sys->old_buf_free,
+			   log_sys->old_lsn);
 #endif
 	return(lsn);
 }
diff --git a/storage/innodb_plugin/include/row0mysql.h b/storage/innodb_plugin/include/row0mysql.h
index 97028622505..6d5d195172e 100644
--- a/storage/innodb_plugin/include/row0mysql.h
+++ b/storage/innodb_plugin/include/row0mysql.h
@@ -177,7 +177,9 @@ row_update_prebuilt_trx(
 					in MySQL handle */
 	trx_t*		trx);		/*!< in: transaction handle */
 /*********************************************************************//**
-Unlocks AUTO_INC type locks that were possibly reserved by a trx. */
+Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
+function should be called at the the end of an SQL statement, by the
+connection thread that owns the transaction (trx->mysql_thd). */
 UNIV_INTERN
 void
 row_unlock_table_autoinc_for_mysql(
diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i
index 66240d96a11..815c9ffcee0 100644
--- a/storage/innodb_plugin/include/univ.i
+++ b/storage/innodb_plugin/include/univ.i
@@ -111,14 +111,11 @@ if we are compiling on Windows. */
 #  include <sys/mman.h> /* mmap() for os0proc.c */
 # endif
 
-# undef PACKAGE
-# undef VERSION
-
 /* Include the header file generated by GNU autoconf */
 # ifndef __WIN__
-#ifndef UNIV_HOTBACKUP
-# include "config.h"
-#endif /* UNIV_HOTBACKUP */
+#  ifndef UNIV_HOTBACKUP
+#   include "config.h"
+#  endif /* UNIV_HOTBACKUP */
 # endif
 
 # ifdef HAVE_SCHED_H
diff --git a/storage/innodb_plugin/include/ut0byte.h b/storage/innodb_plugin/include/ut0byte.h
index a2687e62f08..f55e2888c60 100644
--- a/storage/innodb_plugin/include/ut0byte.h
+++ b/storage/innodb_plugin/include/ut0byte.h
@@ -219,8 +219,8 @@ UNIV_INLINE
 void*
 ut_align(
 /*=====*/
-	void*	ptr,		/*!< in: pointer */
-	ulint	align_no);	/*!< in: align by this number */
+	const void*	ptr,		/*!< in: pointer */
+	ulint		align_no);	/*!< in: align by this number */
 /*********************************************************//**
 The following function rounds down a pointer to the nearest
 aligned address.
diff --git a/storage/innodb_plugin/include/ut0byte.ic b/storage/innodb_plugin/include/ut0byte.ic
index e3beed65138..3dd51890cb4 100644
--- a/storage/innodb_plugin/include/ut0byte.ic
+++ b/storage/innodb_plugin/include/ut0byte.ic
@@ -319,8 +319,8 @@ UNIV_INLINE
 void*
 ut_align(
 /*=====*/
-	void*	ptr,		/*!< in: pointer */
-	ulint	align_no)	/*!< in: align by this number */
+	const void*	ptr,		/*!< in: pointer */
+	ulint		align_no)	/*!< in: align by this number */
 {
 	ut_ad(align_no > 0);
 	ut_ad(((align_no - 1) & align_no) == 0);
diff --git a/storage/innodb_plugin/include/ut0ut.h b/storage/innodb_plugin/include/ut0ut.h
index 12c1cd59166..94a93dff6c7 100644
--- a/storage/innodb_plugin/include/ut0ut.h
+++ b/storage/innodb_plugin/include/ut0ut.h
@@ -216,6 +216,7 @@ UNIV_INTERN
 ib_time_t
 ut_time(void);
 /*=========*/
+#ifndef UNIV_HOTBACKUP
 /**********************************************************//**
 Returns system time.
 Upon successful completion, the value 0 is returned; otherwise the
@@ -248,6 +249,7 @@ UNIV_INTERN
 uint
 ut_time_ms(void);
 /*============*/
+#endif /* !UNIV_HOTBACKUP */
 
 /**********************************************************//**
 Returns the difference of two times in seconds.
diff --git a/storage/innodb_plugin/lock/lock0lock.c b/storage/innodb_plugin/lock/lock0lock.c
index 41805b58e0b..20d444af3f4 100644
--- a/storage/innodb_plugin/lock/lock0lock.c
+++ b/storage/innodb_plugin/lock/lock0lock.c
@@ -5371,6 +5371,20 @@ lock_release_autoinc_last_lock(
 	lock_table_dequeue(lock);
 }
 
+/*******************************************************************//**
+Check if a transaction holds any autoinc locks. 
+@return TRUE if the transaction holds any AUTOINC locks. */
+UNIV_INTERN
+ibool
+lock_trx_holds_autoinc_locks(
+/*=========================*/
+	const trx_t*	trx)		/*!< in: transaction */
+{
+	ut_a(trx->autoinc_locks != NULL);
+
+	return(!ib_vector_is_empty(trx->autoinc_locks));
+}
+
 /*******************************************************************//**
 Release all the transaction's autoinc locks. */
 UNIV_INTERN
diff --git a/storage/innodb_plugin/log/log0log.c b/storage/innodb_plugin/log/log0log.c
index f67a1067301..85de72bb768 100644
--- a/storage/innodb_plugin/log/log0log.c
+++ b/storage/innodb_plugin/log/log0log.c
@@ -3234,6 +3234,7 @@ logs_empty_and_mark_files_at_shutdown(void)
 	ut_a(lsn == log_sys->lsn);
 }
 
+#ifdef UNIV_LOG_DEBUG
 /******************************************************//**
 Checks by parsing that the catenated log segment for a single mtr is
 consistent. */
@@ -3241,7 +3242,7 @@ UNIV_INTERN
 ibool
 log_check_log_recs(
 /*===============*/
-	byte*		buf,		/*!< in: pointer to the start of
+	const byte*	buf,		/*!< in: pointer to the start of
 					the log segment in the
 					log_sys->buf log buffer */
 	ulint		len,		/*!< in: segment length in bytes */
@@ -3249,8 +3250,8 @@ log_check_log_recs(
 {
 	ib_uint64_t	contiguous_lsn;
 	ib_uint64_t	scanned_lsn;
-	byte*		start;
-	byte*		end;
+	const byte*	start;
+	const byte*	end;
 	byte*		buf1;
 	byte*		scan_buf;
 
@@ -3283,6 +3284,7 @@ log_check_log_recs(
 
 	return(TRUE);
 }
+#endif /* UNIV_LOG_DEBUG */
 
 /******************************************************//**
 Peeks the current lsn.
diff --git a/storage/innodb_plugin/log/log0recv.c b/storage/innodb_plugin/log/log0recv.c
index aea29c78517..3b40925f079 100644
--- a/storage/innodb_plugin/log/log0recv.c
+++ b/storage/innodb_plugin/log/log0recv.c
@@ -2415,8 +2415,7 @@ recv_scan_log_recs(
 	scanned_lsn = start_lsn;
 	more_data = FALSE;
 
-	while (log_block < buf + len && !finished) {
-
+	do {
 		no = log_block_get_hdr_no(log_block);
 		/*
 		fprintf(stderr, "Log block header no %lu\n", no);
@@ -2546,10 +2545,11 @@ recv_scan_log_recs(
 			/* Log data for this group ends here */
 
 			finished = TRUE;
+			break;
 		} else {
 			log_block += OS_FILE_LOG_BLOCK_SIZE;
 		}
-	}
+	} while (log_block < buf + len && !finished);
 
 	*group_scanned_lsn = scanned_lsn;
 
diff --git a/storage/innodb_plugin/mtr/mtr0mtr.c b/storage/innodb_plugin/mtr/mtr0mtr.c
index be31c5df801..0c4bec8c82c 100644
--- a/storage/innodb_plugin/mtr/mtr0mtr.c
+++ b/storage/innodb_plugin/mtr/mtr0mtr.c
@@ -115,7 +115,6 @@ mtr_log_reserve_and_write(
 	dyn_array_t*	mlog;
 	dyn_block_t*	block;
 	ulint		data_size;
-	ibool		success;
 	byte*		first_data;
 
 	ut_ad(mtr);
@@ -134,8 +133,8 @@ mtr_log_reserve_and_write(
 	if (mlog->heap == NULL) {
 		mtr->end_lsn = log_reserve_and_write_fast(
 			first_data, dyn_block_get_used(mlog),
-			&(mtr->start_lsn), &success);
-		if (success) {
+			&mtr->start_lsn);
+		if (mtr->end_lsn) {
 
 			return;
 		}
diff --git a/storage/innodb_plugin/page/page0zip.c b/storage/innodb_plugin/page/page0zip.c
index 92ba0ec768a..e170adce30a 100644
--- a/storage/innodb_plugin/page/page0zip.c
+++ b/storage/innodb_plugin/page/page0zip.c
@@ -47,8 +47,10 @@ Created June 2005 by Marko Makela
 # define buf_LRU_stat_inc_unzip()			((void) 0)
 #endif /* !UNIV_HOTBACKUP */
 
+#ifndef UNIV_HOTBACKUP
 /** Statistics on compression, indexed by page_zip_des_t::ssize - 1 */
 UNIV_INTERN page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE - 1];
+#endif /* !UNIV_HOTBACKUP */
 
 /* Please refer to ../include/page0zip.ic for a description of the
 compressed page format. */
@@ -1144,7 +1146,9 @@ page_zip_compress(
 	ulint*		offsets	= NULL;
 	ulint		n_blobs	= 0;
 	byte*		storage;/* storage of uncompressed columns */
+#ifndef UNIV_HOTBACKUP
 	ullint		usec = ut_time_us(NULL);
+#endif /* !UNIV_HOTBACKUP */
 #ifdef PAGE_ZIP_COMPRESS_DBG
 	FILE*		logfile = NULL;
 #endif
@@ -1208,7 +1212,9 @@ page_zip_compress(
 		}
 	}
 #endif /* PAGE_ZIP_COMPRESS_DBG */
+#ifndef UNIV_HOTBACKUP
 	page_zip_stat[page_zip->ssize - 1].compressed++;
+#endif /* !UNIV_HOTBACKUP */
 
 	if (UNIV_UNLIKELY(n_dense * PAGE_ZIP_DIR_SLOT_SIZE
 			  >= page_zip_get_size(page_zip))) {
@@ -1345,8 +1351,10 @@ page_zip_compress(
 			fclose(logfile);
 		}
 #endif /* PAGE_ZIP_COMPRESS_DBG */
+#ifndef UNIV_HOTBACKUP
 		page_zip_stat[page_zip->ssize - 1].compressed_usec
 			+= ut_time_us(NULL) - usec;
+#endif /* !UNIV_HOTBACKUP */
 		return(FALSE);
 	}
 
@@ -1404,12 +1412,14 @@ page_zip_compress(
 		fclose(logfile);
 	}
 #endif /* PAGE_ZIP_COMPRESS_DBG */
+#ifndef UNIV_HOTBACKUP
 	{
 		page_zip_stat_t*	zip_stat
 			= &page_zip_stat[page_zip->ssize - 1];
 		zip_stat->compressed_ok++;
 		zip_stat->compressed_usec += ut_time_us(NULL) - usec;
 	}
+#endif /* !UNIV_HOTBACKUP */
 
 	return(TRUE);
 }
@@ -2820,7 +2830,9 @@ page_zip_decompress(
 	ulint		trx_id_col = ULINT_UNDEFINED;
 	mem_heap_t*	heap;
 	ulint*		offsets;
+#ifndef UNIV_HOTBACKUP
 	ullint		usec = ut_time_us(NULL);
+#endif /* !UNIV_HOTBACKUP */
 
 	ut_ad(page_zip_simple_validate(page_zip));
 	UNIV_MEM_ASSERT_W(page, UNIV_PAGE_SIZE);
@@ -2976,12 +2988,14 @@ page_zip_decompress(
 
 	page_zip_fields_free(index);
 	mem_heap_free(heap);
+#ifndef UNIV_HOTBACKUP
 	{
 		page_zip_stat_t*	zip_stat
 			= &page_zip_stat[page_zip->ssize - 1];
 		zip_stat->decompressed++;
 		zip_stat->decompressed_usec += ut_time_us(NULL) - usec;
 	}
+#endif /* !UNIV_HOTBACKUP */
 
 	/* Update the stat counter for LRU policy. */
 	buf_LRU_stat_inc_unzip();
diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c
index 8d80d73f0c7..5fd57efa00c 100644
--- a/storage/innodb_plugin/row/row0mysql.c
+++ b/storage/innodb_plugin/row/row0mysql.c
@@ -866,18 +866,22 @@ row_update_statistics_if_needed(
 }
 
 /*********************************************************************//**
-Unlocks AUTO_INC type locks that were possibly reserved by a trx. */
+Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
+function should be called at the the end of an SQL statement, by the
+connection thread that owns the transaction (trx->mysql_thd). */
 UNIV_INTERN
 void
 row_unlock_table_autoinc_for_mysql(
 /*===============================*/
 	trx_t*	trx)	/*!< in/out: transaction */
 {
-	mutex_enter(&kernel_mutex);
+	if (lock_trx_holds_autoinc_locks(trx)) {
+		mutex_enter(&kernel_mutex);
 
-	lock_release_autoinc_locks(trx);
+		lock_release_autoinc_locks(trx);
 
-	mutex_exit(&kernel_mutex);
+		mutex_exit(&kernel_mutex);
+	}
 }
 
 /*********************************************************************//**
diff --git a/storage/innodb_plugin/ut/ut0ut.c b/storage/innodb_plugin/ut/ut0ut.c
index a01a0470938..5857c9bdef4 100644
--- a/storage/innodb_plugin/ut/ut0ut.c
+++ b/storage/innodb_plugin/ut/ut0ut.c
@@ -132,6 +132,7 @@ ut_time(void)
 	return(time(NULL));
 }
 
+#ifndef UNIV_HOTBACKUP
 /**********************************************************//**
 Returns system time.
 Upon successful completion, the value 0 is returned; otherwise the
@@ -215,6 +216,7 @@ ut_time_ms(void)
 
 	return((uint) tv.tv_sec * 1000 + tv.tv_usec / 1000);
 }
+#endif /* !UNIV_HOTBACKUP */
 
 /**********************************************************//**
 Returns the difference of two times in seconds.
-- 
2.30.9