遇到一个需求,已有的一个表,需要把已有的一个普通索引变成唯一索引,表数据量大约在百万级别,duplicate的量大约在几K左右。想到了使用alter ignore table (http://dev.mysql.com/doc/refman/5.5/en/alter-table.html),于是便找了一个测试库,发现依旧报uk冲突:
- root@test 12:55:26>alter ignore table vertical_bail_detail_0007 add unique key uk_ooid(out_order_id);
- ERROR 1062 (23000): Duplicate entry 'GT2-18578' for key 'uk_ooid'
开始怀疑是mysql版本的问题,于是在5.1.48和5.5.18上都试了一遍,结果一样,于是便找了一下mysql的bug,发现确实是一个innodb的bug,链接(http://bugs.mysql.com/bug.php?id=65731;http://bugs.mysql.com/bug.php?id=40344)
bug#40344里面提到了一个解决方法:workaround is to first run "set session old_alter_table=1;"试了一下,确实可以。
- root@test 01:41:52>set session old_alter_table =on;
- Query OK, 0 rows affected (0.00 sec)
- root@test 01:42:44>alter ignore table vertical_bail_detail_0007 add unique key uk_ooid(out_order_id),drop index IDX_BAIL_DETAIL_OOID;
- Query OK, 1430517 rows affected (1 min 11.19 sec)
- Records: 1430517 Duplicates: 103 Warnings: 0
ps1:注意,如果你要是想使用set session old_alter_table =on;来解决这个问题,而且有是有主备的情况,记得执行前设置一下set session sql_log_bin=off.以免备库报错,同样,还需要再备库重复一下主库的操作。
ps2:看了一下bug的时间,08年提的bug,12年才有人close,而且还是到5.6.6才给close,不得不吐槽一下,bug的fix周期真久...
-----
最近看fast index creation,官方文档上列出过这个问题(http://dev.mysql.com/doc/refman/5.5/en/innodb-create-index-limitations.html)