From b090f85ff72bc8e20597005914b5f622ed0bff9a Mon Sep 17 00:00:00 2001 From: Mark Callaghan Date: Wed, 9 Feb 2011 12:12:20 -0800 Subject: [PATCH] s --- storage/innodb_plugin/fil/fil0fil.c | 28 ++++++++++++++++++++++++++++ storage/innodb_plugin/include/fil0fil.h | 5 +++++ 2 files changed, 33 insertions(+), 0 deletions(-) diff --git a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c index 1a21d9a..e50a6ae 100644 --- a/storage/innodb_plugin/fil/fil0fil.c +++ b/storage/innodb_plugin/fil/fil0fil.c @@ -1074,6 +1074,9 @@ try_again: rw_lock_create(&space->latch, SYNC_FSP); + pthread_cond_init(&space->extend_cond, NULL); + space->extend_in_progress = FALSE; + HASH_INSERT(fil_space_t, hash, fil_system->spaces, id, space); HASH_INSERT(fil_space_t, name_hash, fil_system->name_hash, @@ -1222,6 +1225,9 @@ fil_space_free( rw_lock_free(&(space->latch)); + pthread_cond_destroy(&(space->extend_cond)); + ut_ad(space->extend_in_progress == FALSE); + mem_free(space->name); mem_free(space); @@ -4217,6 +4223,17 @@ fil_extend_space_to_desired_size( fil_node_prepare_for_io(node, fil_system, space); + /* Wait until another thread is not extending this space because when + disk IO is done below fil_system->mutex will be released. This must be + done after fil_node_prepare_for_io increments n_pending to prevent + others from dropping or renaming the tablespace after this briefly + drops fil_system->mutex while IO is in progress. */ + + while (space->extend_in_progress) { + pthread_cond_wait(&space->extend_cond, &fil_system->mutex); + } + space->extend_in_progress = TRUE; + start_page_no = space->size; file_start_page_no = space->size - node->size; @@ -4236,6 +4253,10 @@ fil_extend_space_to_desired_size( offset_low = ((start_page_no - file_start_page_no) % (4096 * ((1024 * 1024) / page_size))) * page_size; + + /* Don't stall others -- see http://bugs.mysql.com/56433 */ + mutex_exit(&fil_system->mutex); + #ifdef UNIV_HOTBACKUP success = os_file_write(node->name, node->handle, buf, offset_low, offset_high, @@ -4247,6 +4268,9 @@ fil_extend_space_to_desired_size( page_size * n_pages, NULL, NULL, &space->io_perf2, NULL); #endif + + mutex_enter(&fil_system->mutex); + if (success) { node->size += n_pages; space->size += n_pages; @@ -4291,6 +4315,10 @@ fil_extend_space_to_desired_size( /* printf("Extended %s to %lu, actual size %lu pages\n", space->name, size_after_extend, *actual_size); */ + + space->extend_in_progress = FALSE; + pthread_cond_broadcast(&space->extend_cond); + mutex_exit(&fil_system->mutex); fil_flush(space_id, FLUSH_FROM_OTHER); diff --git a/storage/innodb_plugin/include/fil0fil.h b/storage/innodb_plugin/include/fil0fil.h index bef44f7..8f4c8f2 100644 --- a/storage/innodb_plugin/include/fil0fil.h +++ b/storage/innodb_plugin/include/fil0fil.h @@ -253,6 +253,9 @@ struct fil_space_struct { #ifndef UNIV_HOTBACKUP rw_lock_t latch; /*!< latch protecting the file space storage allocation */ + pthread_cond_t extend_cond; + /*!< When file is being extended wait on this + until extend_in_progress is FALSE */ #endif /* !UNIV_HOTBACKUP */ UT_LIST_NODE_T(fil_space_t) unflushed_spaces; /*!< list of spaces with at least one unflushed @@ -263,6 +266,8 @@ struct fil_space_struct { /*!< list of all spaces */ os_io_perf2_t io_perf2;/*!< per tablespace IO perf counters */ ulint magic_n;/*!< FIL_SPACE_MAGIC_N */ + ibool extend_in_progress; + /*!< TRUE when file is being extended */ }; /** Value of fil_space_struct::magic_n */ -- 1.7.3.2.146.gca209