summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-08-31 11:08:43 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2017-08-31 11:08:43 +0300
commit38ca9be4de38a4a6688985f3f73d75a2a75665f4 (patch)
treed887745a37193b541e49fddd1f22eebd2a44f9a5
parent28b2896a434670d7b03c4a5e3fba8b4f3872a297 (diff)
downloadmariadb-git-38ca9be4de38a4a6688985f3f73d75a2a75665f4.tar.gz
MDEV-13684 InnoDB race condition between fil_crypt_thread and btr_scrub_init
There is a race condition in InnoDB startup. A number of fil_crypt_thread are created by fil_crypt_threads_init(). These threads may call btr_scrub_complete_space() before btr_scrub_init() was called. Those too early calls would be accessing an uninitialized scrub_stat_mutex. innobase_start_or_create_for_mysql(): Invoke btr_scrub_init() before fil_crypt_threads_init(). fil_crypt_complete_rotate_space(): Only invoke btr_scrub_complete_space() if scrubbing is enabled. There is no need to update the statistics if it is not enabled.
-rw-r--r--storage/innobase/btr/btr0scrub.cc12
-rw-r--r--storage/innobase/fil/fil0crypt.cc3
-rw-r--r--storage/innobase/include/btr0scrub.h11
-rw-r--r--storage/innobase/srv/srv0start.cc4
-rw-r--r--storage/xtradb/btr/btr0scrub.cc12
-rw-r--r--storage/xtradb/fil/fil0crypt.cc3
-rw-r--r--storage/xtradb/include/btr0scrub.h11
-rw-r--r--storage/xtradb/srv/srv0start.cc4
8 files changed, 24 insertions, 36 deletions
diff --git a/storage/innobase/btr/btr0scrub.cc b/storage/innobase/btr/btr0scrub.cc
index 24c84ed301b..1b10b79838d 100644
--- a/storage/innobase/btr/btr0scrub.cc
+++ b/storage/innobase/btr/btr0scrub.cc
@@ -886,17 +886,15 @@ btr_scrub_update_total_stat(btr_scrub_t *scrub_data)
memset(&scrub_data->scrub_stat, 0, sizeof(scrub_data->scrub_stat));
}
-/**************************************************************//**
-Complete iterating a space */
+/** Complete iterating a space.
+@param[in,out] scrub_data scrub data */
UNIV_INTERN
-bool
-btr_scrub_complete_space(
-/*=====================*/
- btr_scrub_t* scrub_data) /*!< in/out: scrub data */
+void
+btr_scrub_complete_space(btr_scrub_t* scrub_data)
{
+ ut_ad(scrub_data->scrubbing);
btr_scrub_table_close_for_thread(scrub_data);
btr_scrub_update_total_stat(scrub_data);
- return scrub_data->scrubbing;
}
/*********************************************************************
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index a388ce4b604..25966e17e75 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -2127,7 +2127,8 @@ fil_crypt_complete_rotate_space(
mutex_exit(&crypt_data->mutex);
/* all threads must call btr_scrub_complete_space wo/ mutex held */
- if (btr_scrub_complete_space(&state->scrub_data) == true) {
+ if (state->scrub_data.scrubbing) {
+ btr_scrub_complete_space(&state->scrub_data);
if (should_flush) {
/* only last thread updates last_scrub_completed */
ut_ad(crypt_data);
diff --git a/storage/innobase/include/btr0scrub.h b/storage/innobase/include/btr0scrub.h
index 608266c206d..8029cc91005 100644
--- a/storage/innobase/include/btr0scrub.h
+++ b/storage/innobase/include/btr0scrub.h
@@ -154,13 +154,10 @@ btr_scrub_start_space(
ulint space, /*!< in: space */
btr_scrub_t* scrub_data); /*!< in/out: scrub data */
-/****************************************************************
-Complete iterating a space
-* @return true if space was scrubbed */
+/** Complete iterating a space.
+@param[in,out] scrub_data scrub data */
UNIV_INTERN
-bool
-btr_scrub_complete_space(
-/*=====================*/
- btr_scrub_t* scrub_data); /*!< in/out: scrub data */
+void
+btr_scrub_complete_space(btr_scrub_t* scrub_data);
#endif
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 0010ec9c002..db52e31881c 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -3030,12 +3030,10 @@ files_checked:
/* Create thread(s) that handles key rotation */
fil_system_enter();
+ btr_scrub_init();
fil_crypt_threads_init();
fil_system_exit();
- /* Init data for datafile scrub threads */
- btr_scrub_init();
-
/* Initialize online defragmentation. */
btr_defragment_init();
btr_defragment_thread_active = true;
diff --git a/storage/xtradb/btr/btr0scrub.cc b/storage/xtradb/btr/btr0scrub.cc
index 24c84ed301b..1b10b79838d 100644
--- a/storage/xtradb/btr/btr0scrub.cc
+++ b/storage/xtradb/btr/btr0scrub.cc
@@ -886,17 +886,15 @@ btr_scrub_update_total_stat(btr_scrub_t *scrub_data)
memset(&scrub_data->scrub_stat, 0, sizeof(scrub_data->scrub_stat));
}
-/**************************************************************//**
-Complete iterating a space */
+/** Complete iterating a space.
+@param[in,out] scrub_data scrub data */
UNIV_INTERN
-bool
-btr_scrub_complete_space(
-/*=====================*/
- btr_scrub_t* scrub_data) /*!< in/out: scrub data */
+void
+btr_scrub_complete_space(btr_scrub_t* scrub_data)
{
+ ut_ad(scrub_data->scrubbing);
btr_scrub_table_close_for_thread(scrub_data);
btr_scrub_update_total_stat(scrub_data);
- return scrub_data->scrubbing;
}
/*********************************************************************
diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc
index a388ce4b604..25966e17e75 100644
--- a/storage/xtradb/fil/fil0crypt.cc
+++ b/storage/xtradb/fil/fil0crypt.cc
@@ -2127,7 +2127,8 @@ fil_crypt_complete_rotate_space(
mutex_exit(&crypt_data->mutex);
/* all threads must call btr_scrub_complete_space wo/ mutex held */
- if (btr_scrub_complete_space(&state->scrub_data) == true) {
+ if (state->scrub_data.scrubbing) {
+ btr_scrub_complete_space(&state->scrub_data);
if (should_flush) {
/* only last thread updates last_scrub_completed */
ut_ad(crypt_data);
diff --git a/storage/xtradb/include/btr0scrub.h b/storage/xtradb/include/btr0scrub.h
index 608266c206d..8029cc91005 100644
--- a/storage/xtradb/include/btr0scrub.h
+++ b/storage/xtradb/include/btr0scrub.h
@@ -154,13 +154,10 @@ btr_scrub_start_space(
ulint space, /*!< in: space */
btr_scrub_t* scrub_data); /*!< in/out: scrub data */
-/****************************************************************
-Complete iterating a space
-* @return true if space was scrubbed */
+/** Complete iterating a space.
+@param[in,out] scrub_data scrub data */
UNIV_INTERN
-bool
-btr_scrub_complete_space(
-/*=====================*/
- btr_scrub_t* scrub_data); /*!< in/out: scrub data */
+void
+btr_scrub_complete_space(btr_scrub_t* scrub_data);
#endif
diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc
index c87b7652c21..94e680d0e80 100644
--- a/storage/xtradb/srv/srv0start.cc
+++ b/storage/xtradb/srv/srv0start.cc
@@ -3146,12 +3146,10 @@ files_checked:
#endif /* WITH_WSREP */
/* Create thread(s) that handles key rotation */
fil_system_enter();
+ btr_scrub_init();
fil_crypt_threads_init();
fil_system_exit();
- /* Init data for datafile scrub threads */
- btr_scrub_init();
-
/* Initialize online defragmentation. */
btr_defragment_init();
btr_defragment_thread_active = true;