Bug #98623 Please make adding/removing AUTO_INCREMENT to a table efficient.
Submitted: 16 Feb 2020 13:46 Modified: 17 Feb 2020 6:09
Reporter: Jean-François Gagné Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: DDL Severity:S4 (Feature request)
Version:5.7.29, 8.0.19 OS:Any
Assigned to: CPU Architecture:Any

[16 Feb 2020 13:46] Jean-François Gagné
Description:
Hi,

I recently had to remove the auto-increment field property on a 500 GB table, and it took more than 10 hours to execute because the table was rebuilt.

IMHO, removing an auto-increment from a table should not rebuild the table, it should be almost instant.

In "How to repeat", I also show that adding back an auto-increment is slow.

Please consider making the removal and addition of the AUTO_INCREMENT field property efficient.

Many thanks, JFG

How to repeat:
# Create a sandbox with dbdeployer.
$ dbdeployer deploy single mysql_5.7.29

# Create a schema and a table.
# I am using many CHAR fields to generate a big dataset quickly.
$ ./use <<< "CREATE DATABASE test_jfg"
$ ./use test_jfg <<< "CREATE TABLE t(id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, v VARCHAR(255))"
$ seq -f "ALTER TABLE t ADD COLUMN c%.0f CHAR(255) DEFAULT '';" 1 9 | ./use test_jfg

# Generate ~200 MB of data in that table.
$ seq -f "INSERT INTO t(v) VALUES ('%f');" 1 100000 | sed -e '1~1000s/^/COMMIT;BEGIN;/' | ./use test_jfg

# Remove the AUTO_INCREMENT, and prove that it takes time and that the table is rebuilt.
$ time ./use test_jfg <<< "ALTER TABLE t MODIFY COLUMN id INT UNSIGNED"& sleep 1; ls -l data/test_jfg/; fg
[1] 1449
total 340000
-rw-r----- 1 jgagne jgagne        65 Feb 16 13:28 db.opt
-rw-r----- 1 jgagne jgagne      8814 Feb 16 13:29 #sql-4d6_1d.frm
-rw-r----- 1 jgagne jgagne  62914560 Feb 16 13:29 #sql-4d6_1d.ibd
-rw-r----- 1 jgagne jgagne      8814 Feb 16 13:28 t.frm
-rw-r----- 1 jgagne jgagne 285212672 Feb 16 13:29 t.ibd
time ./use test_jfg <<< "ALTER TABLE t MODIFY COLUMN id INT UNSIGNED"

real    0m10.128s
user    0m0.004s
sys     0m0.000s

# Add back the AUTO_INCREMENT...
$ time ./use test_jfg <<< "ALTER TABLE t MODIFY COLUMN id INT UNSIGNED AUTO_INCREMENT"& sleep 1; ls -l data/test_jfg/; fg
[1] 1454
total 360480
-rw-r----- 1 jgagne jgagne        65 Feb 16 13:28 db.opt
-rw-r----- 1 jgagne jgagne      8814 Feb 16 13:30 #sql-4d6_1e.frm
-rw-r----- 1 jgagne jgagne  83886080 Feb 16 13:30 #sql-4d6_1e.ibd
-rw-r----- 1 jgagne jgagne      8814 Feb 16 13:29 t.frm
-rw-r----- 1 jgagne jgagne 285212672 Feb 16 13:29 t.ibd
time ./use test_jfg <<< "ALTER TABLE t MODIFY COLUMN id INT UNSIGNED AUTO_INCREMENT"

real    0m8.300s
user    0m0.004s
sys     0m0.000s

# And with 8.0.19...
$ dbdeployer deploy single mysql_8.0.19

[...]

$ time ./use test_jfg <<< "ALTER TABLE t MODIFY COLUMN id INT UNSIGNED"& sleep 1; ls -l data/test_jfg/; fg
[1] 1874
total 323496
-rw-r----- 1 jgagne jgagne  46137344 Feb 16 13:34 #sql-6fd_15.ibd
-rw-r----- 1 jgagne jgagne 285212672 Feb 16 13:34 t.ibd
time ./use test_jfg <<< "ALTER TABLE t MODIFY COLUMN id INT UNSIGNED"

real    0m10.239s
user    0m0.000s
sys     0m0.004s

$ time ./use test_jfg <<< "ALTER TABLE t MODIFY COLUMN id INT UNSIGNED AUTO_INCREMENT"& sleep 1; ls -l data/test_jfg/; fg
[1] 1879
total 339976
-rw-r----- 1 jgagne jgagne  75497472 Feb 16 13:34 #sql-6fd_16.ibd
-rw-r----- 1 jgagne jgagne 272629760 Feb 16 13:34 t.ibd
time ./use test_jfg <<< "ALTER TABLE t MODIFY COLUMN id INT UNSIGNED AUTO_INCREMENT"

real    0m8.240s
user    0m0.000s
sys     0m0.004s

Suggested fix:
Optimize the removal and addition of the AUTO_INCREMENT field property on a table.
[17 Feb 2020 6:09] MySQL Verification Team
Hello Jean-François,

Thank you for the feature request!

regards,
Umesh