[MDEV-12836] Avoid table rebuild when removing of auto_increment settings Created: 2017-05-18  Updated: 2021-07-23  Resolved: 2019-03-20

Status: Closed
Project: MariaDB Server
Component/s: Data Definition - Alter Table, Storage Engine - InnoDB
Fix Version/s: 10.4.4

Type: Task Priority: Critical
Reporter: Valerii Kravchuk Assignee: Sergei Golubchik
Resolution: Fixed Votes: 1
Labels: upstream

Issue Links:
Blocks
blocks MDEV-11424 Instant ALTER TABLE of failure-free r... Closed
Problem/Incident
causes MDEV-19272 virtual enum_alter_inplace_result ha_... Closed
causes MDEV-26224 InnoDB fails to remove AUTO_INCREMENT... Closed
Relates
relates to MDEV-11335 Changing delay_key_write option for M... Closed
Sprint: 10.2.12, 5.5.59

 Description   

Basically, it's a request to implement upstream feature request:

https://bugs.mysql.com/bug.php?id=72109

Copying the table to just drop auto_increment attribute:

MariaDB [test]> create table t(id int auto_increment not null, key(id)) engine=InnoDB;
Query OK, 0 rows affected (0.22 sec)
 
MariaDB [test]> alter table t modify column id int not null, algorithm=inplace; 
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY

is awful in production. Workarounds exist, but why not to do this in-place and without copying all the data?



 Comments   
Comment by Marko Mäkelä [ 2017-05-19 ]

According to an interactive debugging session between myself and valerii, the SQL layer is delivering correct metadata (altered_table->found_next_number_field == NULL, and AUTO_INCREMENT_FLAG is not set on the field).

The fix should be in ha_innobase::check_if_supported_inplace_alter() and possibly ha_innobase::prepare_inplace_alter_table().

This should be a simple fix, because InnoDB does not store the AUTO_INCREMENT metadata in its own data dictionary. We will only have to update the in-memory data dictionary cache if this is the only change made in the ALTER TABLE statement.

Comment by Marko Mäkelä [ 2018-01-10 ]

I tried the following variation of this:

--source include/have_innodb.inc
create table t(id int auto_increment primary key) engine=InnoDB;
alter table t modify column id int, algorithm=inplace;
drop table t;

This will result in ha_alter_info->handler_flags = ALTER_COLUMN_DEFAULT | ALTER_COLUMN_TYPE.
To fix this, InnoDB would have to compare the types of existing columns when ALTER_COLUMN_TYPE is set. I think that this is feasible to fix in MariaDB 10.2, but not in earlier versions (theoretically it could be done already in 10.0).

Comment by Julien Muchembled [ 2018-01-10 ]

What about TokuDB and RocksDB ? Is it possible to implement something generic ?

Comment by Marko Mäkelä [ 2018-02-06 ]

I think that the handler::inplace_alter_table() interface is already as generic as it gets. The storage engines that support AUTO_INCREMENT do need to be aware of the metadata changes. Theoretically, news flag could be introduced for the removal or addition of AUTO_INCREMENT attributes, but in the end each ALGORITHM=INPLACE capable storage engine would still have to do something about it.

This ticket will only cover the change for InnoDB.

Comment by Marko Mäkelä [ 2018-12-12 ]

kevg, can you fix this? I think that it is more feasible to fix in 10.3, which introduced the ALGORITHM=INSTANT keyword. Or only 10.4, if the code is too different from 10.3.

Comment by Marko Mäkelä [ 2019-01-25 ]

The changes are mostly outside InnoDB. The InnoDB changes look mostly OK to me.

Comment by Eugene Kosov (Inactive) [ 2019-02-05 ]

According to serg review this ticket not only about INSTANT operation which changes metadata only, but also about converting non-unique index to unique and generating/fixing AUTO_INCREMENT values like in this test case:

  create table t1 (a int not null, index (a));
   insert t1 values (0),(0),(0);
   alter table t1 modify a int auto_increment;
   select * from t1;

Comment by Sergei Golubchik [ 2019-02-12 ]

No, this issue is only about the INSTANT operation that changes metadata only — namely about removing AUTO_INCREMENT from a column.

Adding AUTO_INCREMENT is not metadata-only operation, and it's beyond the scope of this issue.

Comment by Eugene Kosov (Inactive) [ 2019-02-12 ]

I'm a bit confused now. What to do with https://github.com/MariaDB/server/pull/1125 ?
Adding AUTO_INCREMENT when data is not need to be changed can and thus should be INSTANT, right? No need to rebuild in that case.

If generating values along with adding AUTO_INCREMENT is a different task could you show me an issue? Or should I create it?

Comment by Sergei Golubchik [ 2019-02-20 ]

What to do with https://github.com/MariaDB/server/pull/1125

Change it to be in scope of this MDEV. Only handle removal of AUTO_INCREMENT, not adding.

Adding AUTO_INCREMENT when data is not need to be changed can and thus should be INSTANT, right?

Yes. But you need to know that the data does not need to be changed. It may be possible, but it's definitely more complex than "simply do it INSTANT" like for the removal of AUTO_INCREMENT. If you want to do it — sure, please, create an MDEV for INSTANT adding ot AUTO_INCREMENT and do it there. Make sure it corectly handles the test case from above.

Comment by Eugene Kosov (Inactive) [ 2019-02-21 ]

Thanks for clarifications.

Yes. But you need to know that the data does not need to be changed. It may be possible, but it's definitely more complex than "simply do it INSTANT" like for the removal of AUTO_INCREMENT.

I can see now it's problematic even when interesting index is unique:

create table t1 (a int not null, unique index (a));
insert t1 values (0),(1),(2);
alter table t1 modify a int auto_increment;
select * from t1;
drop table t1;

query 'alter table t1 modify a int auto_increment' failed: 1062: ALTER TABLE causes auto_increment resequencing, resulting in duplicate entry '1' for key 'a'

Generated at Thu Feb 08 08:00:51 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.