summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-07-05 22:09:28 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2017-07-05 22:09:28 +0300
commit72a2de92a12dd7a1d6b0294bb9aa36411ad60fc3 (patch)
tree3eacbfc81784c2dcedceffa29879447aa0b2d34f /storage/innobase
parentf6633bf058802ad7da8196d01fd19d75c53f7274 (diff)
downloadmariadb-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.cc16
-rw-r--r--storage/innobase/include/log0recv.h3
-rw-r--r--storage/innobase/log/log0log.cc6
-rw-r--r--storage/innobase/log/log0recv.cc4
-rw-r--r--storage/innobase/srv/srv0start.cc13
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++) {