web-dev-qa-db-ja.com

MySQLはLOCK = NONEでインデックスを作成しますが、それでもテーブルをロックします

次のMySQL RoR移行があります。

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

この移行中、いくつかの要求(GET、COUNT、DELETE、UPDATE)を実行しようとしていますが、何も機能せず、これらの要求はすべて待機します

ここでバックグラウンドでのインデックス作成に関する情報を見つけました

https://stackoverflow.com/a/360642

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

しかし、それは私たちのために機能しません

誰かがLOCK = NONEを試しましたか?

AWS RDSでMySQL 5.6.23を使用しています

4
Rubycon

うまくいかない理由がわかります

テーブルには次の制約があります。

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

次に、興味深いことが1つ見つかりました: https://blogs.Oracle.com/mysqlinnodb/entry/online_alter_table_in_mysql

次の場合、オンライン操作(LOCK = NONE)は許可されません。

  • aUTO_INCREMENTカラムを追加するとき、
  • テーブルにFULLTEXTインデックスまたは非表示のFTS_DOC_ID列が含まれている場合、または
  • oN…CASCADEまたはON…SET NULLオプションを使用して、テーブルを参照するFOREIGN KEY制約がある場合。

3番目のケースがあるようです

9
Rubycon