[Commits] 29a980cf5cc: MDEV-11688 follow-up: More robust shutdown after aborted startup.

marko.makela at mariadb.com marko.makela at mariadb.com
Wed Mar 8 22:39:46 EET 2017


revision-id: 29a980cf5cca0f27477d55c86a31c2cf01e3b52b (mariadb-10.2.4-29-g29a980cf5cc)
parent(s): 5da6bd7b959af4a9755556afedde8f34d95c679a
author: Marko Mäkelä
committer: Marko Mäkelä
timestamp: 2017-03-08 22:36:10 +0200
message:

MDEV-11688 follow-up: More robust shutdown after aborted startup.

After starting MariaDB 10.2 with an invalid value of
--innodb-flush-method= (the empty string), shutdown would
attempt to dereference some NULL pointers. This was probably broken
in commit 81b7fe9d383bdf68a622b95384f067ed68ba342c which implemented
shutdown after aborted startup.

logs_empty_and_mark_files_at_shutdown(): Allow shutdown even if
lock_sys, log_sys, or fil_system is NULL.

os_aio_free(): Tolerate os_aio_segment_wait_events==NULL.

innobase_start_or_create_for_mysql(): Do not invoke
srv_init_abort() before initializing all mutexes for the temporary files.

innodb_shutdown(): Tolerate buf_pool_ptr==NULL.

---
 storage/innobase/log/log0log.cc   | 44 ++++++++++++++++++++++++---------------
 storage/innobase/os/os0file.cc    |  6 +++++-
 storage/innobase/srv/srv0start.cc | 29 +++++++++++++++-----------
 3 files changed, 49 insertions(+), 30 deletions(-)

diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 57796acf1af..c3f97b6cc31 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -2015,7 +2015,6 @@ logs_empty_and_mark_files_at_shutdown(void)
 {
 	lsn_t			lsn;
 	ulint			count = 0;
-	ulint			pending_io;
 
 	ib::info() << "Starting shutdown...";
 
@@ -2030,13 +2029,18 @@ logs_empty_and_mark_files_at_shutdown(void)
 
 	srv_shutdown_state = SRV_SHUTDOWN_CLEANUP;
 loop:
+	ut_ad(lock_sys || !srv_was_started);
+	ut_ad(log_sys || !srv_was_started);
+	ut_ad(fil_system || !srv_was_started);
 	os_event_set(srv_buf_resize_event);
 
 	if (!srv_read_only_mode) {
 		os_event_set(srv_error_event);
 		os_event_set(srv_monitor_event);
 		os_event_set(srv_buf_dump_event);
-		os_event_set(lock_sys->timeout_event);
+		if (lock_sys) {
+			os_event_set(lock_sys->timeout_event);
+		}
 		if (dict_stats_event) {
 			os_event_set(dict_stats_event);
 		} else {
@@ -2077,7 +2081,7 @@ logs_empty_and_mark_files_at_shutdown(void)
 		thread_name = "buf_resize_thread";
 	} else if (srv_dict_stats_thread_active) {
 		thread_name = "dict_stats_thread";
-	} else if (lock_sys->timeout_thread_active) {
+	} else if (lock_sys && lock_sys->timeout_thread_active) {
 		thread_name = "lock_wait_timeout_thread";
 	} else if (srv_buf_dump_thread_active) {
 		thread_name = "buf_dump_thread";
@@ -2137,25 +2141,29 @@ logs_empty_and_mark_files_at_shutdown(void)
 		os_event_set(log_scrub_event);
 	}
 
-	log_mutex_enter();
-	const ulint	n_write	= log_sys->n_pending_checkpoint_writes;
-	const ulint	n_flush	= log_sys->n_pending_flushes;
-	log_mutex_exit();
+	if (log_sys) {
+		log_mutex_enter();
+		const ulint	n_write	= log_sys->n_pending_checkpoint_writes;
+		const ulint	n_flush	= log_sys->n_pending_flushes;
+		log_mutex_exit();
 
-	if (log_scrub_thread_active || n_write || n_flush) {
-		if (srv_print_verbose_log && count > 600) {
-			ib::info() << "Pending checkpoint_writes: " << n_write
-				<< ". Pending log flush writes: " << n_flush;
-			count = 0;
+		if (log_scrub_thread_active || n_write || n_flush) {
+			if (srv_print_verbose_log && count > 600) {
+				ib::info() << "Pending checkpoint_writes: "
+					<< n_write
+					<< ". Pending log flush writes: "
+					<< n_flush;
+				count = 0;
+			}
+			goto loop;
 		}
-		goto loop;
 	}
 
 	ut_ad(!log_scrub_thread_active);
 
-	pending_io = buf_pool_check_no_pending_io();
-
-	if (pending_io) {
+	if (!buf_pool_ptr) {
+		ut_ad(!srv_was_started);
+	} else if (ulint pending_io = buf_pool_check_no_pending_io()) {
 		if (srv_print_verbose_log && count > 600) {
 			ib::info() << "Waiting for " << pending_io << " buffer"
 				" page I/Os to complete";
@@ -2187,7 +2195,9 @@ logs_empty_and_mark_files_at_shutdown(void)
 
 		srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
 
-		fil_close_all_files();
+		if (fil_system) {
+			fil_close_all_files();
+		}
 		return;
 	}
 
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index f71602c43b9..755d20bac6c 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -6036,7 +6036,11 @@ os_aio_free()
 {
 	AIO::shutdown();
 
-	if (!srv_use_native_aio) {
+	ut_ad(!os_aio_segment_wait_events || !srv_use_native_aio);
+	ut_ad(srv_use_native_aio || os_aio_segment_wait_events
+	      || !srv_was_started);
+
+	if (!srv_use_native_aio && os_aio_segment_wait_events) {
 		for (ulint i = 0; i < os_aio_n_segments; i++) {
 			os_event_destroy(os_aio_segment_wait_events[i]);
 		}
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index c360500b884..c7b61cfb82c 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -1688,10 +1688,6 @@ innobase_start_or_create_for_mysql(void)
 
 	srv_boot();
 
-	if (err != DB_SUCCESS) {
-		return(srv_init_abort(err));
-	}
-
 	ib::info() << ut_crc32_implementation;
 
 	if (!srv_read_only_mode) {
@@ -1717,15 +1713,17 @@ innobase_start_or_create_for_mysql(void)
 				ib::error() << "Unable to create "
 					<< srv_monitor_file_name << ": "
 					<< strerror(errno);
-				return(srv_init_abort(DB_ERROR));
+				if (err == DB_SUCCESS) {
+					err = DB_ERROR;
+				}
 			}
 		} else {
 
 			srv_monitor_file_name = NULL;
 			srv_monitor_file = os_file_create_tmpfile(NULL);
 
-			if (!srv_monitor_file) {
-				return(srv_init_abort(DB_ERROR));
+			if (!srv_monitor_file && err == DB_SUCCESS) {
+				err = DB_ERROR;
 			}
 		}
 
@@ -1734,8 +1732,8 @@ innobase_start_or_create_for_mysql(void)
 
 		srv_dict_tmpfile = os_file_create_tmpfile(NULL);
 
-		if (!srv_dict_tmpfile) {
-			return(srv_init_abort(DB_ERROR));
+		if (!srv_dict_tmpfile && err == DB_SUCCESS) {
+			err = DB_ERROR;
 		}
 
 		mutex_create(LATCH_ID_SRV_MISC_TMPFILE,
@@ -1743,11 +1741,15 @@ innobase_start_or_create_for_mysql(void)
 
 		srv_misc_tmpfile = os_file_create_tmpfile(NULL);
 
-		if (!srv_misc_tmpfile) {
-			return(srv_init_abort(DB_ERROR));
+		if (!srv_misc_tmpfile && err == DB_SUCCESS) {
+			err = DB_ERROR;
 		}
 	}
 
+	if (err != DB_SUCCESS) {
+		return(srv_init_abort(err));
+	}
+
 	srv_n_file_io_threads = srv_n_read_io_threads;
 
 	srv_n_file_io_threads += srv_n_write_io_threads;
@@ -2917,7 +2919,10 @@ innodb_shutdown()
 
 	pars_lexer_close();
 	log_mem_free();
-	buf_pool_free(srv_buf_pool_instances);
+	ut_ad(buf_pool_ptr || !srv_was_started);
+	if (buf_pool_ptr) {
+		buf_pool_free(srv_buf_pool_instances);
+	}
 
 	/* 6. Free the thread management resoruces. */
 	os_thread_free();


More information about the commits mailing list