diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2017-07-05 22:09:28 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2017-07-05 22:09:28 +0300 |
commit | 72a2de92a12dd7a1d6b0294bb9aa36411ad60fc3 (patch) | |
tree | 3eacbfc81784c2dcedceffa29879447aa0b2d34f /storage/innobase | |
parent | f6633bf058802ad7da8196d01fd19d75c53f7274 (diff) | |
download | mariadb-git-72a2de92a12dd7a1d6b0294bb9aa36411ad60fc3.tar.gz |
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.
Diffstat (limited to 'storage/innobase')
-rw-r--r-- | storage/innobase/buf/buf0flu.cc | 16 | ||||
-rw-r--r-- | storage/innobase/include/log0recv.h | 3 | ||||
-rw-r--r-- | storage/innobase/log/log0log.cc | 6 | ||||
-rw-r--r-- | storage/innobase/log/log0recv.cc | 4 | ||||
-rw-r--r-- | storage/innobase/srv/srv0start.cc | 13 |
5 files changed, 17 insertions, 25 deletions
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index 541091d845f..24971cfebd4 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -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); diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h index 744ad79f589..24ad9ae2a30 100644 --- a/storage/innobase/include/log0recv.h +++ b/storage/innobase/include/log0recv.h @@ -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 diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 2e8d8233fd5..9a61e2067a4 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -1901,6 +1901,12 @@ loop: } 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); diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 81c60922d71..ff7523a2954 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -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. diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 64ddb5a7ec5..46a757be5be 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -2248,7 +2248,7 @@ files_checked: 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 @@ files_checked: } } - 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++) { |