diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-01-25 16:35:13 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-01-25 16:35:13 +0200 |
commit | 9bd80ada6facfb4ae3d159f3c924c1845c8d3481 (patch) | |
tree | 745635d87a79c9f9920180e6cbcd9c8ceb055f8d | |
parent | f2518f3da9d0c6386e69db364fbf8df9db12a2ee (diff) | |
parent | 31d0727a103b5f8e983bd89d0ddd0dbe2a2278f2 (diff) | |
download | mariadb-git-9bd80ada6facfb4ae3d159f3c924c1845c8d3481.tar.gz |
Merge 10.2 into 10.3
-rw-r--r-- | mysql-test/suite/innodb/r/instant_varchar_enlarge.result | 9 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/instant_varchar_enlarge.test | 8 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 117 | ||||
-rw-r--r-- | storage/innobase/include/fil0fil.h | 25 |
4 files changed, 71 insertions, 88 deletions
diff --git a/mysql-test/suite/innodb/r/instant_varchar_enlarge.result b/mysql-test/suite/innodb/r/instant_varchar_enlarge.result new file mode 100644 index 00000000000..14f16bd4fe2 --- /dev/null +++ b/mysql-test/suite/innodb/r/instant_varchar_enlarge.result @@ -0,0 +1,9 @@ +create table t (a varchar(100)) engine=innodb; +select name, pos, mtype, prtype, len from information_schema.innodb_sys_columns where name='a'; +name pos mtype prtype len +a 0 1 524303 100 +alter table t modify a varchar(110), algorithm=inplace; +select name, pos, mtype, prtype, len from information_schema.innodb_sys_columns where name='a'; +name pos mtype prtype len +a 0 1 524303 110 +drop table t; diff --git a/mysql-test/suite/innodb/t/instant_varchar_enlarge.test b/mysql-test/suite/innodb/t/instant_varchar_enlarge.test new file mode 100644 index 00000000000..42689deca11 --- /dev/null +++ b/mysql-test/suite/innodb/t/instant_varchar_enlarge.test @@ -0,0 +1,8 @@ +--source include/have_innodb.inc + +# LEN must increase here +create table t (a varchar(100)) engine=innodb; +select name, pos, mtype, prtype, len from information_schema.innodb_sys_columns where name='a'; +alter table t modify a varchar(110), algorithm=inplace; +select name, pos, mtype, prtype, len from information_schema.innodb_sys_columns where name='a'; +drop table t; diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index a0630a74bd4..b1dff700e48 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -421,7 +421,7 @@ fil_space_is_flushed( node != NULL; node = UT_LIST_GET_NEXT(chain, node)) { - if (node->modification_counter > node->flush_counter) { + if (node->needs_flush) { ut_ad(!fil_buffering_disabled(space)); return(false); @@ -458,8 +458,6 @@ fil_node_t* fil_space_t::add(const char* name, pfs_os_file_t handle, ut_a(!is_raw || srv_start_raw_disk_in_use); - node->sync_event = os_event_create("fsync_event"); - node->is_raw_disk = is_raw; node->size = size; @@ -692,7 +690,7 @@ void fil_node_t::close() ut_a(n_pending == 0); ut_a(n_pending_flushes == 0); ut_a(!being_extended); - ut_a(modification_counter == flush_counter + ut_a(!needs_flush || space->purpose == FIL_TYPE_TEMPORARY || srv_fast_shutdown == 2 || !srv_was_started); @@ -741,7 +739,7 @@ fil_try_to_close_file_in_LRU( node != NULL; node = UT_LIST_GET_PREV(LRU, node)) { - if (node->modification_counter == node->flush_counter + if (!node->needs_flush && node->n_pending_flushes == 0 && !node->being_extended) { @@ -761,11 +759,9 @@ fil_try_to_close_file_in_LRU( << node->n_pending_flushes; } - if (node->modification_counter != node->flush_counter) { + if (node->needs_flush) { ib::warn() << "Cannot close file " << node->name - << ", because modification count " - << node->modification_counter << - " != flush count " << node->flush_counter; + << ", because is should be flushed first"; } if (node->being_extended) { @@ -790,7 +786,7 @@ static void fil_flush_low(fil_space_t* space, bool metadata = false) /* No need to flush. User has explicitly disabled buffering. */ - ut_ad(!space->is_in_unflushed_spaces); + ut_ad(!space->is_in_unflushed_spaces()); ut_ad(fil_space_is_flushed(space)); ut_ad(space->n_pending_flushes == 0); @@ -798,8 +794,7 @@ static void fil_flush_low(fil_space_t* space, bool metadata = false) for (fil_node_t* node = UT_LIST_GET_FIRST(space->chain); node != NULL; node = UT_LIST_GET_NEXT(chain, node)) { - ut_ad(node->modification_counter - == node->flush_counter); + ut_ad(!node->needs_flush); ut_ad(node->n_pending_flushes == 0); } #endif /* UNIV_DEBUG */ @@ -814,9 +809,7 @@ static void fil_flush_low(fil_space_t* space, bool metadata = false) node != NULL; node = UT_LIST_GET_NEXT(chain, node)) { - int64_t old_mod_counter = node->modification_counter; - - if (old_mod_counter <= node->flush_counter) { + if (!node->needs_flush) { continue; } @@ -840,31 +833,10 @@ static void fil_flush_low(fil_space_t* space, bool metadata = false) goto skip_flush; } #endif /* _WIN32 */ -retry: - if (node->n_pending_flushes > 0) { - /* We want to avoid calling os_file_flush() on - the file twice at the same time, because we do - not know what bugs OS's may contain in file - i/o */ - - int64_t sig_count = os_event_reset(node->sync_event); - - mutex_exit(&fil_system.mutex); - - os_event_wait_low(node->sync_event, sig_count); - - mutex_enter(&fil_system.mutex); - - if (node->flush_counter >= old_mod_counter) { - - goto skip_flush; - } - - goto retry; - } ut_a(node->is_open()); node->n_pending_flushes++; + node->needs_flush = false; mutex_exit(&fil_system.mutex); @@ -872,18 +844,14 @@ retry: mutex_enter(&fil_system.mutex); - os_event_set(node->sync_event); - node->n_pending_flushes--; +#ifdef _WIN32 skip_flush: - if (node->flush_counter < old_mod_counter) { - node->flush_counter = old_mod_counter; - - if (space->is_in_unflushed_spaces +#endif /* _WIN32 */ + if (!node->needs_flush) { + if (space->is_in_unflushed_spaces() && fil_space_is_flushed(space)) { - space->is_in_unflushed_spaces = false; - UT_LIST_REMOVE( fil_system.unflushed_spaces, space); @@ -1178,19 +1146,16 @@ fil_node_close_to_free( /* We fool the assertion in fil_node_t::close() to think there are no unflushed modifications in the file */ - node->modification_counter = node->flush_counter; - os_event_set(node->sync_event); + node->needs_flush = false; if (fil_buffering_disabled(space)) { - ut_ad(!space->is_in_unflushed_spaces); + ut_ad(!space->is_in_unflushed_spaces()); ut_ad(fil_space_is_flushed(space)); - } else if (space->is_in_unflushed_spaces + } else if (space->is_in_unflushed_spaces() && fil_space_is_flushed(space)) { - space->is_in_unflushed_spaces = false; - UT_LIST_REMOVE(fil_system.unflushed_spaces, space); } @@ -1211,16 +1176,14 @@ fil_space_detach( HASH_DELETE(fil_space_t, hash, fil_system.spaces, space->id, space); - if (space->is_in_unflushed_spaces) { + if (space->is_in_unflushed_spaces()) { ut_ad(!fil_buffering_disabled(space)); - space->is_in_unflushed_spaces = false; UT_LIST_REMOVE(fil_system.unflushed_spaces, space); } - if (space->is_in_rotation_list) { - space->is_in_rotation_list = false; + if (space->is_in_rotation_list()) { UT_LIST_REMOVE(fil_system.rotation_list, space); } @@ -1266,7 +1229,6 @@ fil_space_free_low( for (fil_node_t* node = UT_LIST_GET_FIRST(space->chain); node != NULL; ) { ut_d(space->size -= node->size); - os_event_destroy(node->sync_event); ut_free(node->name); fil_node_t* old_node = node; node = UT_LIST_GET_NEXT(chain, node); @@ -1442,11 +1404,8 @@ fil_space_create( /* Key rotation is not enabled, need to inform background encryption threads. */ UT_LIST_ADD_LAST(fil_system.rotation_list, space); - space->is_in_rotation_list = true; mutex_exit(&fil_system.mutex); - mutex_enter(&fil_crypt_threads_mutex); os_event_set(fil_crypt_threads_event); - mutex_exit(&fil_crypt_threads_mutex); } else { mutex_exit(&fil_system.mutex); } @@ -4112,24 +4071,21 @@ fil_node_complete_io(fil_node_t* node, const IORequest& type) ut_ad(!srv_read_only_mode || node->space->purpose == FIL_TYPE_TEMPORARY); - ++fil_system.modification_counter; - - node->modification_counter = fil_system.modification_counter; - if (fil_buffering_disabled(node->space)) { /* We don't need to keep track of unflushed changes as user has explicitly disabled buffering. */ - ut_ad(!node->space->is_in_unflushed_spaces); - node->flush_counter = node->modification_counter; - - } else if (!node->space->is_in_unflushed_spaces) { + ut_ad(!node->space->is_in_unflushed_spaces()); + ut_ad(node->needs_flush == false); - node->space->is_in_unflushed_spaces = true; + } else { + node->needs_flush = true; - UT_LIST_ADD_FIRST( - fil_system.unflushed_spaces, node->space); + if (!node->space->is_in_unflushed_spaces()) { + UT_LIST_ADD_FIRST(fil_system.unflushed_spaces, + node->space); + } } } @@ -5255,8 +5211,7 @@ fil_space_remove_from_keyrotation(fil_space_t* space) ut_ad(mutex_own(&fil_system.mutex)); ut_ad(space); - if (space->is_in_rotation_list && !space->referenced()) { - space->is_in_rotation_list = false; + if (!space->referenced() && space->is_in_rotation_list()) { ut_a(UT_LIST_GET_LEN(fil_system.rotation_list) > 0); UT_LIST_REMOVE(fil_system.rotation_list, space); } @@ -5397,3 +5352,21 @@ fil_space_set_punch_hole( { node->space->punch_hole = val; } + +/** Checks that this tablespace in a list of unflushed tablespaces. +@return true if in a list */ +bool fil_space_t::is_in_unflushed_spaces() const { + ut_ad(mutex_own(&fil_system.mutex)); + + return fil_system.unflushed_spaces.start == this + || unflushed_spaces.next || unflushed_spaces.prev; +} + +/** Checks that this tablespace needs key rotation. +@return true if in a rotation list */ +bool fil_space_t::is_in_rotation_list() const { + ut_ad(mutex_own(&fil_system.mutex)); + + return fil_system.rotation_list.start == this || rotation_list.next + || rotation_list.prev; +} diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index e6998b55ca3..0a5c1a5cfc5 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -154,15 +154,16 @@ struct fil_space_t { UT_LIST_NODE_T(fil_space_t) named_spaces; /*!< list of spaces for which MLOG_FILE_NAME records have been issued */ - bool is_in_unflushed_spaces; - /*!< true if this space is currently in - unflushed_spaces */ + /** Checks that this tablespace in a list of unflushed tablespaces. + @return true if in a list */ + bool is_in_unflushed_spaces() const; UT_LIST_NODE_T(fil_space_t) space_list; /*!< list of all spaces */ /** other tablespaces needing key rotation */ UT_LIST_NODE_T(fil_space_t) rotation_list; - /** whether this tablespace needs key rotation */ - bool is_in_rotation_list; + /** Checks that this tablespace needs key rotation. + @return true if in a rotation list */ + bool is_in_rotation_list() const; /** MariaDB encryption data */ fil_space_crypt_t* crypt_data; @@ -289,10 +290,6 @@ struct fil_node_t { char* name; /** file handle (valid if is_open) */ pfs_os_file_t handle; - /** event that groups and serializes calls to fsync; - os_event_set() and os_event_reset() are protected by - fil_system.mutex */ - os_event_t sync_event; /** whether the file actually is a raw device or disk partition */ bool is_raw_disk; /** size of the file in database pages (0 if not known yet); @@ -310,10 +307,8 @@ struct fil_node_t { ulint n_pending_flushes; /** whether the file is currently being extended */ bool being_extended; - /** number of writes to the file since the system was started */ - int64_t modification_counter; - /** the modification_counter of the latest flush to disk */ - int64_t flush_counter; + /** whether this file had writes after lasy fsync() */ + bool needs_flush; /** link to other files in this tablespace */ UT_LIST_NODE_T(fil_node_t) chain; /** link to the fil_system.LRU list (keeping track of open files) */ @@ -617,10 +612,8 @@ public: tablespaces whose files contain unflushed writes; those spaces have at least one file node where - modification_counter > flush_counter */ + needs_flush == true */ ulint n_open; /*!< number of files currently open */ - int64_t modification_counter;/*!< when we write to a file we - increment this by one */ ulint max_assigned_id;/*!< maximum space id in the existing tables, or assigned during the time mysqld has been up; at an InnoDB |