10

I have the following MySQL RoR Migrations:

class ReindexRpushNotification < ActiveRecord::Migration
 def up
 execute("DROP INDEX `index_rpush_notifications_multi` ON rpush_notifications;")
 execute("ALTER TABLE rpush_notifications ADD INDEX index_rpush_notifications_multi (delivered, failed, processing, deliver_after), ALGORITHM=INPLACE, LOCK=NONE;")
 end
 def down
 execute("DROP INDEX `index_rpush_notifications_multi` ON rpush_notifications;")
 execute("ALTER TABLE rpush_notifications ADD INDEX index_rpush_notifications_multi (delivered, failed), ALGORITHM=INPLACE, LOCK=NONE;")
 end
end

during this migration I'm trying to perform some requests (GET, COUNT, DELETE, UPDATE) but nothing work, all these requests just wait

I found an info about index creation in background here

https://stackoverflow.com/a/36064200

http://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.html

but it doesn't work for us

Did anybody try LOCK=NONE?

We use MySQL 5.6.23 on AWS RDS

asked May 12, 2016 at 16:09

2 Answers 2

15

Looks like I have a clue why it doesn't work

Our table have the following constraint:

CONSTRAINT `rpush_notifications_event_id_fk` 
 FOREIGN KEY (`event_id`) REFERENCES `events` (`id`) ON DELETE CASCADE

Next, I found here one interesting thing: https://blogs.oracle.com/mysqlinnodb/entry/online_alter_table_in_mysql

Online operation (LOCK=NONE) is not allowed in the following cases:

  • when adding an AUTO_INCREMENT column,
  • when the table contains FULLTEXT indexes or a hidden FTS_DOC_ID column, or
  • when there are FOREIGN KEY constraints referring to the table, with ON...CASCADE or ON...SET NULL option.

so looks like we have a 3rd case

answered May 12, 2016 at 16:34
4
  • 5
    Still, shouldn't it throw an error rather than to just proceed while locking production tables and bringing down the wrath of the masses on you? Commented Jun 6, 2018 at 8:04
  • 3
    Classic MySql silent error. Got bitten by it today. Not happy. Commented Nov 20, 2018 at 15:55
  • 2
    What about if you use SET FOREIGN_KEY_CHECKS=0; before index creation, and re-enable it afterwards? Commented Feb 28, 2019 at 11:19
  • 1
    I tested SET FOREIGN_KEY_CHECKS=0 first and it still locked for me unfortunately. Commented Jul 11, 2023 at 23:27
-1

Consider adding a new index first, then DROP the old index. DROP should be a lot faster than ADD.

Or, if that fails, don't drop the old index.

answered May 24, 2016 at 23:57

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.