List:Commits« Previous MessageNext Message »
From:marko.makela Date:May 31 2012 6:23pm
Subject:bzr push into mysql-trunk-wl6255 branch (marko.makela:3919 to 3920)
View as plain text  
 3920 Marko Mäkelä	2012-05-31
      Fix race condition in InnoDB transaction commit flushing.
      
      trx_flush_log_if_needed_low(), trx_flush_log_if_needed():
      Refactored common code. Read srv_flush_log_at_trx_commit only once.
      Previously, a race condition could occur if srv_flush_log_at_trx_commit
      changed during the checks.
      
      trx_commit(), trx_prepare(), trx_commit_complete_for_mysql():
      Invoke trx_flush_log_if_needed() instead of duplicating the code.

    modified:
      storage/innobase/include/trx0trx.h
      storage/innobase/trx/trx0trx.cc
 3919 Marko Mäkelä	2012-05-31
      WL#6255: Fix a bug that affected ROW_FORMAT conversions
      of tables that contain fulltext indexes.
      
      innobase_create_key_defs(): Test for "rebuild" instead of "new_primary".

    modified:
      storage/innobase/handler/handler0alter.cc
=== modified file 'storage/innobase/include/trx0trx.h'
--- a/storage/innobase/include/trx0trx.h	revid:marko.makela@strippedlwqw7qhym51maf
+++ b/storage/innobase/include/trx0trx.h	revid:marko.makela@strippedl6a
@@ -224,13 +224,13 @@ trx_get_trx_by_xid(
 	const XID*	xid);	/*!< in: X/Open XA transaction identifier */
 /**********************************************************************//**
 If required, flushes the log to disk if we called trx_commit_for_mysql()
-with trx->flush_log_later == TRUE.
-@return	0 or error number */
+with trx->flush_log_later == TRUE. */
 UNIV_INTERN
-ulint
+void
 trx_commit_complete_for_mysql(
 /*==========================*/
-	trx_t*	trx);	/*!< in: trx handle */
+	trx_t*	trx)	/*!< in/out: transaction */
+	__attribute__((nonnull));
 /**********************************************************************//**
 Marks the latest SQL statement ended. */
 UNIV_INTERN

=== modified file 'storage/innobase/trx/trx0trx.cc'
--- a/storage/innobase/trx/trx0trx.cc	revid:marko.makela@stripped
+++ b/storage/innobase/trx/trx0trx.cc	revid:marko.makela@oracle.com-20120531182212-u1l372oy77ggvl6a
@@ -987,6 +987,51 @@ trx_finalize_for_fts(
 	trx->fts_trx = NULL;
 }
 
+/**********************************************************************//**
+If required, flushes the log to disk based on the value of
+innodb_flush_log_at_trx_commit. */
+static __attribute__((nonnull))
+void
+trx_flush_log_if_needed_low(
+/*========================*/
+	lsn_t	lsn)	/*!< in: lsn up to which logs are to be
+			flushed. */
+{
+	switch (srv_flush_log_at_trx_commit) {
+	case 0:
+		/* Do nothing */
+		break;
+	case 1:
+		/* Write the log and optionally flush it to disk */
+		log_write_up_to(lsn, LOG_WAIT_ONE_GROUP,
+				srv_unix_file_flush_method != SRV_UNIX_NOSYNC);
+		break;
+	case 2:
+		/* Write the log but do not flush it to disk */
+		log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
+
+		break;
+	default:
+		ut_error;
+	}
+}
+
+/**********************************************************************//**
+If required, flushes the log to disk based on the value of
+innodb_flush_log_at_trx_commit. */
+static __attribute__((nonnull))
+void
+trx_flush_log_if_needed(
+/*====================*/
+	lsn_t	lsn,	/*!< in: lsn up to which logs are to be
+			flushed. */
+	trx_t*	trx)	/*!< in/out: transaction */
+{
+	trx->op_info = "flushing log";
+	trx_flush_log_if_needed_low(lsn);
+	trx->op_info = "";
+}
+
 /****************************************************************//**
 Commits a transaction. */
 UNIV_INTERN
