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. ...@@ -3126,16 +3126,13 @@ pools. As of now we'll have only one coordinator.
@return a dummy parameter */ @return a dummy parameter */
extern "C" extern "C"
os_thread_ret_t os_thread_ret_t
DECLARE_THREAD(buf_flush_page_cleaner_coordinator)( DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(void*)
/*===============================================*/
void* arg MY_ATTRIBUTE((unused)))
/*!< in: a dummy parameter required by
os_thread_create */
{ {
my_thread_init(); my_thread_init();
#ifdef UNIV_PFS_THREAD #ifdef UNIV_PFS_THREAD
pfs_register_thread(page_cleaner_thread_key); pfs_register_thread(page_cleaner_thread_key);
#endif /* UNIV_PFS_THREAD */ #endif /* UNIV_PFS_THREAD */
ut_ad(!srv_read_only_mode);
#ifdef UNIV_DEBUG_THREAD_CREATION #ifdef UNIV_DEBUG_THREAD_CREATION
ib::info() << "page_cleaner thread running, id " ib::info() << "page_cleaner thread running, id "
...@@ -3158,17 +3155,14 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)( ...@@ -3158,17 +3155,14 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(
os_event_set(recv_sys->flush_end); os_event_set(recv_sys->flush_end);
#endif /* UNIV_LINUX */ #endif /* UNIV_LINUX */
while (!srv_read_only_mode do {
&& srv_shutdown_state == SRV_SHUTDOWN_NONE
&& recv_sys->heap != NULL) {
/* treat flushing requests during recovery. */ /* treat flushing requests during recovery. */
ulint n_flushed_lru = 0; ulint n_flushed_lru = 0;
ulint n_flushed_list = 0; ulint n_flushed_list = 0;
os_event_wait(recv_sys->flush_start); os_event_wait(recv_sys->flush_start);
if (srv_shutdown_state != SRV_SHUTDOWN_NONE if (!recv_writer_thread_active) {
|| recv_sys->heap == NULL) {
break; break;
} }
...@@ -3195,7 +3189,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)( ...@@ -3195,7 +3189,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(
os_event_reset(recv_sys->flush_start); os_event_reset(recv_sys->flush_start);
os_event_set(recv_sys->flush_end); os_event_set(recv_sys->flush_end);
} } while (recv_writer_thread_active);
os_event_wait(buf_flush_event); os_event_wait(buf_flush_event);
......
...@@ -38,6 +38,9 @@ Created 9/20/1997 Heikki Tuuri ...@@ -38,6 +38,9 @@ Created 9/20/1997 Heikki Tuuri
#include <list> #include <list>
#include <vector> #include <vector>
/** Is recv_writer_thread active? */
extern bool recv_writer_thread_active;
/** @return whether recovery is currently running. */ /** @return whether recovery is currently running. */
#define recv_recovery_is_on() recv_recovery_on #define recv_recovery_is_on() recv_recovery_on
......
...@@ -1901,6 +1901,12 @@ logs_empty_and_mark_files_at_shutdown(void) ...@@ -1901,6 +1901,12 @@ logs_empty_and_mark_files_at_shutdown(void)
} else { } else {
ut_ad(!srv_dict_stats_thread_active); 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); os_thread_sleep(100000);
......
...@@ -124,8 +124,8 @@ mysql_pfs_key_t trx_rollback_clean_thread_key; ...@@ -124,8 +124,8 @@ mysql_pfs_key_t trx_rollback_clean_thread_key;
mysql_pfs_key_t recv_writer_thread_key; mysql_pfs_key_t recv_writer_thread_key;
#endif /* UNIV_PFS_THREAD */ #endif /* UNIV_PFS_THREAD */
/** Flag indicating if recv_writer thread is active. */ /** Is recv_writer_thread active? */
static volatile bool recv_writer_thread_active; bool recv_writer_thread_active;
#ifndef DBUG_OFF #ifndef DBUG_OFF
/** Return string name of the redo log record type. /** Return string name of the redo log record type.
......
...@@ -2248,7 +2248,7 @@ innobase_start_or_create_for_mysql() ...@@ -2248,7 +2248,7 @@ innobase_start_or_create_for_mysql()
recv_apply_hashed_log_recs(true); recv_apply_hashed_log_recs(true);
if (recv_sys->found_corrupt_log) { if (recv_sys->found_corrupt_log) {
return (DB_CORRUPTION); return(srv_init_abort(DB_CORRUPTION));
} }
DBUG_PRINT("ib_log", ("apply completed")); DBUG_PRINT("ib_log", ("apply completed"));
...@@ -2258,17 +2258,6 @@ innobase_start_or_create_for_mysql() ...@@ -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) { if (!srv_read_only_mode) {
const ulint flags = FSP_FLAGS_PAGE_SSIZE(); const ulint flags = FSP_FLAGS_PAGE_SSIZE();
for (ulint id = 0; id <= srv_undo_tablespaces; id++) { 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