Skip to content

Commit 29a980c

Browse files
committed
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 81b7fe9 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.
1 parent 5da6bd7 commit 29a980c

File tree

3 files changed

+49
-30
lines changed

3 files changed

+49
-30
lines changed

storage/innobase/log/log0log.cc

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2015,7 +2015,6 @@ logs_empty_and_mark_files_at_shutdown(void)
20152015
{
20162016
lsn_t lsn;
20172017
ulint count = 0;
2018-
ulint pending_io;
20192018

20202019
ib::info() << "Starting shutdown...";
20212020

@@ -2030,13 +2029,18 @@ logs_empty_and_mark_files_at_shutdown(void)
20302029

20312030
srv_shutdown_state = SRV_SHUTDOWN_CLEANUP;
20322031
loop:
2032+
ut_ad(lock_sys || !srv_was_started);
2033+
ut_ad(log_sys || !srv_was_started);
2034+
ut_ad(fil_system || !srv_was_started);
20332035
os_event_set(srv_buf_resize_event);
20342036

20352037
if (!srv_read_only_mode) {
20362038
os_event_set(srv_error_event);
20372039
os_event_set(srv_monitor_event);
20382040
os_event_set(srv_buf_dump_event);
2039-
os_event_set(lock_sys->timeout_event);
2041+
if (lock_sys) {
2042+
os_event_set(lock_sys->timeout_event);
2043+
}
20402044
if (dict_stats_event) {
20412045
os_event_set(dict_stats_event);
20422046
} else {
@@ -2077,7 +2081,7 @@ logs_empty_and_mark_files_at_shutdown(void)
20772081
thread_name = "buf_resize_thread";
20782082
} else if (srv_dict_stats_thread_active) {
20792083
thread_name = "dict_stats_thread";
2080-
} else if (lock_sys->timeout_thread_active) {
2084+
} else if (lock_sys && lock_sys->timeout_thread_active) {
20812085
thread_name = "lock_wait_timeout_thread";
20822086
} else if (srv_buf_dump_thread_active) {
20832087
thread_name = "buf_dump_thread";
@@ -2137,25 +2141,29 @@ logs_empty_and_mark_files_at_shutdown(void)
21372141
os_event_set(log_scrub_event);
21382142
}
21392143

2140-
log_mutex_enter();
2141-
const ulint n_write = log_sys->n_pending_checkpoint_writes;
2142-
const ulint n_flush = log_sys->n_pending_flushes;
2143-
log_mutex_exit();
2144+
if (log_sys) {
2145+
log_mutex_enter();
2146+
const ulint n_write = log_sys->n_pending_checkpoint_writes;
2147+
const ulint n_flush = log_sys->n_pending_flushes;
2148+
log_mutex_exit();
21442149

2145-
if (log_scrub_thread_active || n_write || n_flush) {
2146-
if (srv_print_verbose_log && count > 600) {
2147-
ib::info() << "Pending checkpoint_writes: " << n_write
2148-
<< ". Pending log flush writes: " << n_flush;
2149-
count = 0;
2150+
if (log_scrub_thread_active || n_write || n_flush) {
2151+
if (srv_print_verbose_log && count > 600) {
2152+
ib::info() << "Pending checkpoint_writes: "
2153+
<< n_write
2154+
<< ". Pending log flush writes: "
2155+
<< n_flush;
2156+
count = 0;
2157+
}
2158+
goto loop;
21502159
}
2151-
goto loop;
21522160
}
21532161

21542162
ut_ad(!log_scrub_thread_active);
21552163

2156-
pending_io = buf_pool_check_no_pending_io();
2157-
2158-
if (pending_io) {
2164+
if (!buf_pool_ptr) {
2165+
ut_ad(!srv_was_started);
2166+
} else if (ulint pending_io = buf_pool_check_no_pending_io()) {
21592167
if (srv_print_verbose_log && count > 600) {
21602168
ib::info() << "Waiting for " << pending_io << " buffer"
21612169
" page I/Os to complete";
@@ -2187,7 +2195,9 @@ logs_empty_and_mark_files_at_shutdown(void)
21872195

21882196
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
21892197

2190-
fil_close_all_files();
2198+
if (fil_system) {
2199+
fil_close_all_files();
2200+
}
21912201
return;
21922202
}
21932203

storage/innobase/os/os0file.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6036,7 +6036,11 @@ os_aio_free()
60366036
{
60376037
AIO::shutdown();
60386038

6039-
if (!srv_use_native_aio) {
6039+
ut_ad(!os_aio_segment_wait_events || !srv_use_native_aio);
6040+
ut_ad(srv_use_native_aio || os_aio_segment_wait_events
6041+
|| !srv_was_started);
6042+
6043+
if (!srv_use_native_aio && os_aio_segment_wait_events) {
60406044
for (ulint i = 0; i < os_aio_n_segments; i++) {
60416045
os_event_destroy(os_aio_segment_wait_events[i]);
60426046
}

storage/innobase/srv/srv0start.cc

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1688,10 +1688,6 @@ innobase_start_or_create_for_mysql(void)
16881688

16891689
srv_boot();
16901690

1691-
if (err != DB_SUCCESS) {
1692-
return(srv_init_abort(err));
1693-
}
1694-
16951691
ib::info() << ut_crc32_implementation;
16961692

16971693
if (!srv_read_only_mode) {
@@ -1717,15 +1713,17 @@ innobase_start_or_create_for_mysql(void)
17171713
ib::error() << "Unable to create "
17181714
<< srv_monitor_file_name << ": "
17191715
<< strerror(errno);
1720-
return(srv_init_abort(DB_ERROR));
1716+
if (err == DB_SUCCESS) {
1717+
err = DB_ERROR;
1718+
}
17211719
}
17221720
} else {
17231721

17241722
srv_monitor_file_name = NULL;
17251723
srv_monitor_file = os_file_create_tmpfile(NULL);
17261724

1727-
if (!srv_monitor_file) {
1728-
return(srv_init_abort(DB_ERROR));
1725+
if (!srv_monitor_file && err == DB_SUCCESS) {
1726+
err = DB_ERROR;
17291727
}
17301728
}
17311729

@@ -1734,20 +1732,24 @@ innobase_start_or_create_for_mysql(void)
17341732

17351733
srv_dict_tmpfile = os_file_create_tmpfile(NULL);
17361734

1737-
if (!srv_dict_tmpfile) {
1738-
return(srv_init_abort(DB_ERROR));
1735+
if (!srv_dict_tmpfile && err == DB_SUCCESS) {
1736+
err = DB_ERROR;
17391737
}
17401738

17411739
mutex_create(LATCH_ID_SRV_MISC_TMPFILE,
17421740
&srv_misc_tmpfile_mutex);
17431741

17441742
srv_misc_tmpfile = os_file_create_tmpfile(NULL);
17451743

1746-
if (!srv_misc_tmpfile) {
1747-
return(srv_init_abort(DB_ERROR));
1744+
if (!srv_misc_tmpfile && err == DB_SUCCESS) {
1745+
err = DB_ERROR;
17481746
}
17491747
}
17501748

1749+
if (err != DB_SUCCESS) {
1750+
return(srv_init_abort(err));
1751+
}
1752+
17511753
srv_n_file_io_threads = srv_n_read_io_threads;
17521754

17531755
srv_n_file_io_threads += srv_n_write_io_threads;
@@ -2917,7 +2919,10 @@ innodb_shutdown()
29172919

29182920
pars_lexer_close();
29192921
log_mem_free();
2920-
buf_pool_free(srv_buf_pool_instances);
2922+
ut_ad(buf_pool_ptr || !srv_was_started);
2923+
if (buf_pool_ptr) {
2924+
buf_pool_free(srv_buf_pool_instances);
2925+
}
29212926

29222927
/* 6. Free the thread management resoruces. */
29232928
os_thread_free();

0 commit comments

Comments
 (0)