Commit 29a980cf authored by Marko Mäkelä's avatar Marko Mäkelä

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 81b7fe9d 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.
parent 5da6bd7b
......@@ -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;
}
......
......@@ -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]);
}
......
......@@ -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();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment