List:Commits« Previous MessageNext Message »
From:marko.makela Date:September 24 2012 12:02pm
Subject:bzr push into mysql-5.6-wl6494 branch (marko.makela:4307 to 4309) WL#6494
View as plain text  
 4309 Marko Mäkelä	2012-09-24
      WL#6494 crash injection for server startup (innodb_force_recovery_crash)
      
      RECOVERY_CRASH(x): A macro for crashing the server if
      innodb_force_recovery_crash is set to a particular value.
      
      create_log_files(), create_log_files_rename(),
      innobase_start_or_create_for_mysql(): Add RECOVERY_CRASH() injection.

    added:
      mysql-test/suite/sys_vars/r/innodb_force_recovery_crash_basic.result
      mysql-test/suite/sys_vars/t/innodb_force_recovery_crash_basic.test
    modified:
      storage/innobase/handler/ha_innodb.cc
      storage/innobase/include/srv0srv.h
      storage/innobase/srv/srv0srv.cc
      storage/innobase/srv/srv0start.cc
 4308 Marko Mäkelä	2012-09-24
      WL#6494 fault tolerance improvements
      
      fil_close_log_files(): Add a parameter to specify whether the file
      space objects should be freed as well.
      
      INIT_LOG_FILE0: Initial number of the first redo log file.
      
      create_log_files(): New function, for creating the redo log files.
      Delete any log files first, and create a log checkpoint after
      creating the files.
      
      create_log_files_rename(): New function, for renaming the first redo
      log file after everything has been set up. At database creation, the
      database will be unrecoverable until we have initialized the system
      pages. This is why the renaming has to be separate from
      create_log_files().
      
      innobase_start_or_create_for_mysql(): Create the first log file as
      ib_logfile100 and only rename it to ib_logfile0 when done. In this
      way, a subsequent restart of the server should simply create all log
      files from the scratch.

    modified:
      storage/innobase/fil/fil0fil.cc
      storage/innobase/include/fil0fil.h
      storage/innobase/srv/srv0start.cc
 4307 Marko Mäkelä	2012-09-21
      WL#6494 error log cleanup:
      create_log_file(): Use ib_logf() for diagnostics.

    modified:
      storage/innobase/srv/srv0start.cc
=== added file 'mysql-test/suite/sys_vars/r/innodb_force_recovery_crash_basic.result'
--- a/mysql-test/suite/sys_vars/r/innodb_force_recovery_crash_basic.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/innodb_force_recovery_crash_basic.result	revid:marko.makela@strippedom-20120924120023-gqkwar10njnm9rir
@@ -0,0 +1,33 @@
+select @@global.innodb_force_recovery_crash in (0, 1);
+@@global.innodb_force_recovery_crash in (0, 1)
+1
+select @@global.innodb_force_recovery_crash;
+@@global.innodb_force_recovery_crash
+0
+select @@session.innodb_force_recovery_crash;
+ERROR HY000: Variable 'innodb_force_recovery_crash' is a GLOBAL variable
+show global variables like 'innodb_force_recovery_crash';
+Variable_name	Value
+innodb_force_recovery_crash	0
+show session variables like 'innodb_force_recovery_crash';
+Variable_name	Value
+innodb_force_recovery_crash	0
+select * from information_schema.global_variables where variable_name='innodb_force_recovery_crash';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_FORCE_RECOVERY_CRASH	0
+select * from information_schema.session_variables where variable_name='innodb_force_recovery_crash';
+VARIABLE_NAME	VARIABLE_VALUE
+INNODB_FORCE_RECOVERY_CRASH	0
+set global innodb_force_recovery_crash=1;
+ERROR HY000: Variable 'innodb_force_recovery_crash' is a read only variable
+set global innodb_force_recovery_crash=0;
+ERROR HY000: Variable 'innodb_force_recovery_crash' is a read only variable
+select @@global.innodb_force_recovery_crash;
+@@global.innodb_force_recovery_crash
+0
+set session innodb_force_recovery_crash='some';
+ERROR HY000: Variable 'innodb_force_recovery_crash' is a read only variable
+set @@session.innodb_force_recovery_crash='some';
+ERROR HY000: Variable 'innodb_force_recovery_crash' is a read only variable
+set global innodb_force_recovery_crash='some';
+ERROR HY000: Variable 'innodb_force_recovery_crash' is a read only variable

