capistranoでデプロイする過程でmigrationがエラーで実行できなかったのでメモ。
ActiveRecord::ConcurrentMigrationError
こんなエラーが出た
rake stderr: rake aborted! ActiveRecord::ConcurrentMigrationError: Cannot run migrations because another migration process is currently running.
どうやら同じデータベース内で別のmigrationプロセスが走っているから実行できないよということらしい。
先ほど通信状況が悪く途中でCtrl+Cで終了させてしまったのがいけなかったっぽい。
プロセスをkill
mysqlにログインして現在走っているプロセスを確認してみる
mysql> SHOW PROCESSLIST; +--------+-----------+---------------------+------------+---------+------+----------------+---------------------------------------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +--------+-----------+---------------------+------------+---------+------+----------------+---------------------------------------------------------------------+ | 248003 | hoge_user | 172.31.11.92:63986 | hoge_db | Sleep | 2 | | NULL | | 248004 | hoge_user | 172.31.11.92:63988 | hoge_db | Sleep | 5 | | NULL | | 248005 | hoge_user | 172.31.11.92:63990 | hoge_db | Sleep | 3 | | NULL | | 248006 | hoge_user | 172.31.11.92:63992 | hoge_db | Sleep | 5 | | NULL | | 248039 | hoge_user | 172.31.11.92:64058 | hoge_db | Query | 272 | altering table | ALTER TABLE `users` ADD `status` tinyint(1) | | 248461 | hoge_user | 172.31.11.92:64358 | hoge_db | Query | 0 | init | SHOW PROCESSLIST | +--------+-----------+---------------------+------------+---------+------+----------------+---------------------------------------------------------------------+
こちらを一つずつ消していく
mysql> kill 248003; Query OK, 0 rows affected (0.00 sec)
勢い余って最後のSHOW PROCESSLIST
まで消そうとしてしまったのだけどちゃんとエラーになった
mysql> kill 248461; ERROR 1317 (70100): Query execution was interrupted
Mysql2::Error: Duplicate column name
で、いざもう一度デプロイ(migration)を実行してみるとまた違うエラーが発生
rake aborted! StandardError: An error has occurred, all later migrations canceled: Mysql2::Error: Duplicate column name 'status': ALTER TABLE `users` ADD `status` tinyint(1)
すでにusersテーブルにstatusは存在するからカラム名が重複するものはADDできないよーということらしい。
おそらく先ほどmigrationのプロセスが途中だったので、すでにDBにカラムが追加されるところまで終わっていた可能性がある。
もう一度mysqlにログインしてDBを見てみると
mysql> show columns from users; +---------------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | name | varchar(255) | NO | | NULL | | | created_at | datetime | NO | | NULL | | | updated_at | datetime | NO | | NULL | | | status | tinyint(1) | YES | | NULL | | +---------------------+--------------+------+-----+---------+----------------+ 5 rows in set (0.00 sec)
やっぱりあった。
migrationとDBの内容が食い違っている状態なので、手作業でmysql側を合わせていく(カラムを削除する)
mysql> alter table users drop column status; Query OK, 0 rows affected, 2 warnings (21 min 48.04 sec) Records: 0 Duplicates: 0 Warnings: 2
結構時間かかった^^;
で、もう一度migration実行したら今度はいけました。