Beenden Sie eine Postgresql-Sitzung / Verbindung

369

Wie kann ich alle meine Postgresql-Verbindungen beenden?

Ich versuche es, rake db:dropaber 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 a aus sehe, herunterzufahren, ps -ef | grep postgresaber das funktioniert auch nicht:

kill: kill 2358 failed: operation not permitted
DanS
quelle
Als alle anderen Versuche fehlschlugen, reparierte der pgreset-Edelstein irgendwie die Schienen / pg und dachte, dass eine Verbindung bestand, was nicht der Fall war.
JosephK

Antworten:

671

Sie können pg_terminate_backend () verwenden , um eine Verbindung zu beenden . Sie müssen Superuser sein, um diese Funktion nutzen zu können. Dies 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 - Privilegien , um neue Verbindungen zu vermeiden:

REVOKE CONNECT ON DATABASE dbname FROM PUBLIC, username;

Wenn Sie Postgres 8.4-9.1 verwenden, verwenden Sie procpid anstelle von 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'
    ;
Frank Heikens
quelle
68
Beachten Sie, dass in Postgres 9.2 procpid in pid umbenannt wird.
Devin
Wenn er ein Superuser wäre, hätte er sudoden Kill nicht trotzdem machen können?
ndnenkov
3
@ndn Ein Datenbank-Superuser ist nicht dasselbe wie ein Superuser auf Betriebssystemebene. Es gibt keine sudoin PG.
jpmc26
Dies ist die einzige funktionierende Antwort auf viele SO-Fragen, da sie den REVOKESchritt hat. Du hast jemanden gerettet, noch einmal, denke ich!
AymDev
Dies funktioniert danke ....
Ajay Kumar
205

Vielleicht einfach neu starten postgres=>sudo service postgresql restart

Haris Krajina
quelle
@Starkers Ich habe die meisten Antworten oben durchgesehen, bis es mir dämmerte :)
Haris Krajina
32
@Starker Ja, besonders sicher in der Produktion unter hoher Last;)
Erathiel
10
brew services restart postgresqlWenn Sie
gebraut
28

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';
Dorian
quelle
13

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 Datenverzeichnis an einer anderen Stelle befindet, können Sie herausfinden, wo es sich befindet, indem Sie die Ausgabe von untersuchen ps aux | grep postgres

Artemave
quelle
4
Oderbrew services restart postgresql
PJSCopeland
@PJSCopeland Danke für die einfachste Lösung! Ich denke, Ihr Kommentar verdient eine echte Antwort, also: stackoverflow.com/a/48226667/1097104
Juuso Ohtonen
Danke dafür, @JuusoOhtonen. Sag dir was, wenn du den Ruf davon haben willst, könntest du zumindest auf meinen Kommentar zurückgreifen?
PJSCopeland
@PJSCopeland Fertig.
Juuso Ohtonen
Hatte Probleme mit anderen Antworten und ähnlichen SO-Post-Lösungen. Laufen Sie pg_ctl restart -D /usr/local/var/postgreshaben den Trick getan! (Ich habe nicht einmal den ersten oder dritten Befehl ausgeführt).
Iggy
8

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

Aufgehoben von den hier und hier gefundenen Kernpunkten .

Hier ist eine modifizierte Version , die sowohl für PostgreSQL 9.1 als auch für 9.2 funktioniert.

Chris
quelle
6

Ich verwende die folgende Rechenaufgabe, um die Rails- drop_databaseMethode 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

Bearbeiten: Dies ist für Postgresql 9.2+

Chris Aitchison
quelle
Sie müssen pg_stat_activity.procpidanstelle von pg_stat_activity.pidPostgres 9.1 und niedriger verwenden. Siehe stackoverflow.com/a/5408501/444774
talyric
1
Das ist eine großartige Antwort! Es ist besser und sicherer als die Rails-Standardeinstellung. Vielen Dank!
Piersadrian
5

Einfacher und aktueller ist:

  1. Verwenden Sie ps -ef | grep postgres, um die Verbindungsnummer zu finden
  2. sudo kill -9 "#" der Verbindung

Hinweis: Möglicherweise ist die PID identisch. Wenn man einen tötet, werden alle getötet.

Herr Rene
quelle
3

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:

Auch als absolute Notlösung können Sie Ihre Daten dann führen Sie diesen Befehl sichern:

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