=== added file 'mysql-test/suite/sys_vars/t/innodb_force_recovery_crash_basic.test'
--- a/mysql-test/suite/sys_vars/t/innodb_force_recovery_crash_basic.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/innodb_force_recovery_crash_basic.test	revid:marko.makela@strippedrir
@@ -0,0 +1,28 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+
+#
+# exists as global only
+#
+select @@global.innodb_force_recovery_crash in (0, 1);
+select @@global.innodb_force_recovery_crash;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.innodb_force_recovery_crash;
+show global variables like 'innodb_force_recovery_crash';
+show session variables like 'innodb_force_recovery_crash';
+select * from information_schema.global_variables where variable_name='innodb_force_recovery_crash';
+select * from information_schema.session_variables where variable_name='innodb_force_recovery_crash';
+
+# show that it's read-only
+#
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set global innodb_force_recovery_crash=1;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set global innodb_force_recovery_crash=0;
+select @@global.innodb_force_recovery_crash;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set session innodb_force_recovery_crash='some';
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set @@session.innodb_force_recovery_crash='some';
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set global innodb_force_recovery_crash='some';

=== modified file 'storage/innobase/fil/fil0fil.cc'
--- a/storage/innobase/fil/fil0fil.cc	revid:marko.makela@oracle.com-20120921105209-game83cudrr8cq27
+++ b/storage/innobase/fil/fil0fil.cc	revid:marko.makela@stripped24120023-gqkwar10njnm9rir
@@ -1769,8 +1769,9 @@ Closes the redo log files. There must no
 flushed modifications in the files. */
 UNIV_INTERN
 void
-fil_close_log_files(void)
-/*=====================*/
+fil_close_log_files(
+/*================*/
+	bool	free)	/*!< in: whether to free the memory object */
 {
 	fil_space_t*	space;
 
@@ -1798,7 +1799,9 @@ fil_close_log_files(void)
 
 		space = UT_LIST_GET_NEXT(space_list, space);
 
-		fil_space_free(prev_space->id, FALSE);
+		if (free) {
+			fil_space_free(prev_space->id, FALSE);
+		}
 	}
 
 	mutex_exit(&fil_system->mutex);

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc	revid:marko.makela@stripped
+++ b/storage/innobase/handler/ha_innodb.cc	revid:marko.makela@stripped
@@ -125,7 +125,6 @@ static long innobase_log_files_in_group;
 static long innobase_log_buffer_size;
 static long innobase_additional_mem_pool_size;
 static long innobase_file_io_threads;
-static long innobase_force_recovery;
 static long innobase_open_files;
 static long innobase_autoinc_lock_mode;
 static ulong innobase_commit_concurrency = 0;
@@ -3140,8 +3139,6 @@ innobase_change_buffering_inited_ok:
 	srv_n_read_io_threads = (ulint) innobase_read_io_threads;
 	srv_n_write_io_threads = (ulint) innobase_write_io_threads;
 
-	srv_force_recovery = (ulint) innobase_force_recovery;
-
 	srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
 
 	page_compression_level = (ulint) innobase_compression_level;
@@ -15678,11 +15675,18 @@ static MYSQL_SYSVAR_ULONG(write_io_threa
   "Number of background write I/O threads in InnoDB.",
   NULL, NULL, 4, 1, 64, 0);
 
