Hi, Thirunarayanan! On Nov 05, Thirunarayanan Balathandayuthapani wrote:
revision-id: 5403baabc7ef87e301964434e3670ded06af0802 (mariadb-10.2.18-40-g5403baabc7e) parent(s): ab1ce2204e959bea596817494e932754ab5cbe88 author: Thirunarayanan Balathandayuthapani <thiru@mariadb.com> committer: Thirunarayanan Balathandayuthapani <thiru@mariadb.com> timestamp: 2018-10-26 16:49:08 +0530 message:
MDEV-16849 Extending indexed VARCHAR column should be instantaneous
Analysis: ======== Increasing the length of the indexed varchar column is not an instant operation for innodb.
Fix: === - Introduce the new handler flag 'Alter_inplace_info::ALTER_COLUMN_INDEX_LENGTH' to indicate the index length differs due to change of column length changes.
- InnoDB makes the ALTER_COLUMN_INDEX_LENGTH flag as instant operation.
This is a port of Mysql fix.
diff --git a/sql/handler.cc b/sql/handler.cc index da41daf2440..b1fa53fb145 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4253,7 +4253,8 @@ handler::check_if_supported_inplace_alter(TABLE *altered_table, Alter_inplace_info::CHANGE_CREATE_OPTION | Alter_inplace_info::ALTER_PARTITIONED | Alter_inplace_info::ALTER_VIRTUAL_GCOL_EXPR | - Alter_inplace_info::ALTER_RENAME; + Alter_inplace_info::ALTER_RENAME | + Alter_inplace_info::ALTER_COLUMN_INDEX_LENGTH;
You sure? It means that any engine by default can do ALTER_COLUMN_INDEX_LENGTH inplace, unless some other check in the engine disallows it. I'd rather not enable it for all engine, so better remove it. InnoDB has his own check inside ha_innobase::check_if_supported_inplace_alter() anyway.
/* Is there at least one operation that requires copy algorithm? */ if (ha_alter_info->handler_flags & ~inplace_offline_operations) diff --git a/sql/handler.h b/sql/handler.h index ed2ef822c88..f2250699cfb 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1994,6 +1994,11 @@ class Alter_inplace_info
static const HA_ALTER_FLAGS ALTER_DROP_CHECK_CONSTRAINT= 1ULL << 40;
+ /** + Change in index length such that it doesn't require index rebuild. + */ + static const HA_ALTER_FLAGS ALTER_COLUMN_INDEX_LENGTH= 1ULL << 41; + /** Create options (like MAX_ROWS) for the new version of table.
diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 02780e7d1e0..94d35c99d0a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6687,18 +6687,27 @@ static bool fill_alter_inplace_info(THD *thd, key_part < end; key_part++, new_part++) { + new_field= get_field_by_index(alter_info, new_part->fieldnr); /* + If there is a change in index length due to column expansion + like varchar(X) changed to varchar(X + N) and has a compatible + packed data representation, we mark it for fast/INPLACE change + in index definition. InnoDB supports INPLACE for this cases + Key definition has changed if we are using a different field or - if the used key part length is different. It makes sense to - check lengths first as in case when fields differ it is likely - that lengths differ too and checking fields is more expensive - in general case. + if the user key part length is different. */ - if (key_part->length != new_part->length) + if (key_part->length != new_part->length && + (ha_alter_info->alter_info->flags & Alter_info::ALTER_CHANGE_COLUMN) &&
why is that? Can it happen that ALTER_CHANGE_COLUMN flag is not set?
+ (key_part->field->is_equal((Create_field*) new_field) + == IS_EQUAL_PACK_LENGTH)) + { + ha_alter_info->handler_flags |= + Alter_inplace_info::ALTER_COLUMN_INDEX_LENGTH; + } + else if (key_part->length != new_part->length) goto index_changed;
- new_field= get_field_by_index(alter_info, new_part->fieldnr); - /* For prefix keys KEY_PART_INFO::field points to cloned Field object with adjusted length. So below we have to check field
Regards, Sergei Chief Architect MariaDB and security@mariadb.org