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
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'
;
Peut-être qu'il suffit de redémarrer postgres
=> Sudo service postgresql restart
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';
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
MacOS, si postgresql a été installé avec brew:
brew services restart postgresql
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.
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+
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
.
J'AI RÉSOLU CETTE MANIÈRE:
Dans mon Windows8 64 bit, restart
ing le service: postgresql-x64-9.5
Plus facile et plus à jour est:
ps -ef | grep postgres
pour trouver la connexion #Sudo kill -9 "#"
de la connexionRemarque: Il peut y avoir un PID identique. Tuer un tue tous.
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
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.
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.
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
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.
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.
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.