Un rake db précédent: rollback au point mort. Maintenant, lorsque vous tentez une nouvelle migration, nous obtenons l'erreur suivante:
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)
Nous utilisons Postresql
Un verrouillage consultatif a été ajouté dans Rails 5 pour éviter les erreurs de concurrence non planifiées pendant la migration. Le correctif consiste à effacer le verrou de base de données qui a été laissé en place.
Passez en revue les verrous en exécutant ce SQL sur votre base de données:
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
Pour effacer un verrou, exécutez ce SQL sur votre base de données:
select pg_advisory_unlock({the pid of the lock you want to release})
Donc, dans mon cas, la requête était différente
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
Cela vous dira essentiellement les pids
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>
et après cela, vous pouvez simplement déverrouiller le pid avec la commande suivante: select pg_advisory_unlock(#{target_pid})
par exemple.:
select pg_advisory_unlock(17272)
select pg_advisory_unlock(22640)
select pg_advisory_unlock(22640)
select pg_advisory_unlock(360)
À votre santé!
Si vous manipulez avec les données de la base de données, pas avec les paramètres de table et de colonne, peut-être qu'une tâche de râteau unique est un meilleur endroit pour cela?