Rails + Postgres drop error: database is being accessed by other users

前端 未结 16 2082
时光取名叫无心
时光取名叫无心 2020-12-04 06:26

I have a rails application running over Postgres.

I have two servers: one for testing and the other for production.

Very often I need to clone the production

相关标签:
16条回答
  • 2020-12-04 06:55

    I had a similar error saying 1 user was using the database, I realized it was ME! I shut down my rails server and then did the rake:drop command and it worked!

    0 讨论(0)
  • 2020-12-04 06:57

    Here's a quick way to kill all the connections to your postgres database.

    sudo kill -9 `ps -u postgres -o pid` 
    

    Warning: this will kill any running processes that the postgres user has open, so make sure you want to do this first.

    0 讨论(0)
  • 2020-12-04 06:57

    You can simply monkeypatch the ActiveRecord code that does the dropping.

    For 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
    

    For 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
    

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

    0 讨论(0)
  • 2020-12-04 06:57

    Just make sure that the you have exited the rails console on any open terminal window and exited the rails server...this is one of the most common mistake made by people

    0 讨论(0)
  • 2020-12-04 06:59

    I wrote a gem called pgreset that will automatically kill connections to the database in question when you run rake db:drop (or db:reset, etc). All you have to do is add it to your Gemfile and this issue should go away. At the time of this writing it works with Rails 4 and up and has been tested on Postgres 9.x. Source code is available on github for anyone interested.

    gem 'pgreset'
    
    0 讨论(0)
  • 2020-12-04 07:01

    I use the following rake task to override the Rails drop_database method.

    lib/database.rake

    require 'active_record/connection_adapters/postgresql_adapter'
    module ActiveRecord
      module ConnectionAdapters
        class PostgreSQLAdapter < AbstractAdapter
          def drop_database(name)
            raise "Nah, I won't drop the production database" if Rails.env.production?
            execute <<-SQL
              UPDATE pg_catalog.pg_database
              SET datallowconn=false WHERE datname='#{name}'
            SQL
    
            execute <<-SQL
              SELECT pg_terminate_backend(pg_stat_activity.pid)
              FROM pg_stat_activity
              WHERE pg_stat_activity.datname = '#{name}';
            SQL
            execute "DROP DATABASE IF EXISTS #{quote_table_name(name)}"
          end
        end
      end
    end
    
    0 讨论(0)
提交回复
热议问题