Skip to content

Commit 5999d51

Browse files
committed
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.
1 parent d8515c8 commit 5999d51

File tree

5 files changed

+32
-62
lines changed

5 files changed

+32
-62
lines changed

extra/mariabackup/xtrabackup.cc

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3418,15 +3418,11 @@ xb_data_files_init()
34183418
return(xb_load_tablespaces());
34193419
}
34203420

3421-
/************************************************************************
3422-
Destroy the tablespace memory cache. */
3423-
static
3424-
void
3425-
xb_data_files_close()
3421+
/** Destroy the tablespace memory cache. */
3422+
static void xb_data_files_close()
34263423
{
3427-
ut_ad(!os_thread_count);
3428-
fil_close_all_files();
3429-
buf_dblwr.close();
3424+
fil_close_all_files();
3425+
buf_dblwr.close();
34303426
}
34313427

34323428
/***********************************************************************

storage/innobase/buf/buf0flu.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1987,7 +1987,10 @@ static os_thread_ret_t DECLARE_THREAD(buf_flush_page_cleaner)(void*)
19871987
buf_flush_wait_batch_end_acquiring_mutex(false);
19881988
}
19891989

1990+
mysql_mutex_lock(&buf_pool.flush_list_mutex);
19901991
buf_page_cleaner_is_active = false;
1992+
mysql_cond_broadcast(&buf_pool.done_flush_list);
1993+
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
19911994

19921995
my_thread_end();
19931996
/* We count the number of threads in os_thread_exit(). A created

storage/innobase/include/os0thread.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,6 @@ typedef void* (*os_posix_f_t) (void*);
6666
typedef unsigned int mysql_pfs_key_t;
6767
#endif /* HAVE_PSI_INTERFACE */
6868

69-
/** Number of threads active. */
70-
externAtomic_counter<ulint>os_thread_count;
71-
7269
/***************************************************************//**
7370
Compares two thread ids for equality.
7471
@return TRUE if equal */

storage/innobase/os/os0thread.cc

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ Created 9/8/1995 Heikki Tuuri
2727
#include "univ.i"
2828
#include "srv0srv.h"
2929

30-
/** Number of threads active. */
31-
Atomic_counter<ulint> os_thread_count;
32-
3330
/***************************************************************//**
3431
Compares two thread ids for equality.
3532
@return TRUE if equal */
@@ -110,8 +107,6 @@ os_thread_t os_thread_create(os_thread_func_t func, void *arg)
110107

111108
CloseHandle(handle);
112109

113-
os_thread_count++;
114-
115110
return((os_thread_t)new_thread_id);
116111
#else /* _WIN32 else */
117112

@@ -125,8 +120,6 @@ os_thread_t os_thread_create(os_thread_func_t func, void *arg)
125120
abort();
126121
}
127122

128-
os_thread_count++;
129-
130123
ret = pthread_create(&new_thread_id, &attr, func, arg);
131124

132125
ut_a(ret == 0);
@@ -135,8 +128,6 @@ os_thread_t os_thread_create(os_thread_func_t func, void *arg)
135128

136129
#endif /* not _WIN32 */
137130

138-
ut_a(os_thread_count <= srv_max_n_threads);
139-
140131
return((os_thread_t)new_thread_id);
141132
}
142133

@@ -152,8 +143,6 @@ ATTRIBUTE_NORETURN void os_thread_exit()
152143
pfs_delete_thread();
153144
#endif
154145

155-
os_thread_count--;
156-
157146
#ifdef _WIN32
158147
ExitThread(0);
159148
#else

storage/innobase/srv/srv0start.cc

Lines changed: 25 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -822,11 +822,8 @@ srv_open_tmp_tablespace(bool create_new_db)
822822
return(err);
823823
}
824824

825-
/**
826-
Shutdown all background threads created by InnoDB. */
827-
static
828-
void
829-
srv_shutdown_all_bg_threads()
825+
/** Shutdown background threads, except the page cleaner. */
826+
static void srv_shutdown_threads()
830827
{
831828
ut_ad(!srv_undo_sources);
832829
srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS;
@@ -838,38 +835,9 @@ srv_shutdown_all_bg_threads()
838835
srv_purge_shutdown();
839836
}
840837

