diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2017-08-31 11:08:43 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2017-08-31 11:08:43 +0300 |
commit | 38ca9be4de38a4a6688985f3f73d75a2a75665f4 (patch) | |
tree | d887745a37193b541e49fddd1f22eebd2a44f9a5 | |
parent | 28b2896a434670d7b03c4a5e3fba8b4f3872a297 (diff) | |
download | mariadb-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.cc | 12 | ||||
-rw-r--r-- | storage/innobase/fil/fil0crypt.cc | 3 | ||||
-rw-r--r-- | storage/innobase/include/btr0scrub.h | 11 | ||||
-rw-r--r-- | storage/innobase/srv/srv0start.cc | 4 | ||||
-rw-r--r-- | storage/xtradb/btr/btr0scrub.cc | 12 | ||||
-rw-r--r-- | storage/xtradb/fil/fil0crypt.cc | 3 | ||||
-rw-r--r-- | storage/xtradb/include/btr0scrub.h | 11 | ||||
-rw-r--r-- | storage/xtradb/srv/srv0start.cc | 4 |
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; |