-static MYSQL_SYSVAR_LONG(force_recovery, innobase_force_recovery,
+static MYSQL_SYSVAR_ULONG(force_recovery, srv_force_recovery,
   PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
   "Helps to save your data in case the disk image of the database becomes corrupt.",
   NULL, NULL, 0, 0, 6, 0);
 
+#ifndef DBUG_OFF
+static MYSQL_SYSVAR_ULONG(force_recovery_crash, srv_force_recovery_crash,
+  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+  "Helps to save your data in case the disk image of the database becomes corrupt.",
+  NULL, NULL, 0, 0, 10, 0);
+#endif /* !DBUG_OFF */
+
 static MYSQL_SYSVAR_ULONG(page_size, srv_page_size,
   PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
   "Page size to use for all InnoDB tablespaces.",
@@ -15994,6 +15998,9 @@ static struct st_mysql_sys_var* innobase
   MYSQL_SYSVAR(flush_log_at_trx_commit),
   MYSQL_SYSVAR(flush_method),
   MYSQL_SYSVAR(force_recovery),
+#ifndef DBUG_OFF
+  MYSQL_SYSVAR(force_recovery_crash),
+#endif /* !DBUG_OFF */
   MYSQL_SYSVAR(ft_cache_size),
   MYSQL_SYSVAR(ft_enable_stopword),
   MYSQL_SYSVAR(ft_max_token_size),

=== modified file 'storage/innobase/include/fil0fil.h'
--- a/storage/innobase/include/fil0fil.h	revid:marko.makela@stripped
+++ b/storage/innobase/include/fil0fil.h	revid:marko.makela@oracle.com-20120924120023-gqkwar10njnm9rir
@@ -331,8 +331,9 @@ Closes the redo log files. There must no
 flushed modifications in the files. */
 UNIV_INTERN
 void
-fil_close_log_files(void);
-/*=====================*/
+fil_close_log_files(
+/*================*/
+	bool	free);	/*!< in: whether to free the memory object */
 /*******************************************************************//**
 Sets the max tablespace id counter if the given number is bigger than the
 previous value. */

=== modified file 'storage/innobase/include/srv0srv.h'
--- a/storage/innobase/include/srv0srv.h	revid:marko.makela@strippedgame83cudrr8cq27
+++ b/storage/innobase/include/srv0srv.h	revid:marko.makela@strippedm9rir
@@ -319,7 +319,10 @@ extern ulong	srv_max_dirty_pages_pct_lwm
 extern ulong	srv_adaptive_flushing_lwm;
 extern ulong	srv_flushing_avg_loops;
 
-extern ulint	srv_force_recovery;
+extern ulong	srv_force_recovery;
+#ifndef DBUG_OFF
+extern ulong	srv_force_recovery_crash;
+#endif /* !DBUG_OFF */
 
 extern ulint	srv_fast_shutdown;	/*!< If this is 1, do not do a
 					purge and index buffer merge.

=== modified file 'storage/innobase/srv/srv0srv.cc'
--- a/storage/innobase/srv/srv0srv.cc	revid:marko.makela@oracle.com-20120921105209-game83cudrr8cq27
+++ b/storage/innobase/srv/srv0srv.cc	revid:marko.makela@stripped924120023-gqkwar10njnm9rir
@@ -297,10 +297,16 @@ UNIV_INTERN srv_stats_t	srv_stats;
 /* structure to pass status variables to MySQL */
 UNIV_INTERN export_var_t export_vars;
 
-/* If the following is != 0 we do not allow inserts etc. This protects
-the user from forgetting the innodb_force_recovery keyword to my.cnf */
-
-UNIV_INTERN ulint	srv_force_recovery	= 0;
+/** Normally 0. When nonzero, skip some phases of crash recovery,
+starting from SRV_FORCE_IGNORE_CORRUPT, so that data can be recovered
+by SELECT or mysqldump. When this is nonzero, we do not allow any user
+modifications to the data. */
+UNIV_INTERN ulong	srv_force_recovery;
+#ifndef DBUG_OFF
+/** Inject a crash at different steps of the recovery process.
+This is for testing and debugging only. */
+UNIV_INTERN ulong	srv_force_recovery_crash;
+#endif /* !DBUG_OFF */
 
 /** Print all user-level transactions deadlocks to mysqld stderr */
 

=== modified file 'storage/innobase/srv/srv0start.cc'
--- a/storage/innobase/srv/srv0start.cc	revid:marko.makela@stripped
+++ b/storage/innobase/srv/srv0start.cc	revid:marko.makela@stripped-20120924120023-gqkwar10njnm9rir
@@ -540,6 +540,147 @@ create_log_file(
 	return(DB_SUCCESS);
 }
 
+/** Initial number of the first redo log file */
+#define INIT_LOG_FILE0	101
+
+#ifdef DBUG_OFF
+# define RECOVERY_CRASH(x) do {} while(0)
+#else
+# define RECOVERY_CRASH(x) if (srv_force_recovery_crash == x) DBUG_SUICIDE()
+#endif
+
+/*********************************************************************//**
+Creates all log files.
+@return	DB_SUCCESS or error code */
+static
+dberr_t
+create_log_files(
+/*=============*/
+	char*	logfilename,	/*!< in/out: buffer for log file name */
+	size_t	dirnamelen,	/*!< in: length of the directory path */
+	lsn_t	lsn,		/*!< in: FIL_PAGE_FILE_FLUSH_LSN value */
+	char*&	logfile0)	/*!< out: name of the first log file */
+{
+	/* Remove any old log files. */
+	for (unsigned i = 0; i <= INIT_LOG_FILE0; i++) {
+		sprintf(logfilename + dirnamelen, "ib_logfile%u", i);
+
+		/* Ignore errors about non-existent files or files
+		that cannot be removed. The create_log_file() will
+		return an error when the file exists. */
+#ifdef __WIN__
+		DeleteFile((LPCTSTR) logfilename);
+#else
+		unlink(logfilename);
+#endif
+		/* Crashing after deleting the first
+		file should be recoverable. The buffer
+		pool was clean, and we can simply create
+		all log files from the scratch. */
+		RECOVERY_CRASH(6);
+	}
+
+	ut_ad(!buf_pool_check_no_pending_io());
+
+	RECOVERY_CRASH(7);
+
+	for (unsigned i = 0; i < srv_n_log_files; i++) {
+		sprintf(logfilename + dirnamelen,
+			"ib_logfile%u", i ? i : INIT_LOG_FILE0);
+
+		dberr_t err = create_log_file(&files[i], logfilename);
+
+		if (err != DB_SUCCESS) {
+			return(err);
+		}
+	}
+
+	RECOVERY_CRASH(8);
+
+	/* We did not create the first log file initially as
+	ib_logfile0, so that crash recovery cannot find it until it
+	has been completed and renamed. */
+	sprintf(logfilename + dirnamelen, "ib_logfile%u", INIT_LOG_FILE0);
+
+	fil_space_create(
+		logfilename, SRV_LOG_SPACE_FIRST_ID,
+		fsp_flags_set_page_size(0, UNIV_PAGE_SIZE),
+		FIL_LOG);
+	ut_a(fil_validate());
+
+	logfile0 = fil_node_create(
+		logfilename, (ulint) srv_log_file_size,
+		SRV_LOG_SPACE_FIRST_ID, FALSE);
+	ut_a(logfile0);
+
+	for (unsigned i = 1; i < srv_n_log_files; i++) {
+		sprintf(logfilename + dirnamelen, "ib_logfile%u", i);
+
+		if (!fil_node_create(
+			    logfilename,
+			    (ulint) srv_log_file_size,
+			    SRV_LOG_SPACE_FIRST_ID, FALSE)) {
+			ut_error;
+		}
+	}
+
+	log_group_init(0, srv_n_log_files,
+		       srv_log_file_size * UNIV_PAGE_SIZE,
+		       SRV_LOG_SPACE_FIRST_ID,
+		       SRV_LOG_SPACE_FIRST_ID + 1);
+
+	fil_open_log_and_system_tablespace_files();
+
+	/* Create a log checkpoint. */
+	mutex_enter(&log_sys->mutex);
+	ut_d(recv_no_log_write = FALSE);
+	recv_reset_logs(lsn, TRUE);
+	mutex_exit(&log_sys->mutex);
+
+	return(DB_SUCCESS);
+}
+
+/*********************************************************************//**
+Renames the first all log file. */
+static
+void
+create_log_files_rename(
+/*====================*/
+	char*	logfilename,	/*!< in/out: buffer for log file name */
+	size_t	dirnamelen,	/*!< in: length of the directory path */
+	lsn_t	lsn,		/*!< in: FIL_PAGE_FILE_FLUSH_LSN value */
+	char*	logfile0)	/*!< in/out: name of the first log file */
+{
+	/* Close the log files, so that we can rename
+	the first one. */
+	fil_close_log_files(false);
+
+	/* Rename the first log file, now that a log
+	checkpoint has been created. */
+	sprintf(logfilename + dirnamelen, "ib_logfile%u", 0);
+
+	RECOVERY_CRASH(9);
+
+	ib_logf(IB_LOG_LEVEL_INFO,
+		"Renaming log file %s to %s", logfile0, logfilename);
+
+	mutex_enter(&log_sys->mutex);
+	ut_ad(strlen(logfile0) == 2 + strlen(logfilename));
+	ibool success = os_file_rename(
+		innodb_file_log_key, logfile0, logfilename);
+	ut_a(success);
+
+	RECOVERY_CRASH(10);
+
+	/* Replace the first file with ib_logfile0. */
+	strcpy(logfile0, logfilename);
+	mutex_exit(&log_sys->mutex);
+
+	fil_open_log_and_system_tablespace_files();
+
+	ib_logf(IB_LOG_LEVEL_WARN, "New log files created, LSN=" LSN_PF, lsn);
+}
+
 /*********************************************************************//**
 Opens a log file.
 @return	DB_SUCCESS or error code */
@@ -1266,7 +1407,6 @@ innobase_start_or_create_for_mysql(void)
 /*====================================*/
 {
 	ibool		create_new_db;
-	ibool		log_created;
 	lsn_t		min_flushed_lsn;
 	lsn_t		max_flushed_lsn;
 #ifdef UNIV_LOG_ARCHIVE
@@ -1277,11 +1417,13 @@ innobase_start_or_create_for_mysql(void)
 	ulint		sum_of_data_file_sizes;
 	ulint		tablespace_size_in_header;
 	dberr_t		err;
-	ulint		i;
+	unsigned	i;
+	ulint		srv_n_log_files_found = srv_n_log_files;
 	ulint		io_limit;
 	mtr_t		mtr;
 	ib_bh_t*	ib_bh;
 	char		logfilename[10000];
+	char*		logfile0	= NULL;
 	size_t		dirnamelen;
 
 #ifdef HAVE_DARWIN_THREADS
@@ -1801,39 +1943,68 @@ innobase_start_or_create_for_mysql(void)
 	}
 
 	srv_log_file_size_requested = srv_log_file_size;
-	log_created = FALSE;
 
 	if (create_new_db) {
-create_log_files:
-		for (i = 0; i < srv_n_log_files; i++) {
-			sprintf(logfilename + dirnamelen,
-				"ib_logfile%lu", (ulong) i);
+		{
+			bool success = buf_flush_list(
+				ULINT_MAX, LSN_MAX, NULL);
+			ut_a(success);
+		}
 
-			err = create_log_file(&files[i], logfilename);
+		min_flushed_lsn = max_flushed_lsn = log_get_lsn();
 
-			if (err != DB_SUCCESS) {
-				return(err);
-			}
+		buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
+create_log_files:
+		err = create_log_files(logfilename, dirnamelen,
+				       max_flushed_lsn, logfile0);
+
+		if (err != DB_SUCCESS) {
+			return(err);
 		}
 
-		log_created = TRUE;
+		if (!create_new_db) {
+			create_log_files_rename(logfilename, dirnamelen,
+						max_flushed_lsn, logfile0);
+		}
 	} else {
 		for (i = 0; i < 100/* max of srv_n_log_files */; i++) {
 			os_offset_t	size;
 			os_file_stat_t	stat_info;
 
 			sprintf(logfilename + dirnamelen,
-				"ib_logfile%lu", (ulong) i);
+				"ib_logfile%u", i);
 
 			err = os_file_get_status(
 				logfilename, &stat_info, false);
 
 			if (err == DB_NOT_FOUND) {
 				if (i == 0) {
-					goto create_log_files;
-				}
+					if (max_flushed_lsn != min_flushed_lsn) {
+						ib_logf(IB_LOG_LEVEL_ERROR,
+							"Cannot create"
+							" log files because"
+							" data files are"
+							" corrupt or"
+							" not in sync"
+							" with each other");
+						return(DB_ERROR);
+					}
+
+					if (max_flushed_lsn < (lsn_t) 1000) {
+						ib_logf(IB_LOG_LEVEL_ERROR,
+							"Cannot create"
+							" log files because"
+							" data files are"
+							" corrupt or the"
+							" database was not"
+							" shut down cleanly"
+							" after creating"
+							" the data files.");
+						return(DB_ERROR);
+					}
 
-				if (i < 2) {
+					goto create_log_files;
+				} else if (i < 2) {
 					/* must have at least 2 log files */
 					return(err);
 				}
@@ -1880,45 +2051,48 @@ create_log_files:
 				return(DB_ERROR);
 			}
 		}
-	}
 
-	/* Create the in-memory file space objects. */
+		srv_n_log_files_found = i;
 
-	sprintf(logfilename + dirnamelen, "ib_logfile%lu", 0UL);
+		/* Create the in-memory file space objects. */
 
-	fil_space_create(logfilename,
-			 SRV_LOG_SPACE_FIRST_ID,
-			 fsp_flags_set_page_size(0, UNIV_PAGE_SIZE),
-			 FIL_LOG);
+		sprintf(logfilename + dirnamelen, "ib_logfile%u", 0);
 
-	ut_a(fil_validate());
+		fil_space_create(logfilename,
+				 SRV_LOG_SPACE_FIRST_ID,
+				 fsp_flags_set_page_size(0, UNIV_PAGE_SIZE),
+				 FIL_LOG);
 
-	/* srv_log_file_size is measured in pages; if page size is 16KB,
-	then we have a limit of 64TB on 32 bit systems */
-	ut_a(srv_log_file_size <= ULINT_MAX);
-
-	for (ulint j = 0; j < i; j++) {
-		sprintf(logfilename + dirnamelen, "ib_logfile%lu",
-			(ulong) j);
+		ut_a(fil_validate());
 
-		if (!fil_node_create(logfilename, (ulint) srv_log_file_size,
-				     SRV_LOG_SPACE_FIRST_ID, FALSE)) {
-			return(DB_ERROR);
+		/* srv_log_file_size is measured in pages; if page size is 16KB,
+		then we have a limit of 64TB on 32 bit systems */
+		ut_a(srv_log_file_size <= ULINT_MAX);
+
+		for (unsigned j = 0; j < i; j++) {
+			sprintf(logfilename + dirnamelen, "ib_logfile%u", j);
+
+			if (!fil_node_create(logfilename,
+					     (ulint) srv_log_file_size,
+					     SRV_LOG_SPACE_FIRST_ID, FALSE)) {
+				return(DB_ERROR);
+			}
 		}
-	}
 
 #ifdef UNIV_LOG_ARCHIVE
-	/* Create the file space object for archived logs. Under
-	MySQL, no archiving ever done. */
-	fil_space_create("arch_log_space", SRV_LOG_SPACE_FIRST_ID + 1,
-			 0, FIL_LOG);
+		/* Create the file space object for archived logs. Under
+		MySQL, no archiving ever done. */
+		fil_space_create("arch_log_space", SRV_LOG_SPACE_FIRST_ID + 1,
+				 0, FIL_LOG);
 #endif /* UNIV_LOG_ARCHIVE */
-	log_group_init(0, i, srv_log_file_size * UNIV_PAGE_SIZE,
-		       SRV_LOG_SPACE_FIRST_ID,
-		       SRV_LOG_SPACE_FIRST_ID + 1); /* dummy arch space id */
+		log_group_init(0, i, srv_log_file_size * UNIV_PAGE_SIZE,
+			       SRV_LOG_SPACE_FIRST_ID,
+			       SRV_LOG_SPACE_FIRST_ID + 1);
+	}
 
-	/* Open all log files and data files in the system tablespace: we
-	keep them open until database shutdown */
+	/* Open all log files and data files in the system
+	tablespace: we keep them open until database
+	shutdown */
 
 	fil_open_log_and_system_tablespace_files();
 
@@ -1940,68 +2114,6 @@ create_log_files:
 	can also be used by recovery if it tries to drop some table */
 	dict_stats_thread_init();
 
-	if (log_created && !create_new_db
-#ifdef UNIV_LOG_ARCHIVE
-	    && !srv_archive_recovery
-#endif /* UNIV_LOG_ARCHIVE */
-	    ) {
-		if (max_flushed_lsn != min_flushed_lsn
-#ifdef UNIV_LOG_ARCHIVE
-		    || max_arch_log_no != min_arch_log_no
-#endif /* UNIV_LOG_ARCHIVE */
-		    ) {
-			ut_print_timestamp(stderr);
-			fprintf(stderr,
-				" InnoDB: Cannot initialize created"
-				" log files because\n");
-			ut_print_timestamp(stderr);
-			fprintf(stderr,
-				" InnoDB: data files were not in sync"
-				" with each other\n");
-			ut_print_timestamp(stderr);
-			fprintf(stderr,
-				" InnoDB: or the data files are corrupt.\n");
-
-			return(DB_ERROR);
-		}
-
-		if (max_flushed_lsn < (lsn_t) 1000) {
-			ut_print_timestamp(stderr);
-			fprintf(stderr,
-				" InnoDB: Cannot initialize created"
-				" log files because\n");
-			ut_print_timestamp(stderr);
-			fprintf(stderr,
-				" InnoDB: data files are corrupt,"
-				" or new data files were\n");
-			ut_print_timestamp(stderr);
-			fprintf(stderr,
-				" InnoDB: created when the database"
-				" was started previous\n");
-			ut_print_timestamp(stderr);
-			fprintf(stderr,
-				" InnoDB: time but the database"
-				" was not shut down\n");
-			ut_print_timestamp(stderr);
-			fprintf(stderr,
-				" InnoDB: normally after that.\n");
-
-			return(DB_ERROR);
-		}
-
-		mutex_enter(&(log_sys->mutex));
-
-#ifdef UNIV_LOG_ARCHIVE
-		/* Do not + 1 arch_log_no because we do not use log
-		archiving */
-		recv_reset_logs(max_flushed_lsn, max_arch_log_no, TRUE);
-#else
-		recv_reset_logs(max_flushed_lsn, TRUE);
-#endif /* UNIV_LOG_ARCHIVE */
-
-		mutex_exit(&(log_sys->mutex));
-	}
-
 	trx_sys_file_format_init();
 
 	trx_sys_create();
@@ -2030,6 +2142,20 @@ create_log_files:
 
 		srv_startup_is_before_trx_rollback_phase = FALSE;
 
+		bool success = buf_flush_list(ULINT_MAX, LSN_MAX, NULL);
+		ut_a(success);
+
+		min_flushed_lsn = max_flushed_lsn = log_get_lsn();
+
+		buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
+
+		/* Stamp the LSN to the data files. */
+		fil_write_flushed_lsn_to_data_files(max_flushed_lsn, 0);
+
+		fil_flush_file_spaces(FIL_TABLESPACE);
+
+		create_log_files_rename(logfilename, dirnamelen,
+					max_flushed_lsn, logfile0);
 #ifdef UNIV_LOG_ARCHIVE
 	} else if (srv_archive_recovery) {
 		ut_print_timestamp(stderr);
@@ -2143,7 +2269,7 @@ create_log_files:
 		if (!srv_force_recovery
 		    && !recv_sys->found_corrupt_log
 		    && (srv_log_file_size_requested != srv_log_file_size
-			|| i != srv_n_log_files)) {
+			|| srv_n_log_files_found != srv_n_log_files)) {
 			/* Prepare to replace the redo log files. */
 
 			/* Clean the buffer pool. */
@@ -2151,6 +2277,8 @@ create_log_files:
 				ULINT_MAX, LSN_MAX, NULL);
 			ut_a(success);
 
+			RECOVERY_CRASH(1);
+
 			min_flushed_lsn = max_flushed_lsn = log_get_lsn();
 
 			ib_logf(IB_LOG_LEVEL_WARN,
@@ -2164,6 +2292,8 @@ create_log_files:
 
 			buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
 
+			RECOVERY_CRASH(2);
+
 			/* Flush the old log files. */
 			log_buffer_flush_to_disk();
 
@@ -2172,15 +2302,21 @@ create_log_files:
 			ut_d(recv_no_log_write = TRUE);
 			ut_ad(!buf_pool_check_no_pending_io());
 
+			RECOVERY_CRASH(3);
+
 			/* Stamp the LSN to the data files. */
 			fil_write_flushed_lsn_to_data_files(
 				max_flushed_lsn, 0);
 
 			fil_flush_file_spaces(FIL_TABLESPACE);
 
-			/* Close the redo log files, so that we can
-			replace them. */
-			fil_close_log_files();
+			RECOVERY_CRASH(4);
+
+			/* Close and free the redo log files, so that
+			we can replace them. */
+			fil_close_log_files(true);
+
+			RECOVERY_CRASH(5);
 
 			/* Free the old log file space. */
 			log_group_close_all();
@@ -2188,82 +2324,17 @@ create_log_files:
 			ib_logf(IB_LOG_LEVEL_WARN,
 				"Starting to delete and rewrite log files.");
 
-			/* Remove the old log files. */
-			for (ulint j = 0; j < i; j++) {
-				os_file_stat_t	stat_info;
-
-				sprintf(logfilename + dirnamelen,
-					"ib_logfile%lu", (ulong) j);
-
-				err = os_file_get_status(
-					logfilename, &stat_info, false);
-
-				if (err == DB_NOT_FOUND) {
-					break;
-				}
-
-				if (!os_file_delete(logfilename)) {
-					return(DB_ERROR);
-				}
-			}
-
-			ut_ad(!buf_pool_check_no_pending_io());
-
 			srv_log_file_size = srv_log_file_size_requested;
 
-			/* Create new log files. */
-			for (i = 0; i < srv_n_log_files; i++) {
-				sprintf(logfilename + dirnamelen,
-					"ib_logfile%lu", (ulong) i);
-
-				err = create_log_file(&files[i], logfilename);
-
-				if (err != DB_SUCCESS) {
-					return(err);
-				}
-			}
-
-			log_created = TRUE;
+			err = create_log_files(logfilename, dirnamelen,
+					       max_flushed_lsn, logfile0);
 
-			sprintf(logfilename + dirnamelen,
-				"ib_logfile%lu", 0UL);
-
-			fil_space_create(
-				logfilename, SRV_LOG_SPACE_FIRST_ID,
-				fsp_flags_set_page_size(0, UNIV_PAGE_SIZE),
-				FIL_LOG);
-			ut_a(fil_validate());
-
-			for (i = 0; i < srv_n_log_files; i++) {
-				sprintf(logfilename + dirnamelen,
-					"ib_logfile%lu", (ulong) i);
-
-				if (!fil_node_create(
-					    logfilename,
-					    (ulint) srv_log_file_size,
-					    SRV_LOG_SPACE_FIRST_ID, FALSE)) {
-					ut_error;
-				}
+			if (err != DB_SUCCESS) {
+				return(err);
 			}
 
-			log_group_init(0, srv_n_log_files,
-				       srv_log_file_size * UNIV_PAGE_SIZE,
-				       SRV_LOG_SPACE_FIRST_ID,
-				       SRV_LOG_SPACE_FIRST_ID + 1);
-
-			fil_open_log_and_system_tablespace_files();
-
-			/* Create a log checkpoint. */
-			mutex_enter(&log_sys->mutex);
-			ut_d(recv_no_log_write = FALSE);
-			ut_ad(max_flushed_lsn == log_sys->lsn);
-			recv_reset_logs(max_flushed_lsn, TRUE);
-			mutex_exit(&log_sys->mutex);
-
-			ib_logf(IB_LOG_LEVEL_WARN,
-				"New log files created"
-				", LSN=" LSN_PF,
-				max_flushed_lsn);
+			create_log_files_rename(logfilename, dirnamelen,
+						max_flushed_lsn, logfile0);
 		}
 
 		srv_startup_is_before_trx_rollback_phase = FALSE;

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.6-wl6494 branch (marko.makela:4307 to 4309) WL#6494marko.makela24 Sep