2013年9月17日火曜日

MySQL 5.6.11以降のInnoDBテーブルでAUTO_INCREMENTの値を小さくできない件

なんか変だなーと思っていたんですがすっきりしました。

mysql56> CREATE TABLE t1 (num serial, val varchar(32)) Engine= InnoDB;
Query OK, 0 rows affected (0.05 sec)

mysql56> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `num` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `val` varchar(32) DEFAULT NULL,
  UNIQUE KEY `num` (`num`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql56> INSERT INTO t1 VALUES (1, 'one'), (2, 'two');
Query OK, 2 rows affected (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql56> SELECT * FROM t1;
+-----+------+
| num | val  |
+-----+------+
|   1 | one  |
|   2 | two  |
+-----+------+
2 rows in set (0.00 sec)

mysql56> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `num` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `val` varchar(32) DEFAULT NULL,
  UNIQUE KEY `num` (`num`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql56> ALTER TABLE t1 AUTO_INCREMENT= 10000;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql56> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `num` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `val` varchar(32) DEFAULT NULL,
  UNIQUE KEY `num` (`num`)
) ENGINE=InnoDB AUTO_INCREMENT=10000 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql56> ALTER TABLE t1 AUTO_INCREMENT= 10;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql56> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `num` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `val` varchar(32) DEFAULT NULL,
  UNIQUE KEY `num` (`num`)
) ENGINE=InnoDB AUTO_INCREMENT=10000 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

5.5のInnoDBならこれできるんです。5.6のMyISAMでもできます。

マニュアルの書き方を比較しても、5.6のInnoDBでだけAUTO_INCREMENTを小さくできない様には読めないのでなんかもやもやします。

5.5 ALTER TABLE: http://dev.mysql.com/doc/refman/5.5/en/alter-table.html
⇒MAX(auto_increment_column)より小さい値を与えた場合、MyISAMはMAX(auto_increment_column)+ 1に勝手に切り詰めて、InnoDBは値が変更されない。
⇒MAX(auto_increment_column)より大きい値の場合は言及なし。

5.6 ALTER TABLE: http://dev.mysql.com/doc/refman/5.6/en/alter-table.html
⇒MyISAMもInnoDBもMAX(auto_increment_column)より小さい値を与えた場合はMAX(auto_increment_column)+ 1に切り詰める。
⇒MAX(auto_increment_column)より大きい値の場合は言及なし。


と思ったらバグレポート見つけた。これだ。

MySQL Bug #69882: http://bugs.mysql.com/bug.php?id=69882


バグレポートのWorkaroundにはTRUNCATEしか紹介されていませんが、ALTER TABLE .. ALGORITHM= COPYを使えば小さくできました。ドキュメントの記載漏れなのか、バグとして扱われるのか微妙なとこですね。。

【2014/02/03 12:48】 結構前ですが、バグとしてVerifyされてます。5.6.16(2014/01/31)でFIXされています。


mysql56> ALTER TABLE t1 ALGORITHM= COPY, AUTO_INCREMENT= 10;
Query OK, 2 rows affected (0.11 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql56> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `num` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `val` varchar(32) DEFAULT NULL,
  UNIQUE KEY `num` (`num`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

これ見ても、InnoDB Online ALTER TABLEの時はできない、と言ってるようには見えないんですけどねー。。
http://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.html

0 件のコメント :

コメントを投稿