web-dev-qa-db-fra.com

Tuer une session/connexion postgresql

Comment puis-je tuer toutes mes connexions postgresql?

J'essaie un rake db:drop mais je reçois:

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

J'ai essayé d'arrêter les processus que je vois depuis un ps -ef | grep postgres mais cela ne marche pas non plus:

kill: kill 2358 failed: operation not permitted
280
DanS

Vous pouvez utiliser pg_terminate_backend () pour tuer une connexion. Vous devez être superutilisateur pour utiliser cette fonction. Cela fonctionne sur tous les systèmes d'exploitation les mêmes. 

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'
    ;

Avant d'exécuter cette requête, vous devez R&EACUTE;VOQUER les privilèges CONNECT pour éviter de nouvelles connexions:

REVOKE CONNECT ON DATABASE dbname FROM PUBLIC, username;

Si vous utilisez Postgres 8.4-9.1, utilisez procpid au lieu de 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'
    ;
519
Frank Heikens

Peut-être qu'il suffit de redémarrer postgres => Sudo service postgresql restart 

172
Haris Krajina

Avec toutes les informations sur le processus en cours:

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

OSX, Postgres 9.2 (installé avec 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


Si votre datadir est ailleurs, vous pouvez le trouver en examinant le résultat de ps aux | grep postgres

12
artemave

MacOS, si postgresql a été installé avec brew:

brew services restart postgresql

Source: Tuer une session/connexion postgresql

8
Juuso Ohtonen

Cela semble fonctionner pour 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

Levé des idées trouvées ici et ici .

Voici une version modifiée qui fonctionne à la fois pour PostgreSQL 9.1 et 9.2.

8
Chris

J'utilise la tâche de rake suivante pour remplacer la méthode 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

Edit: Ceci est pour Postgresql 9.2+ 

6
Chris Aitchison

J'avais ce problème et le problème était que Navicat était connecté à ma base de données Postgres locale. Une fois que j'ai déconnecté Navicat, le problème a disparu.

MODIFIER:

En outre, en dernier recours absolu , vous pouvez sauvegarder vos données, puis exécuter cette commande:

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

... qui va tuer tout ce à quoi l'utilisateur postgres a accès. Évitez de le faire sur une machine de production, mais vous ne devriez pas avoir de problème avec un environnement de développement. Avant de tenter de redémarrer PostgreSQL, vous devez vous assurer que chaquepostgres processus est bien terminé.

EDIT 2:

En raison de cet article unix.SE je suis passé de kill -9 à kill -15.

4
Jamon Holmgren

J'AI RÉSOLU CETTE MANIÈRE:

Dans mon Windows8 64 bit, restarting le service: postgresql-x64-9.5

2
X-Coder

Plus facile et plus à jour est:

  1. Utilisez ps -ef | grep postgres pour trouver la connexion #
  2. Sudo kill -9 "#" de la connexion

Remarque: Il peut y avoir un PID identique. Tuer un tue tous.

1
Mr. Rene
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
1
Janki

Quittez postgres et redémarrez-le. C'est simple, mais ça marche à chaque fois pour moi, là où d'autres commandes cli ne le sont parfois.

1
Stan Amsellem

Je voulais juste souligner que la réponse de Haris pourrait ne pas fonctionner si un autre processus d'arrière-plan utilise la base de données.

script/delayed_job stop

Et alors seulement, j'ai pu supprimer/réinitialiser la base de données.

1
mlabarca

Il n'y a pas besoin de le laisser tomber. Il suffit de supprimer et de recréer le schéma public. Dans la plupart des cas, cela a exactement le même effet.

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
0
jtsagata

Scénario à distance. Mais si vous essayez d'exécuter des tests dans une application Rails et que vous obtenez quelque chose comme:

"ActiveRecord :: StatementInvalid: PG :: ObjectInUse: ERROR: la base de données" myapp_test "est utilisée par d'autres utilisateurs DÉTAIL: une autre session utilise la base de données."

Assurez-vous de fermer pgAdmin ou tout autre outil d'interface graphique de postgres avant d'exécuter les tests.

0
Shifa Khan

Ouvrez PGadmin pour voir si une page de requête est ouverte, fermez-la et déconnectez le serveur PostgresSQL, puis connectez-le à nouveau et essayez l'option de suppression/suppression.

0
Pritam

Je suis sur un Mac et j'utilise postgres via Postgres.app. J'ai résolu ce problème en quittant et en redémarrant l'application.

0
Juan José Ramírez