提问



我该如何杀死所有的postgresql连接?


我正在尝试rake db:drop,但我得到:


ERROR:  database "database_name" is being accessed by other users
DETAIL:  There are 1 other session(s) using the database.


我试图关闭我从ps -ef | grep postgres看到的过程,但这也不起作用:


kill: kill 2358 failed: operation not permitted

最佳参考


您可以使用pg_terminate_backend()来终止连接。您必须是超级用户才能使用此功能。这适用于所有操作系统。 [31]


SELECT 
    pg_terminate_backend(pid) 
FROM 
    pg_stat_activity 
WHERE 
    -- don't kill my own connection!
    pid <> pg_backend_pid()
    -- don't kill the connections to other databases
    AND datname = 'database_name'
    ;


在执行此查询之前,您必须REVOKE CONNECT权限以避免新连接:[32]


REVOKE CONNECT ON DATABASE dbname FROM PUBLIC, username;



  如果您使用Postgres 8.4-9.1使用procpid而不是pid



SELECT 
    pg_terminate_backend(procpid) 
FROM 
    pg_stat_activity 
WHERE 
    -- don't kill my own connection!
    procpid <> pg_backend_pid()
    -- don't kill the connections to other databases
    AND datname = 'database_name'
    ;

其它参考1


也许只是重启postgres => sudo service postgresql restart

其它参考2


有关运行过程的所有信息:


SELECT *, pg_terminate_backend(pid)
FROM pg_stat_activity 
WHERE pid <> pg_backend_pid()
AND datname = 'my_database_name';

其它参考3


OSX,Postgres 9.2(随自制软件一起安装)


$ launchctl unload -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
$ pg_ctl restart -D /usr/local/var/postgres
$ launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist


点击
如果你的datadir在别处你可以通过检查ps aux | grep postgres的输出找出它的位置

其它参考4


这似乎适用于PostgreSQL 9.1:


#{Rails.root}/lib/tasks/databases.rake
# monkey patch ActiveRecord to avoid There are n other session(s) using the database.
def drop_database(config)
  case config['adapter']
  when /mysql/
    ActiveRecord::Base.establish_connection(config)
    ActiveRecord::Base.connection.drop_database config['database']
  when /sqlite/
    require 'pathname'
    path = Pathname.new(config['database'])
    file = path.absolute? ? path.to_s : File.join(Rails.root, path)

    FileUtils.rm(file)
  when /postgresql/
    ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
    ActiveRecord::Base.connection.select_all("select * from pg_stat_activity order by procpid;").each do |x|
      if config['database'] == x['datname'] && x['current_query'] =~ /<IDLE>/
        ActiveRecord::Base.connection.execute("select pg_terminate_backend(#{x['procpid']})")
      end
    end
    ActiveRecord::Base.connection.drop_database config['database']
  end
end


从这里和这里发现的要点中解脱出来。[33] [34]


这是一个适用于PostgreSQL 9.1和9.2的修改版本。

其它参考5


我使用以下rake任务来覆盖Rails drop_database方法。


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


编辑:这适用于Postgresql 9.2+

其它参考6


MacOS,如果使用 brew 安装 postgresql :


brew services restart postgresql


来源:杀死postgresql会话/连接

其它参考7


我有这个问题,问题是Navicat连接到我当地的Postgres数据库。一旦我断开Navicat,问题就消失了。


编辑:


此外,作为绝对的最后手段,您可以备份数据然后运行此命令:


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


...将杀死postgres用户正在访问的所有内容。避免在生产计算机上执行此操作,但是您不应该对开发环境有任何问题。在此之后尝试重新启动PostgreSQL之前确保每个 postgres进程真正终止是至关重要的。 。


编辑2:


由于这个unix.SE帖子我已经从kill -9改为kill -15[38]

其它参考8


退出postgres并重新启动它。很简单,但每次都适用于我,其他cli命令有时候不会。

其它参考9


我已经解决了这个问题:


在我的 Windows8 64 位中,只需restart服务: postgresql-x64-9.5

其它参考10


只是想指出,如果其他一些后台进程正在使用数据库,Haris的答案可能无效,在我的情况下,它延迟了工作,我做了:


script/delayed_job stop


只有这样我才能删除/重置数据库。

其它参考11


没有必要放弃它。只需删除并重新创建公共架构即可。在大多数情况下,这具有完全相同的效果。


namespace :db do

desc 'Clear the database'
task :clear_db => :environment do |t,args|
  ActiveRecord::Base.establish_connection
  ActiveRecord::Base.connection.tables.each do |table|
    next if table == 'schema_migrations'
    ActiveRecord::Base.connection.execute("TRUNCATE #{table}")
  end
end

desc 'Delete all tables (but not the database)'
task :drop_schema => :environment do |t,args|
  ActiveRecord::Base.establish_connection
  ActiveRecord::Base.connection.execute("DROP SCHEMA public CASCADE")
  ActiveRecord::Base.connection.execute("CREATE SCHEMA public")
  ActiveRecord::Base.connection.execute("GRANT ALL ON SCHEMA public TO postgres")
  ActiveRecord::Base.connection.execute("GRANT ALL ON SCHEMA public TO public")
  ActiveRecord::Base.connection.execute("COMMENT ON SCHEMA public IS 'standard public schema'")
end

desc 'Recreate the database and seed'
task :redo_db => :environment do |t,args|
  # Executes the dependencies, but only once
  Rake::Task["db:drop_schema"].invoke
  Rake::Task["db:migrate"].invoke
  Rake::Task["db:migrate:status"].invoke 
  Rake::Task["db:structure:dump"].invoke
  Rake::Task["db:seed"].invoke
end

end

其它参考12


远程方案。但是,如果您正在尝试在rails应用程序中运行测试,那么您会得到类似的东西


ActiveRecord :: StatementInvalid:PG :: ObjectInUse:ERROR:数据库myapp_test正在被其他用户访问
DETAIL:还有1个使用该数据库的会话。


确保在运行测试之前关闭pgAdmin或任何其他postgres GUI工具。

其它参考13


SELECT 
pg_terminate_backend(pid) 
FROM 
pg_stat_activity 
WHERE
pid <> pg_backend_pid()
-- no need to kill connections to other databases
AND datname = current_database();
-- use current_database by opening right query tool

其它参考14


案例:

无法执行查询:


DROP TABLE dbo.t_tabelname


解决方案:

一个。显示查询状态Activity如下:


SELECT * FROM pg_stat_activity  ;


湾查找查询列包含的行:


'DROP TABLE dbo.t_tabelname'


C。在同一行中,获取PID列的值


example : 16409


d。执行这些脚本:


SELECT 
    pg_terminate_backend(25263) 
FROM 
    pg_stat_activity 
WHERE 
    -- don't kill my own connection!
    25263 <> pg_backend_pid()
    -- don't kill the connections to other databases
    AND datname = 'database_name'
    ;