Commit 72a2de92 authored by Marko Mäkelä's avatar Marko Mäkelä

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.
parent f6633bf0
......@@ -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++) {
......
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