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