Wie kann ich alle meine Postgresql-Verbindungen beenden?
Ich versuche einen rake db:drop
aber ich bekomme:
ERROR: database "database_name" is being accessed by other users
DETAIL: There are 1 other session(s) using the database.
Ich habe versucht, die Prozesse, die ich von einem ps -ef | grep postgres
aus sehe, herunterzufahren, aber das funktioniert auch nicht:
kill: kill 2358 failed: operation not permitted
Sie können pg_terminate_backend () verwenden, um eine Verbindung zu beenden. Sie müssen Superuser sein, um diese Funktion nutzen zu können. Das funktioniert auf allen Betriebssystemen gleich.
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'
;
Bevor Sie diese Abfrage ausführen, müssen Sie REVOKE die CONNECT-Berechtigungen setzen, um neue Verbindungen zu vermeiden:
REVOKE CONNECT ON DATABASE dbname FROM PUBLIC, username;
Wenn Sie Postgres 8.4-9.1 verwenden, verwenden Sie statt pid procpid
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'
;
Starten Sie einfach postgres
=> Sudo service postgresql restart
neu.
Mit allen Infos zum laufenden Prozess:
SELECT *, pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE pid <> pg_backend_pid()
AND datname = 'my_database_name';
OSX, Postgres 9.2 (installiert mit Homebrew)
$ 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
Wenn sich Ihr Datadir an einer anderen Stelle befindet, können Sie herausfinden, wo es sich befindet, indem Sie die Ausgabe von ps aux | grep postgres
MacOS, wenn postgresql mit brew installiert wurde:
brew services restart postgresql
Dies scheint für PostgreSQL 9.1 zu funktionieren:
#{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
Von den Gesten aufgehoben gefunden hier und hier .
Hier ist eine modifizierte Version , die für PostgreSQL 9.1 und 9.2 funktioniert.
Ich verwende die folgende Rake-Task, um die Rails drop_database
-Methode zu überschreiben.
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
Edit: Dies ist für Postgresql 9.2+
Ich hatte dieses Problem und das Problem war, dass Navicat mit meiner lokalen Postgres-Datenbank verbunden war. Nachdem ich Navicat getrennt hatte, verschwand das Problem.
BEARBEITEN:
Als absoluter letzter Ausweg können Sie Ihre Daten sichern und dann den folgenden Befehl ausführen:
Sudo kill -15 `ps -u postgres -o pid`
... was alles tötet, worauf der Postgres-Benutzer zugreift. Vermeiden Sie dies auf einer Produktionsmaschine, aber Sie sollten kein Problem mit einer Entwicklungsumgebung haben. Es ist wichtig, dass Sie sicherstellen, dass jederpostgres
-Prozess wirklich beendet wurde, bevor Sie PostgreSQL danach erneut starten.
EDIT 2:
Wegen dieser Unix.SE-Beitrag habe ich von kill -9
zu kill -15
gewechselt.
Ich habe diesen Weg gelöst:
In meinem Windows8 64 Bit restart
ing den Dienst: postgresql-x64-9.5
Einfacher und aktualisierter Weg ist:
ps -ef | grep postgres
, um die Verbindung zu finden #Sudo kill -9 "#"
der VerbindungHinweis: Möglicherweise ist die PID identisch. Wer einen tötet, tötet alle.
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
Postgres beenden und neu starten. Einfach, funktioniert aber jedes Mal für mich, wo andere CLI-Befehle manchmal nicht funktionieren.
Ich wollte nur darauf hinweisen, dass Haris 'Answer möglicherweise nicht funktioniert, wenn ein anderer Hintergrundprozess die Datenbank verwendet.
script/delayed_job stop
Und nur dann konnte ich die Datenbank löschen/löschen.
Es ist nicht nötig, es fallen zu lassen. Löschen Sie einfach das öffentliche Schema und erstellen Sie es erneut. In den meisten Fällen hat dies genau den gleichen Effekt.
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
Remote-Szenario Aber wenn Sie versuchen, Tests in einer Rails-App auszuführen, erhalten Sie so etwas
"ActiveRecord :: StatementInvalid: PG :: ObjectInUse: ERROR: Auf die Datenbank" myapp_test "wird von anderen Benutzern zugegriffen
Stellen Sie sicher, dass Sie pgAdmin oder andere Postgres-GUI-Tools schließen, bevor Sie Tests ausführen.
Öffnen Sie PGadmin, und überprüfen Sie, ob eine Abfrageseite geöffnet ist. Schließen Sie alle Abfrageseiten und trennen Sie den PostgresSQL-Server. Schließen Sie ihn erneut an und versuchen Sie, die Option delete/drop zu verwenden. Dies hat mir geholfen.
Ich bin auf einem Mac und verwende Postgres via Postgres.app
. Ich habe dieses Problem gelöst, indem ich die App gerade beendet und wieder gestartet habe.