... was alles tötet, auf das der Postgres-Benutzer zugreift. Vermeiden Sie dies auf einer Produktionsmaschine, aber Sie sollten kein Problem mit einer Entwicklungsumgebung haben. Es ist wichtig, dass Sie alle sicherstellen postgres Prozess wirklich beendet wurde, bevor Sie versuchen, PostgreSQL danach neu zu starten.

EDIT 2:

Aufgrund dieses unix.SE-Beitrags habe ich von kill -9zu geändert kill -15.

Jamon Holmgren
quelle
1
Nach meiner begrenzten Erfahrung mit Navicat Lite reicht es nicht immer aus, nur die Datenbank- oder Serververbindung zu schließen. Navicat Lite scheint die gelegentliche Verbindung offen zu halten, bis die Anwendung beendet wird.
Ken
3

Ich habe diesen Weg gelöst:

In meinem Windows8 64- Bit nur restartden Dienst: postgresql-x64-9.5

X-Coder
quelle
5
Dies ist nur ein Neustart, der im Allgemeinen für Produktionsumgebungen nicht wünschenswert ist. Das Beenden des Umarmungsprozesses ist eine viel wünschenswertere Option.
BrianC
3
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
Janki
quelle
1

Ich wollte nur darauf hinweisen, dass Haris 'Antwort möglicherweise nicht funktioniert, wenn ein anderer Hintergrundprozess die Datenbank verwendet. In meinem Fall handelte es sich um verzögerte Jobs. Ich habe Folgendes getan:

script/delayed_job stop

Und erst dann konnte ich die Datenbank löschen / zurücksetzen.

mlabarca
quelle
1

Beenden Sie postgres und starten Sie es neu. Einfach, funktioniert aber jedes Mal bei mir, wo andere CLI-Befehle dies manchmal nicht tun.

Stan Amsellem
quelle
Einfach und funktioniert! Zur weiteren Verdeutlichung ganz pgAdmin 4 und Neustart
Ka Tech
0

Es ist nicht nötig, es fallen zu lassen. Löschen Sie einfach das öffentliche Schema und erstellen Sie es neu. 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
jtsagata
quelle
0

Remote-Szenario. Aber wenn Sie versuchen, Tests in einer Rails-App auszuführen, erhalten Sie so etwas wie

"ActiveRecord :: StatementInvalid: PG :: ObjectInUse: ERROR: Datenbank" myapp_test "wird von anderen Benutzern aufgerufen. DETAIL: Es gibt 1 andere Sitzung, die die Datenbank verwendet."

Stellen Sie sicher, dass Sie pgAdmin oder andere Postgres-GUI-Tools schließen, bevor Sie Tests ausführen.

Shifa Khan
quelle
0

Fall:
Fehler beim Ausführen der Abfrage:

DROP TABLE dbo.t_tabelname

Lösung:
a. Zeigen Sie den Abfragestatus Aktivität wie folgt an:

SELECT * FROM pg_stat_activity  ;

b. Suchen Sie die Zeile, in der die Spalte "Abfrage" Folgendes enthält:

'DROP TABLE dbo.t_tabelname'

c. Erhalten Sie in derselben Zeile den Wert der Spalte 'PID'

example : 16409

d. Führen Sie die folgenden Skripte aus:

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'
    ;
Fahwi
quelle
0

Ich bin auf einem Mac und benutze Postgres via Postgres.app. Ich habe dieses Problem gelöst, indem ich die App beendet und erneut gestartet habe.

Juan José Ramírez
quelle
0

Öffnen Sie PGadmin, um festzustellen, ob eine Abfrageseite geöffnet ist, schließen Sie alle Abfrageseiten, trennen Sie den PostgresSQL-Server und verbinden Sie ihn erneut. Versuchen Sie, die Option Löschen / Löschen zu verwenden. Dies hat mir geholfen.

Pritam
quelle
0

In PG admin können Sie Ihren Server trennen (Rechtsklick auf den Server) und alle Sitzungen werden beim Neustart getrennt

Alex Binzar
quelle
0

Für mich hat folgendes funktioniert:

sudo gitlab-ctl stop
sudo gitlab-ctl start gitaly
sudo gitlab-rake gitlab:setup [type yes and let it finish]
sudo gitlab-ctl start

Ich benutze:
gitlab_edition: "gitlab-ce"
gitlab_version: '12 .4.0-ce.0.el7 '

Kostas Demiris
quelle
0

Suchen Sie zuerst nach Postgres, dessen Port ausgeführt wird

  1. ps -ef | grep postgres

    Es wird die Portnummer zurückgeben

  2. töte -9 port_number

Endlich wieder Postgres starten

brew services start postgresql 
Poonkodi
quelle