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