web-dev-qa-db-ja.com

Rails 5 dbの移行:ActiveRecord :: ConcurrentMigrationErrorを修正する方法

以前のrake db:rollbackが停止しました。新しい移行を試みると、次のエラーが発生します。

rake aborted!
ActiveRecord::ConcurrentMigrationError: 

Cannot run migrations because another migration process is currently running.

/home/me/.rvm/gems/Ruby-2.4.1@global/gems/activerecord-    5.1.4/lib/active_record/migration.rb:1315:in `with_advisory_lock'
/home/me/.rvm/gems/Ruby-2.4.1@global/gems/activerecord-5.1.4/lib/active_record/migration.rb:1148:in `migrate'
/home/me/.rvm/gems/Ruby-2.4.1@global/gems/activerecord-5.1.4/lib/active_record/migration.rb:1007:in `up'
/home/me/.rvm/gems/Ruby-2.4.1@global/gems/activerecord-5.1.4/lib/active_record/migration.rb:985:in `migrate'
/home/me/.rvm/gems/Ruby-2.4.1@global/gems/activerecord-5.1.4/lib/active_record/tasks/database_tasks.rb:171:in `migrate'
/home/me/.rvm/gems/Ruby-2.4.1@global/gems/activerecord-5.1.4/lib/active_record/railties/databases.rake:58:in `block (2 levels) in <top (required)>'
/home/me/.rvm/gems/Ruby-2.4.1/gems/rake-12.1.0/exe/rake:27:in `<top (required)>'
/home/me/.rvm/gems/Ruby-2.4.1/bin/Ruby_executable_hooks:15:in `eval'
/home/me/.rvm/gems/Ruby-2.4.1/bin/Ruby_executable_hooks:15:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

Postresqlを使用しています

17
KeithP

Rails 5に、アドバイザリロックが追加されました。移行中の予期しない同時実行エラーを防ぐためです。修正は、残ったDBロックをクリアすることです。

DBに対してこのSQLを実行して、ロックを確認します。

SELECT DISTINCT age(now(), query_start) AS age, pg_stat_activity.pid,pg_locks.granted,pg_stat_activity.application_name,pg_stat_activity.backend_start, pg_stat_activity.xact_start, pg_stat_activity.state_change, pg_stat_activity.waiting, pg_stat_activity.state, pg_stat_activity.query_start, left(pg_stat_activity.query, 60) FROM pg_stat_activity, pg_locks WHERE pg_locks.pid = pg_stat_activity.pid

ロックをクリアするには、DBに対して次のSQLを実行します。

select pg_advisory_unlock({the pid of the lock you want to release})

16
KeithP

だから私の場合、クエリは異なっていました

_SELECT DISTINCT age(now(), query_start) AS age, pg_stat_activity.pid,pg_locks.granted,pg_stat_activity.application_name,pg_stat_activity.backend_start, pg_stat_activity.xact_start, pg_stat_activity.state_change, pg_stat_activity.state, pg_stat_activity.query_start, left(pg_stat_activity.query, 60)
    FROM pg_stat_activity, pg_locks
    WHERE pg_locks.pid = pg_stat_activity.pid
_

それは基本的にあなたにpidを教えてくれます

_0 years 0 mons 0 days 0 hours 0 mins -0.01005 secs    360    true    PostgreSQL JDBC Driver    2019-04-03 16:57:16.873609    2019-04-03 16:58:00.531675    2019-04-03 16:58:00.541727    active    2019-04-03 16:58:00.541725    SELECT DISTINCT age(now(), query_start) AS age, pg_stat_acti
    17272    true    ""                        <insufficient privilege>
    22640    true    ""                        <insufficient privilege>
    29466    true    ""                        <insufficient privilege>
_

その後、次のコマンドでpidのロックを解除できます:select pg_advisory_unlock(#{target_pid})

例えば。:

_select pg_advisory_unlock(17272)
select pg_advisory_unlock(22640)
select pg_advisory_unlock(22640)
select pg_advisory_unlock(360)
_

乾杯!

5
d1jhoni1b

テーブルや列の設定ではなく、DB内のデータを操作している場合、たぶん1回のレーキタスクがこれに適していますか?

0
bernstein7