@@ -1151,25 +1196,8 @@ trx_commit(
 			   || thd_requested_durability(trx->mysql_thd)
 			   == HA_IGNORE_DURABILITY) {
 			/* Do nothing */
-		} else if (srv_flush_log_at_trx_commit == 1) {
-			if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
-				/* Write the log but do not flush it to disk */
-
-				log_write_up_to(lsn, LOG_WAIT_ONE_GROUP,
-						FALSE);
-			} else {
-				/* Write the log to the log files AND flush
-				them to disk */
-
-				log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
-			}
-		} else if (srv_flush_log_at_trx_commit == 2) {
-
-			/* Write the log but do not flush it to disk */
-
-			log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
 		} else {
-			ut_error;
+			trx_flush_log_if_needed(lsn, trx);
 		}
 
 		trx->commit_lsn = lsn;
@@ -1430,63 +1458,24 @@ trx_commit_for_mysql(
 
 /**********************************************************************//**
 If required, flushes the log to disk if we called trx_commit_for_mysql()
-with trx->flush_log_later == TRUE.
-@return	0 or error number */
+with trx->flush_log_later == TRUE. */
 UNIV_INTERN
-ulint
+void
 trx_commit_complete_for_mysql(
 /*==========================*/
-	trx_t*	trx)	/*!< in: trx handle */
+	trx_t*	trx)	/*!< in/out: transaction */
 {
-	lsn_t	lsn	= trx->commit_lsn;
-
 	ut_a(trx);
 
-	if (!trx->must_flush_log_later) {
-		return(0);
+	if (!trx->must_flush_log_later
+	    || thd_requested_durability(trx->mysql_thd)
+	       == HA_IGNORE_DURABILITY) {
+		return;
 	}
 
-	trx->op_info = "flushing log";
-
-	switch (srv_flush_log_at_trx_commit) {
-	case 0:
-		/* Do nothing */
-		break;
-	case 1:
-		if (thd_requested_durability(trx->mysql_thd)
-		    == HA_IGNORE_DURABILITY) {
-			break;
-		}
-
-		if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
-			/* Write the log but do not flush it to disk */
-
-			log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
-		} else {
-			/* Write the log to the log files AND flush them to
-			disk */
-
-			log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
-		}
-
-		break;
-	case 2:
-		if (thd_requested_durability(trx->mysql_thd)
-		    == HA_IGNORE_DURABILITY) {
-			break;
-		}
-
-		/* Write the log but do not flush it to disk */
-		log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
-	default:
-		ut_error;
-	}
+	trx_flush_log_if_needed(trx->commit_lsn, trx);
 
 	trx->must_flush_log_later = FALSE;
-
-	trx->op_info = "";
-
-	return(0);
 }
 
 /**********************************************************************//**
@@ -1859,28 +1848,7 @@ trx_prepare(
 		TODO: find out if MySQL holds some mutex when calling this.
 		That would spoil our group prepare algorithm. */
 
-		if (srv_flush_log_at_trx_commit == 0) {
-			/* Do nothing */
-		} else if (srv_flush_log_at_trx_commit == 1) {
-			if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
-				/* Write the log but do not flush it to disk */
-
-				log_write_up_to(lsn, LOG_WAIT_ONE_GROUP,
-						FALSE);
-			} else {
-				/* Write the log to the log files AND flush
-				them to disk */
-
-				log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);
-			}
-		} else if (srv_flush_log_at_trx_commit == 2) {
-
-			/* Write the log but do not flush it to disk */
-
-			log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE);
-		} else {
-			ut_error;
-		}
+		trx_flush_log_if_needed(lsn, trx);
 	}
 }
 

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk-wl6255 branch (marko.makela:3919 to 3920) marko.makela31 May