Capistrano的PostgreSQL的,错误:数据库正在被其他用户访问(Capistrano

2019-08-01 13:13发布

我有一个使用PostgreSQL的作为与试图模仿生产,但它需要有数据库的定期重置QA一个证书的环境与后端建立一个Rails应用程序。

当我尝试执行db:reset部署过程中从Capistrano的任务,我得到的错误:

ERROR: database "database_name" is being accessed by other users

和数据库不能被丢弃,最后一次在部署失败重置任务的一部分。 有没有一种方法,我可以从Capistrano的重置数据库连接,所以我可以成功地删除该表? 管道中的SQL从Capistrano的任务可能会工作给psql,但我不知道是否有更好的方法来进行此事。

Answer 1:

在PostgreSQL,您可以执行以下语句返回比那么这一个以外的所有打开的连接后端的PID:

SELECT pid FROM pg_stat_activity where pid <> pg_backend_pid();

然后你就可以发出AA终止请求每个与后端的

SELECT pg_terminate_backend($1);

结合从第一条语句给每个pg_terminate_backend EXEC返回的PID。

如果其他连接没有使用相同的用户,你将不得不连接为一个超级用户成功发出终止。

  • 联系信号功能的文档
  • 监测统计功能
  • 和pg_stat_activity查看文档

更新:合并的意见,并表示为Capistrano的任务:

desc "Force disconnect of open backends and drop database"
task :force_close_and_drop_db do
  dbname = 'your_database_name'
  run "psql -U postgres",
      :data => <<-"PSQL"
         REVOKE CONNECT ON DATABASE #{dbname} FROM public;
         ALTER DATABASE #{dbname} CONNECTION LIMIT 0;
         SELECT pg_terminate_backend(pid)
           FROM pg_stat_activity
           WHERE pid <> pg_backend_pid()
           AND datname='#{dbname}';
         DROP DATABASE #{dbname};
      PSQL
end


Answer 2:

我已经联合dbenhur的答案与此Capistrano的任务,实现我需要像一个魅力的作品的结果:

desc 'kill pgsql users so database can be dropped'
task :kill_postgres_connections do
  run 'echo "SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE datname=\'database_name\';" | psql -U postgres'
end

这不承担设置为“信任”用户的Postgres的auth_method pg_hba.conf中

然后,你可以把它在你的部署任务后update_code之前migrate

after 'deploy:update_code', 'kill_postgres_connections'


Answer 3:

你可以简单地猴补丁ActiveRecord的代码,不会掉落。

对于Rails的3.X:

# lib/tasks/databases.rake
def drop_database(config)
  raise 'Only for Postgres...' unless config['adapter'] == 'postgresql'
  Rake::Task['environment'].invoke
  ActiveRecord::Base.connection.select_all "select pg_terminate_backend(pg_stat_activity.pid) from pg_stat_activity where datname='#{config['database']}' AND state='idle';"
  ActiveRecord::Base.establish_connection config.merge('database' => 'postgres', 'schema_search_path' => 'public')
  ActiveRecord::Base.connection.drop_database config['database']
end

对于Rails的4.x的:

# config/initializers/postgresql_database_tasks.rb
module ActiveRecord
  module Tasks
    class PostgreSQLDatabaseTasks
      def drop
        establish_master_connection
        connection.select_all "select pg_terminate_backend(pg_stat_activity.pid) from pg_stat_activity where datname='#{configuration['database']}' AND state='idle';"
        connection.drop_database configuration['database']
      end
    end
  end
end

(来自: http://www.krautcomputing.com/blog/2014/01/10/how-to-drop-your-postgres-database-with-rails-4/ )



文章来源: Capistrano with PostgreSQL, error: database is being accessed by other users