841-
/* All threads end up waiting for certain events. Put those events
842-
to the signaled state. Then the threads will exit themselves after
843-
os_event_wait(). */
844-
for (uint i = 0; i < 1000; ++i) {
845-
/* NOTE: IF YOU CREATE THREADS IN INNODB, YOU MUST EXIT THEM
846-
HERE OR EARLIER */
847-
848-
if (!srv_read_only_mode) {
849-
/* b. srv error monitor thread exits automatically,
850-
no need to do anything here */
851-
if (srv_n_fil_crypt_threads_started) {
852-
os_event_set(fil_crypt_threads_event);
853-
}
854-
}
855-
856-
if (buf_page_cleaner_is_active) {
857-
ut_ad(!srv_read_only_mode);
858-
859-
/* e. Exit the buf_flush_page_cleaner */
860-
mysql_cond_signal(&buf_pool.do_flush_list);
861-
}
862-
863-
if (!os_thread_count) {
864-
return;
865-
}
866-
867-
os_thread_sleep(100000);
838+
if (srv_n_fil_crypt_threads) {
839+
fil_crypt_set_thread_cnt(0);
868840
}
869-
870-
ib::warn() << os_thread_count << " threads created by InnoDB"
871-
" had not exited at shutdown!";
872-
ut_ad(0);
873841
}
874842

875843
#ifdef UNIV_DEBUG
@@ -916,7 +884,7 @@ srv_init_abort_low(
916884
}
917885

918886
srv_shutdown_bg_undo_sources();
919-
srv_shutdown_all_bg_threads();
887+
srv_shutdown_threads();
920888
return(err);
921889
}
922890

@@ -1972,9 +1940,10 @@ dberr_t srv_start(bool create_new_db)
19721940
/** Shut down background threads that can generate undo log. */
19731941
void srv_shutdown_bg_undo_sources()
19741942
{
1943+
srv_shutdown_state = SRV_SHUTDOWN_INITIATED;
1944+
19751945
if (srv_undo_sources) {
19761946
ut_ad(!srv_read_only_mode);
1977-
srv_shutdown_state = SRV_SHUTDOWN_INITIATED;
19781947
fts_optimize_shutdown();
19791948
dict_stats_shutdown();
19801949
while (row_get_background_drop_list_len_low()) {
@@ -2010,6 +1979,9 @@ void innodb_preshutdown()
20101979
}
20111980
srv_shutdown_bg_undo_sources();
20121981
srv_purge_shutdown();
1982+
1983+
if (srv_n_fil_crypt_threads)
1984+
fil_crypt_set_thread_cnt(0);
20131985
}
20141986

20151987

@@ -2020,9 +1992,21 @@ void innodb_shutdown()
20201992
ut_ad(!srv_undo_sources);
20211993
switch (srv_operation) {
20221994
case SRV_OPERATION_BACKUP:
2023-
case SRV_OPERATION_RESTORE:
20241995
case SRV_OPERATION_RESTORE_DELTA:
1996+
break;
1997+
case SRV_OPERATION_RESTORE:
20251998
case SRV_OPERATION_RESTORE_EXPORT:
1999+
srv_shutdown_state = SRV_SHUTDOWN_CLEANUP;
2000+
if (!buf_page_cleaner_is_active) {
2001+
break;
2002+
}
2003+
mysql_mutex_lock(&buf_pool.flush_list_mutex);
2004+
while (buf_page_cleaner_is_active) {
2005+
mysql_cond_signal(&buf_pool.do_flush_list);
2006+
mysql_cond_wait(&buf_pool.done_flush_list,
2007+
&buf_pool.flush_list_mutex);
2008+
}
2009+
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
20262010
break;
20272011
case SRV_OPERATION_NORMAL:
20282012
/* Shut down the persistent files. */
@@ -2032,7 +2016,8 @@ void innodb_shutdown()
20322016
os_aio_free();
20332017
fil_close_all_files();
20342018
/* Exit any remaining threads. */
2035-
srv_shutdown_all_bg_threads();
2019+
ut_ad(!buf_page_cleaner_is_active);
2020+
srv_shutdown_threads();
20362021

20372022
if (srv_monitor_file) {
20382023
my_fclose(srv_monitor_file, MYF(MY_WME));

0 commit comments

Comments
 (0)