Skip to content
Permalink
Browse files
Avoid a hang when InnoDB startup is aborted during redo log apply
buf_flush_page_cleaner_coordinator: In the first loop, use an
appropriate termination condition, waiting for !recv_writer_thread_active.

logs_empty_and_mark_files_at_shutdown(): Signal recv_sys->flush_start
in case the recv_writer_thread was never started, or
buf_flush_page_cleaner_coordinator failed to notice its termination.

innobase_start_or_create_for_mysql(): Remove a redundant, unreachable
condition, and properly release resources when aborting startup due to
recv_sys->found_corrupt_log.
  • Loading branch information
dr-m committed Jul 5, 2017
1 parent f6633bf commit 72a2de9
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 25 deletions.
@@ -3126,16 +3126,13 @@ pools. As of now we'll have only one coordinator.
@return a dummy parameter */
extern "C"
os_thread_ret_t
DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(
/*===============================================*/
void* arg MY_ATTRIBUTE((unused)))
/*!< in: a dummy parameter required by
os_thread_create */
DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(void*)
{
my_thread_init();
#ifdef UNIV_PFS_THREAD
pfs_register_thread(page_cleaner_thread_key);
#endif /* UNIV_PFS_THREAD */
ut_ad(!srv_read_only_mode);

#ifdef UNIV_DEBUG_THREAD_CREATION
ib::info() << "page_cleaner thread running, id "
@@ -3158,17 +3155,14 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(
os_event_set(recv_sys->flush_end);
#endif /* UNIV_LINUX */

while (!srv_read_only_mode
&& srv_shutdown_state == SRV_SHUTDOWN_NONE
&& recv_sys->heap != NULL) {
do {
/* treat flushing requests during recovery. */
ulint n_flushed_lru = 0;
ulint n_flushed_list = 0;

os_event_wait(recv_sys->flush_start);

if (srv_shutdown_state != SRV_SHUTDOWN_NONE
|| recv_sys->heap == NULL) {
if (!recv_writer_thread_active) {
break;
}

@@ -3195,7 +3189,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(

os_event_reset(recv_sys->flush_start);
os_event_set(recv_sys->flush_end);
}
} while (recv_writer_thread_active);

os_event_wait(buf_flush_event);

@@ -38,6 +38,9 @@ Created 9/20/1997 Heikki Tuuri
#include <list>
#include <vector>

/** Is recv_writer_thread active? */
extern bool recv_writer_thread_active;

/** @return whether recovery is currently running. */
#define recv_recovery_is_on() recv_recovery_on

@@ -1901,6 +1901,12 @@ logs_empty_and_mark_files_at_shutdown(void)
} else {
ut_ad(!srv_dict_stats_thread_active);
}
if (recv_sys && recv_sys->flush_start) {
/* This is in case recv_writer_thread was never
started, or buf_flush_page_cleaner_coordinator
failed to notice its termination. */
os_event_set(recv_sys->flush_start);
}
}
os_thread_sleep(100000);

@@ -124,8 +124,8 @@ mysql_pfs_key_t trx_rollback_clean_thread_key;
mysql_pfs_key_t recv_writer_thread_key;
#endif /* UNIV_PFS_THREAD */

/** Flag indicating if recv_writer thread is active. */
static volatile bool recv_writer_thread_active;
/** Is recv_writer_thread active? */
bool recv_writer_thread_active;

#ifndef DBUG_OFF
/** Return string name of the redo log record type.
@@ -2248,7 +2248,7 @@ innobase_start_or_create_for_mysql()
recv_apply_hashed_log_recs(true);

if (recv_sys->found_corrupt_log) {
return (DB_CORRUPTION);
return(srv_init_abort(DB_CORRUPTION));
}

DBUG_PRINT("ib_log", ("apply completed"));
@@ -2258,17 +2258,6 @@ innobase_start_or_create_for_mysql()
}
}

if (recv_sys->found_corrupt_log) {
ib::warn()
<< "The log file may have been corrupt and it"
" is possible that the log scan or parsing"
" did not proceed far enough in recovery."
" Please run CHECK TABLE on your InnoDB tables"
" to check that they are ok!"
" It may be safest to recover your"
" InnoDB database from a backup!";
}

if (!srv_read_only_mode) {
const ulint flags = FSP_FLAGS_PAGE_SSIZE();
for (ulint id = 0; id <= srv_undo_tablespaces; id++) {

0 comments on commit 72a2de9

Please sign in to comment.