← Back to team overview

maria-developers team mailing list archive

Re: 5403baabc7e: MDEV-16849 Extending indexed VARCHAR column should be instantaneous

 

Hi, Thirunarayanan!

On Nov 05, Thirunarayanan Balathandayuthapani wrote:
> revision-id: 5403baabc7ef87e301964434e3670ded06af0802 (mariadb-10.2.18-40-g5403baabc7e)
> parent(s): ab1ce2204e959bea596817494e932754ab5cbe88
> author: Thirunarayanan Balathandayuthapani <thiru@xxxxxxxxxxx>
> committer: Thirunarayanan Balathandayuthapani <thiru@xxxxxxxxxxx>
> 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@xxxxxxxxxxx