summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-01-25 16:35:13 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2019-01-25 16:35:13 +0200
commit9bd80ada6facfb4ae3d159f3c924c1845c8d3481 (patch)
tree745635d87a79c9f9920180e6cbcd9c8ceb055f8d
parentf2518f3da9d0c6386e69db364fbf8df9db12a2ee (diff)
parent31d0727a103b5f8e983bd89d0ddd0dbe2a2278f2 (diff)
downloadmariadb-git-9bd80ada6facfb4ae3d159f3c924c1845c8d3481.tar.gz
Merge 10.2 into 10.3
-rw-r--r--mysql-test/suite/innodb/r/instant_varchar_enlarge.result9
-rw-r--r--mysql-test/suite/innodb/t/instant_varchar_enlarge.test8
-rw-r--r--storage/innobase/fil/fil0fil.cc117
-rw-r--r--storage/innobase/include/fil0fil.h25
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