MDEV-36038 ALTER TABLE…SEQUENCE does not work correctly with InnoDB

mysql_alter_table(): Consider ha_sequence::storage_ht() when determining
if the storage engine changed.

ha_sequence::check_if_supported_inplace_alter(): A new function, to
ensure that ha_innobase::check_if_supported_inplace_alter() will be
called on ALTER TABLE name_of_sequence SEQUENCE=0.

ha_innobase::check_if_supported_inplace_alter(): For any change of
the SEQUENCE attribute, always return HA_ALTER_INPLACE_NOT_SUPPORTED,
forcing ALGORITHM=COPY.
This commit is contained in:
Marko Mäkelä 2025-02-18 17:01:44 +02:00 committed by Sergei Golubchik
parent 94ef07d61e
commit 5ebff6e15a
7 changed files with 65 additions and 1 deletions

View File

@ -0,0 +1 @@
--innodb-sys-tables

View File

@ -166,6 +166,32 @@ next_not_cached_value minimum_value maximum_value start_value increment cache_si
select next value for t1;
next value for t1
11
$check_innodb_flags;
is_sequence
12288
alter table t1 sequence=0;
begin;
delete from t1;
rollback;
$check_innodb_flags;
is_sequence
0
alter table t1 sequence=1;
$check_innodb_flags;
is_sequence
12288
alter table t1 sequence=0, algorithm=copy;
$check_innodb_flags;
is_sequence
0
alter table t1 sequence=1, algorithm=inplace;
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: SEQUENCE. Try ALGORITHM=COPY
alter table t1 sequence=1, algorithm=copy;
$check_innodb_flags;
is_sequence
12288
alter table t1 sequence=0, algorithm=inplace;
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: SEQUENCE. Try ALGORITHM=COPY
drop sequence t1;
#
# ALTER TABLE

View File

@ -80,6 +80,25 @@ alter sequence t1 start=100;
show create sequence t1;
select * from t1;
select next value for t1;
let $check_innodb_flags =
select flag & 12288 is_sequence from information_schema.innodb_sys_tables
where name='test/t1';
evalp $check_innodb_flags;
alter table t1 sequence=0;
begin;
delete from t1;
rollback;
evalp $check_innodb_flags;
alter table t1 sequence=1;
evalp $check_innodb_flags;
alter table t1 sequence=0, algorithm=copy;
evalp $check_innodb_flags;
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
alter table t1 sequence=1, algorithm=inplace;
alter table t1 sequence=1, algorithm=copy;
evalp $check_innodb_flags;
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
alter table t1 sequence=0, algorithm=inplace;
drop sequence t1;
--echo #

View File

@ -353,6 +353,12 @@ bool ha_sequence::check_if_incompatible_data(HA_CREATE_INFO *create_info,
return(COMPATIBLE_DATA_YES);
}
enum_alter_inplace_result
ha_sequence::check_if_supported_inplace_alter(TABLE *altered_table,
Alter_inplace_info *ai)
{
return file->check_if_supported_inplace_alter(altered_table, ai);
}
int ha_sequence::external_lock(THD *thd, int lock_type)
{

View File

@ -94,6 +94,9 @@ public:
/* For ALTER ONLINE TABLE */
bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
uint table_changes) override;
enum_alter_inplace_result
check_if_supported_inplace_alter(TABLE *altered_table,
Alter_inplace_info *ai) override;
void write_lock() { write_locked= 1;}
void unlock() { write_locked= 0; }
bool is_locked() { return write_locked; }

View File

@ -11534,7 +11534,8 @@ do_continue:;
- Neither old or new engine uses files from another engine
The above is mainly true for the sequence and the partition engine.
*/
engine_changed= ((new_table->file->ht != table->file->ht) &&
engine_changed= ((new_table->file->storage_ht() !=
table->file->storage_ht()) &&
((!(new_table->file->ha_table_flags() & HA_FILE_BASED) ||
!(table->file->ha_table_flags() & HA_FILE_BASED))) &&
!(table->file->ha_table_flags() & HA_REUSES_FILE_NAMES) &&

View File

@ -2049,6 +2049,12 @@ ha_innobase::check_if_supported_inplace_alter(
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
if (ha_alter_info->create_info->used_fields
& HA_CREATE_USED_SEQUENCE) {
ha_alter_info->unsupported_reason = "SEQUENCE";
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
update_thd();
if (!m_prebuilt->table->space) {
@ -6317,6 +6323,8 @@ prepare_inplace_alter_table_dict(
DBUG_ASSERT(!ctx->add_index);
DBUG_ASSERT(!ctx->add_key_numbers);
DBUG_ASSERT(!ctx->num_to_add_index);
DBUG_ASSERT(!(ha_alter_info->create_info->used_fields
& HA_CREATE_USED_SEQUENCE));
user_table = ctx->new_table;