MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Timothy Smith Date:July 31 2008 9:48pm
Subject:bzr commit into mysql-5.0 branch (timothy.smith:2652) Bug#34286 Bug#35352
Bug#36600
View as plain text  
#At file:///home/tsmith/m/bzr/31jul/ib-5.0-bugteam/

 2652 Timothy Smith	2008-07-31
      Cherry-pick InnoDB fixes for Bug#34286, Bug#35352, and Bug#36600 from snapshot
      innodb-5.0-ss2475.
      
      Bug #34286  Assertion failure in thread 2816 in file .\row\row0sel.c line 3500
      Since autoinc init performs a MySQL SELECT query to determine the auto-inc
      value, set prebuilt->sql_stat_start = TRUE so that it is performed like any
      normal SELECT, regardless of the context in which it was invoked.
      
      
      Bug #35352  If InnoDB crashes with UNDO slots full error the error persists on restart
      We've added a heuristic that checks the size of the UNDO slots cache lists
      (insert and upate). If either of cached lists has more than 500 entries then we
      add any UNDO slots that are freed, to the common free list instead of the cache
      list, this is to avoid the case where all the free slots end up in only one of
      the lists on startup after a crash.
      
      Tested with test case for 26590 and passes all mysql-test(s).
      
      Bug #36600  SHOW STATUS takes a lot of CPU in buf_get_latched_pages_number
      Fixed by removing the Innodb_buffer_pool_pages_latched variable from SHOW
      STATUS output in non-UNIV_DEBUG compilation.
added:
  mysql-test/r/innodb-autoinc-optimize.result
  mysql-test/t/innodb-autoinc-optimize.test
modified:
  innobase/buf/buf0buf.c
  innobase/include/buf0buf.h
  innobase/include/srv0srv.h
  innobase/include/trx0undo.h
  innobase/srv/srv0srv.c
  innobase/trx/trx0trx.c
  innobase/trx/trx0undo.c
  sql/ha_innodb.cc

=== modified file 'innobase/buf/buf0buf.c'
--- a/innobase/buf/buf0buf.c	2007-12-11 00:00:25 +0000
+++ b/innobase/buf/buf0buf.c	2008-07-31 21:47:57 +0000
@@ -2260,6 +2260,7 @@ buf_print(void)
 	ut_a(buf_validate());
 }	
 
+#ifdef UNIV_DEBUG
 /*************************************************************************
 Returns the number of latched pages in the buffer pool. */
 
@@ -2290,6 +2291,7 @@ buf_get_latched_pages_number(void)
         mutex_exit(&(buf_pool->mutex));
         return fixed_pages_number;
 }
+#endif /* UNIV_DEBUG */
 
 /*************************************************************************
 Returns the number of pending buf pool ios. */

=== modified file 'innobase/include/buf0buf.h'
--- a/innobase/include/buf0buf.h	2007-12-11 00:00:25 +0000
+++ b/innobase/include/buf0buf.h	2008-07-31 21:47:57 +0000
@@ -495,7 +495,15 @@ Prints info of the buffer pool data stru
 void
 buf_print(void);
 /*============*/
+
+/*************************************************************************
+Returns the number of latched pages in the buffer pool. */
+
+ulint
+buf_get_latched_pages_number(void);
+/*==============================*/
 #endif /* UNIV_DEBUG */
+
 /************************************************************************
 Prints a page to stderr. */
 
@@ -503,12 +511,7 @@ void
 buf_page_print(
 /*===========*/
 	byte*	read_buf);	/* in: a database page */
-/*************************************************************************
-Returns the number of latched pages in the buffer pool. */
 
-ulint
-buf_get_latched_pages_number(void);
-/*==============================*/
 /*************************************************************************
 Returns the number of pending buf pool ios. */
 

