Commit 5999d512 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-23399 fixup: Avoid crash on Mariabackup shutdown

innodb_preshutdown(): Terminate the encryption threads before
the page cleaner thread can be shut down.

innodb_shutdown(): Always wait for the encryption threads and
page cleaner to shut down.

srv_shutdown_all_bg_threads(): Wait for the encryption threads and
the page cleaner to shut down. (After an aborted startup,
innodb_shutdown() would not be called.)

row_get_background_drop_list_len_low(): Remove.

os_thread_count: Remove. Alternatively, at the end of
srv_shutdown_all_bg_threads() we could try to wait longer
for the count to reach 0. On some platforms, an assertion
os_thread_count==0 could fail even after a small delay,
even though in the core dump all threads would have exited.

srv_shutdown_threads(): Renamed from srv_shutdown_all_bg_threads().
Do not wait for the page cleaner to shut down, because the later
innodb_shutdown(), which may invoke
logs_empty_and_mark_files_at_shutdown(), assumes that it exists.
parent d8515c8d
...@@ -3418,13 +3418,9 @@ xb_data_files_init() ...@@ -3418,13 +3418,9 @@ xb_data_files_init()
return(xb_load_tablespaces()); return(xb_load_tablespaces());
} }
/************************************************************************ /** Destroy the tablespace memory cache. */
Destroy the tablespace memory cache. */ static void xb_data_files_close()
static
void
xb_data_files_close()
{ {
ut_ad(!os_thread_count);
fil_close_all_files(); fil_close_all_files();
buf_dblwr.close(); buf_dblwr.close();
} }
......
...@@ -1987,7 +1987,10 @@ static os_thread_ret_t DECLARE_THREAD(buf_flush_page_cleaner)(void*) ...@@ -1987,7 +1987,10 @@ static os_thread_ret_t DECLARE_THREAD(buf_flush_page_cleaner)(void*)
buf_flush_wait_batch_end_acquiring_mutex(false); buf_flush_wait_batch_end_acquiring_mutex(false);
} }
mysql_mutex_lock(&buf_pool.flush_list_mutex);
buf_page_cleaner_is_active = false; buf_page_cleaner_is_active = false;
mysql_cond_broadcast(&buf_pool.done_flush_list);
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
my_thread_end(); my_thread_end();
/* We count the number of threads in os_thread_exit(). A created /* We count the number of threads in os_thread_exit(). A created
......
...@@ -66,9 +66,6 @@ typedef void* (*os_posix_f_t) (void*); ...@@ -66,9 +66,6 @@ typedef void* (*os_posix_f_t) (void*);
typedef unsigned int mysql_pfs_key_t; typedef unsigned int mysql_pfs_key_t;
#endif /* HAVE_PSI_INTERFACE */ #endif /* HAVE_PSI_INTERFACE */
/** Number of threads active. */
extern Atomic_counter<ulint> os_thread_count;
/***************************************************************//** /***************************************************************//**
Compares two thread ids for equality. Compares two thread ids for equality.
@return TRUE if equal */ @return TRUE if equal */
......
...@@ -27,9 +27,6 @@ Created 9/8/1995 Heikki Tuuri ...@@ -27,9 +27,6 @@ Created 9/8/1995 Heikki Tuuri
#include "univ.i" #include "univ.i"
#include "srv0srv.h" #include "srv0srv.h"
/** Number of threads active. */
Atomic_counter<ulint> os_thread_count;
/***************************************************************//** /***************************************************************//**
Compares two thread ids for equality. Compares two thread ids for equality.
@return TRUE if equal */ @return TRUE if equal */
...@@ -110,8 +107,6 @@ os_thread_t os_thread_create(os_thread_func_t func, void *arg) ...@@ -110,8 +107,6 @@ os_thread_t os_thread_create(os_thread_func_t func, void *arg)
CloseHandle(handle); CloseHandle(handle);
os_thread_count++;
return((os_thread_t)new_thread_id); return((os_thread_t)new_thread_id);
#else /* _WIN32 else */ #else /* _WIN32 else */
...@@ -125,8 +120,6 @@ os_thread_t os_thread_create(os_thread_func_t func, void *arg) ...@@ -125,8 +120,6 @@ os_thread_t os_thread_create(os_thread_func_t func, void *arg)
abort(); abort();
} }
os_thread_count++;
ret = pthread_create(&new_thread_id, &attr, func, arg); ret = pthread_create(&new_thread_id, &attr, func, arg);
ut_a(ret == 0); ut_a(ret == 0);
...@@ -135,8 +128,6 @@ os_thread_t os_thread_create(os_thread_func_t func, void *arg) ...@@ -135,8 +128,6 @@ os_thread_t os_thread_create(os_thread_func_t func, void *arg)
#endif /* not _WIN32 */ #endif /* not _WIN32 */
ut_a(os_thread_count <= srv_max_n_threads);
return((os_thread_t)new_thread_id); return((os_thread_t)new_thread_id);
} }
...@@ -152,8 +143,6 @@ ATTRIBUTE_NORETURN void os_thread_exit() ...@@ -152,8 +143,6 @@ ATTRIBUTE_NORETURN void os_thread_exit()
pfs_delete_thread(); pfs_delete_thread();
#endif #endif
os_thread_count--;
#ifdef _WIN32 #ifdef _WIN32
ExitThread(0); ExitThread(0);
#else #else
......
...@@ -822,11 +822,8 @@ srv_open_tmp_tablespace(bool create_new_db) ...@@ -822,11 +822,8 @@ srv_open_tmp_tablespace(bool create_new_db)
return(err); return(err);
} }
/** /** Shutdown background threads, except the page cleaner. */
Shutdown all background threads created by InnoDB. */ static void srv_shutdown_threads()
static
void
srv_shutdown_all_bg_threads()
{ {
ut_ad(!srv_undo_sources); ut_ad(!srv_undo_sources);
srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS; srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS;
...@@ -838,38 +835,9 @@ srv_shutdown_all_bg_threads() ...@@ -838,38 +835,9 @@ srv_shutdown_all_bg_threads()
srv_purge_shutdown(); srv_purge_shutdown();
} }
/* All threads end up waiting for certain events. Put those events if (srv_n_fil_crypt_threads) {
to the signaled state. Then the threads will exit themselves after fil_crypt_set_thread_cnt(0);
os_event_wait(). */
for (uint i = 0; i < 1000; ++i) {
/* NOTE: IF YOU CREATE THREADS IN INNODB, YOU MUST EXIT THEM
HERE OR EARLIER */
if (!srv_read_only_mode) {
/* b. srv error monitor thread exits automatically,
no need to do anything here */
if (srv_n_fil_crypt_threads_started) {
os_event_set(fil_crypt_threads_event);
}
} }
if (buf_page_cleaner_is_active) {
ut_ad(!srv_read_only_mode);
/* e. Exit the buf_flush_page_cleaner */
mysql_cond_signal(&buf_pool.do_flush_list);
}
if (!os_thread_count) {
return;
}
os_thread_sleep(100000);
}
ib::warn() << os_thread_count << " threads created by InnoDB"
" had not exited at shutdown!";
ut_ad(0);
} }
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
...@@ -916,7 +884,7 @@ srv_init_abort_low( ...@@ -916,7 +884,7 @@ srv_init_abort_low(
} }
srv_shutdown_bg_undo_sources(); srv_shutdown_bg_undo_sources();
srv_shutdown_all_bg_threads(); srv_shutdown_threads();
return(err); return(err);
} }
...@@ -1972,9 +1940,10 @@ dberr_t srv_start(bool create_new_db) ...@@ -1972,9 +1940,10 @@ dberr_t srv_start(bool create_new_db)
/** Shut down background threads that can generate undo log. */ /** Shut down background threads that can generate undo log. */
void srv_shutdown_bg_undo_sources() void srv_shutdown_bg_undo_sources()
{ {
srv_shutdown_state = SRV_SHUTDOWN_INITIATED;
if (srv_undo_sources) { if (srv_undo_sources) {
ut_ad(!srv_read_only_mode); ut_ad(!srv_read_only_mode);
srv_shutdown_state = SRV_SHUTDOWN_INITIATED;
fts_optimize_shutdown(); fts_optimize_shutdown();
dict_stats_shutdown(); dict_stats_shutdown();
while (row_get_background_drop_list_len_low()) { while (row_get_background_drop_list_len_low()) {
...@@ -2010,6 +1979,9 @@ void innodb_preshutdown() ...@@ -2010,6 +1979,9 @@ void innodb_preshutdown()
} }
srv_shutdown_bg_undo_sources(); srv_shutdown_bg_undo_sources();
srv_purge_shutdown(); srv_purge_shutdown();
if (srv_n_fil_crypt_threads)
fil_crypt_set_thread_cnt(0);
} }
...@@ -2020,9 +1992,21 @@ void innodb_shutdown() ...@@ -2020,9 +1992,21 @@ void innodb_shutdown()
ut_ad(!srv_undo_sources); ut_ad(!srv_undo_sources);
switch (srv_operation) { switch (srv_operation) {
case SRV_OPERATION_BACKUP: case SRV_OPERATION_BACKUP:
case SRV_OPERATION_RESTORE:
case SRV_OPERATION_RESTORE_DELTA: case SRV_OPERATION_RESTORE_DELTA:
break;
case SRV_OPERATION_RESTORE:
case SRV_OPERATION_RESTORE_EXPORT: case SRV_OPERATION_RESTORE_EXPORT:
srv_shutdown_state = SRV_SHUTDOWN_CLEANUP;
if (!buf_page_cleaner_is_active) {
break;
}
mysql_mutex_lock(&buf_pool.flush_list_mutex);
while (buf_page_cleaner_is_active) {
mysql_cond_signal(&buf_pool.do_flush_list);
mysql_cond_wait(&buf_pool.done_flush_list,
&buf_pool.flush_list_mutex);
}
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
break; break;
case SRV_OPERATION_NORMAL: case SRV_OPERATION_NORMAL:
/* Shut down the persistent files. */ /* Shut down the persistent files. */
...@@ -2032,7 +2016,8 @@ void innodb_shutdown() ...@@ -2032,7 +2016,8 @@ void innodb_shutdown()
os_aio_free(); os_aio_free();
fil_close_all_files(); fil_close_all_files();
/* Exit any remaining threads. */ /* Exit any remaining threads. */
srv_shutdown_all_bg_threads(); ut_ad(!buf_page_cleaner_is_active);
srv_shutdown_threads();
if (srv_monitor_file) { if (srv_monitor_file) {
my_fclose(srv_monitor_file, MYF(MY_WME)); my_fclose(srv_monitor_file, MYF(MY_WME));
......
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