=== modified file 'innobase/include/srv0srv.h'
--- a/innobase/include/srv0srv.h	2006-01-18 12:20:56 +0000
+++ b/innobase/include/srv0srv.h	2008-07-31 21:47:57 +0000
@@ -531,7 +531,9 @@ struct export_var_struct{
         ulint innodb_buffer_pool_pages_dirty;
         ulint innodb_buffer_pool_pages_misc;
         ulint innodb_buffer_pool_pages_free;
+#ifdef UNIV_DEBUG
         ulint innodb_buffer_pool_pages_latched;
+#endif /* UNIV_DEBUG */
         ulint innodb_buffer_pool_read_requests;
         ulint innodb_buffer_pool_reads;
         ulint innodb_buffer_pool_wait_free;

=== modified file 'innobase/include/trx0undo.h'
--- a/innobase/include/trx0undo.h	2005-02-25 20:35:33 +0000
+++ b/innobase/include/trx0undo.h	2008-07-31 21:47:57 +0000
@@ -237,6 +237,7 @@ trx_undo_set_state_at_finish(
 /*=========================*/
 				/* out: undo log segment header page,
 				x-latched */
+	trx_rseg_t*	rseg,	/* in: rollback segment memory object */
 	trx_t*		trx,	/* in: transaction */
 	trx_undo_t*	undo,	/* in: undo log memory copy */
 	mtr_t*		mtr);	/* in: mtr */

=== modified file 'innobase/srv/srv0srv.c'
--- a/innobase/srv/srv0srv.c	2007-11-20 17:53:19 +0000
+++ b/innobase/srv/srv0srv.c	2008-07-31 21:47:57 +0000
@@ -1803,7 +1803,9 @@ srv_export_innodb_status(void)
         export_vars.innodb_buffer_pool_pages_data= UT_LIST_GET_LEN(buf_pool->LRU);
         export_vars.innodb_buffer_pool_pages_dirty= UT_LIST_GET_LEN(buf_pool->flush_list);
         export_vars.innodb_buffer_pool_pages_free= UT_LIST_GET_LEN(buf_pool->free);
+#ifdef UNIV_DEBUG
         export_vars.innodb_buffer_pool_pages_latched= buf_get_latched_pages_number();
+#endif /* UNIV_DEBUG */
         export_vars.innodb_buffer_pool_pages_total= buf_pool->curr_size;
         export_vars.innodb_buffer_pool_pages_misc= buf_pool->max_size -
           UT_LIST_GET_LEN(buf_pool->LRU) - UT_LIST_GET_LEN(buf_pool->free);

=== modified file 'innobase/trx/trx0trx.c'
--- a/innobase/trx/trx0trx.c	2007-08-15 23:20:54 +0000
+++ b/innobase/trx/trx0trx.c	2008-07-31 21:47:57 +0000
@@ -761,8 +761,8 @@ trx_commit_off_kernel(
 		mutex_enter(&(rseg->mutex));
 			
 		if (trx->insert_undo != NULL) {
-			trx_undo_set_state_at_finish(trx, trx->insert_undo,
-									&mtr);
+			trx_undo_set_state_at_finish(
+				rseg, trx, trx->insert_undo, &mtr);
 		}
 
 		undo = trx->update_undo;
@@ -777,8 +777,8 @@ trx_commit_off_kernel(
 			because only a single OS thread is allowed to do the
 			transaction commit for this transaction. */
 					
-			update_hdr_page = trx_undo_set_state_at_finish(trx,
-								undo, &mtr);
+			update_hdr_page = trx_undo_set_state_at_finish(
+				rseg, trx, undo, &mtr);
 
 			/* We have to do the cleanup for the update log while
 			holding the rseg mutex because update log headers

=== modified file 'innobase/trx/trx0undo.c'
--- a/innobase/trx/trx0undo.c	2005-06-21 17:15:22 +0000
+++ b/innobase/trx/trx0undo.c	2008-07-31 21:47:57 +0000
@@ -1724,6 +1724,7 @@ trx_undo_set_state_at_finish(
 /*=========================*/
 				/* out: undo log segment header page,
 				x-latched */
+	trx_rseg_t*	rseg,	/* in: rollback segment memory object */
 	trx_t*		trx __attribute__((unused)), /* in: transaction */
 	trx_undo_t*	undo,	/* in: undo log memory copy */
 	mtr_t*		mtr)	/* in: mtr */
@@ -1732,8 +1733,10 @@ trx_undo_set_state_at_finish(
 	trx_upagef_t*	page_hdr;
 	page_t*		undo_page;
 	ulint		state;
-	
-	ut_ad(trx && undo && mtr);
+
+	ut_ad(trx);
+	ut_ad(undo);
+	ut_ad(mtr);
 
 	if (undo->id >= TRX_RSEG_N_SLOTS) {
 		fprintf(stderr, "InnoDB: Error: undo->id is %lu\n",
@@ -1747,9 +1750,23 @@ trx_undo_set_state_at_finish(
 	seg_hdr = undo_page + TRX_UNDO_SEG_HDR;
 	page_hdr = undo_page + TRX_UNDO_PAGE_HDR;
 
-	if (undo->size == 1 && mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE)
-						< TRX_UNDO_PAGE_REUSE_LIMIT) {
-		state = TRX_UNDO_CACHED;
+	if (undo->size == 1
+	    && mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE)
+	       < TRX_UNDO_PAGE_REUSE_LIMIT) {
+
+		/* This is a heuristic to avoid the problem of all UNDO
+		slots ending up in one of the UNDO lists. Previously if
+		the server crashed with all the slots in one of the lists,
+		transactions that required the slots of a different type
+		would fail for lack of slots. */
+
+		if (UT_LIST_GET_LEN(rseg->update_undo_list) < 500
+		    && UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) {
+
+			state = TRX_UNDO_CACHED;
+		} else {
+			state = TRX_UNDO_TO_FREE;
+		}
 
 	} else if (undo->type == TRX_UNDO_INSERT) {
 
@@ -1759,7 +1776,7 @@ trx_undo_set_state_at_finish(
 	}
 
 	undo->state = state;
-		   
+
 	mlog_write_ulint(seg_hdr + TRX_UNDO_STATE, state, MLOG_2BYTES, mtr);
 
 	return(undo_page);

=== added file 'mysql-test/r/innodb-autoinc-optimize.result'
--- a/mysql-test/r/innodb-autoinc-optimize.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/innodb-autoinc-optimize.result	2008-07-31 21:47:57 +0000
@@ -0,0 +1,6 @@
+drop table if exists t1;
+create table t1(a int not null auto_increment primary key) engine=innodb;
+insert into t1 set a = -1;
+optimize table t1;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	OK

=== added file 'mysql-test/t/innodb-autoinc-optimize.test'
--- a/mysql-test/t/innodb-autoinc-optimize.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/innodb-autoinc-optimize.test	2008-07-31 21:47:57 +0000
@@ -0,0 +1,16 @@
+-- source include/have_innodb.inc
+# embedded server ignores 'delayed', so skip this
+-- source include/not_embedded.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+#
+# Bug 34286
+#
+create table t1(a int not null auto_increment primary key) engine=innodb;
+insert into t1 set a = -1;
+# NOTE: The database needs to be shutdown and restarted (here) for
+# the test to work. It's included for reference only.
+optimize table t1;

=== modified file 'sql/ha_innodb.cc'
--- a/sql/ha_innodb.cc	2008-03-29 07:52:16 +0000
+++ b/sql/ha_innodb.cc	2008-07-31 21:47:57 +0000
@@ -244,8 +244,10 @@ struct show_var_st innodb_status_variabl
   (char*) &export_vars.innodb_buffer_pool_pages_flushed,  SHOW_LONG},
   {"buffer_pool_pages_free",
   (char*) &export_vars.innodb_buffer_pool_pages_free,     SHOW_LONG},
+#ifdef UNIV_DEBUG
   {"buffer_pool_pages_latched",
   (char*) &export_vars.innodb_buffer_pool_pages_latched,  SHOW_LONG},
+#endif /* UNIV_DEBUG */
   {"buffer_pool_pages_misc",
   (char*) &export_vars.innodb_buffer_pool_pages_misc,     SHOW_LONG},
   {"buffer_pool_pages_total",
@@ -4250,7 +4252,7 @@ ha_innobase::rnd_pos(
 	int		error;
 	uint		keynr	= active_index;
 	DBUG_ENTER("rnd_pos");
-	DBUG_DUMP("key", (uchar *)pos, ref_length);
+	DBUG_DUMP("key", (uchar*) pos, ref_length);
 
 	statistic_increment(current_thd->status_var.ha_read_rnd_count,
 			    &LOCK_status);
@@ -6882,6 +6884,12 @@ ha_innobase::innobase_read_and_init_auto
 	from a table when no table has been locked in ::external_lock(). */
 	prebuilt->trx->n_mysql_tables_in_use++;
 
+	/* Since we will perform a MySQL SELECT query to determine the
+	auto-inc value, set prebuilt->sql_stat_start = TRUE so that it
+	is performed like any normal SELECT, regardless of the context
+	we come here. */
+        prebuilt->sql_stat_start = TRUE;
+
 	error = index_last(table->record[1]);
 
 	prebuilt->trx->n_mysql_tables_in_use--;

Thread
bzr commit into mysql-5.0 branch (timothy.smith:2652) Bug#34286 Bug#35352Bug#36600Timothy Smith31 Jul