database - usuarios - pg_terminate_backend
Matar una sesión/conexión postgresql (15)
Caso:
Fallo al ejecutar la consulta:
DROP TABLE dbo.t_tabelname
Solución:
a. Mostrar actividad de estado de consulta de la siguiente manera:
SELECT * FROM pg_stat_activity ;
segundo. Buscar fila donde la columna ''Consulta'' contiene:
''DROP TABLE dbo.t_tabelname''
do. En la misma fila, obtenga el valor de la columna ''PID''
example : 16409
re. Ejecutar estos scripts:
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''
;
¿Cómo puedo matar todas mis conexiones postgresql?
Estoy probando un rake db:drop
pero me sale:
ERROR: database "database_name" is being accessed by other users
DETAIL: There are 1 other session(s) using the database.
He intentado cerrar los procesos que veo desde un ps -ef | grep postgres
ps -ef | grep postgres
pero esto tampoco funciona:
kill: kill 2358 failed: operation not permitted
Con todas las informaciones sobre el proceso en ejecución:
SELECT *, pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE pid <> pg_backend_pid()
AND datname = ''my_database_name'';
Escenario remoto. Pero si estás tratando de ejecutar pruebas en una aplicación de Rails, y obtienes algo como
"ActiveRecord :: StatementInvalid: PG :: ObjectInUse: ERROR: otros usuarios acceden a la base de datos" myapp_test "DETALLE: Hay 1 sesión más usando la base de datos".
Asegúrese de cerrar pgAdmin o cualquier otra herramienta GUI de postgres antes de ejecutar pruebas.
Esto parece estar funcionando para 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
Levantado de los gistas encontrados here y here .
Aquí hay una versión modificada que funciona tanto para PostgreSQL 9.1 como para 9.2.
He solucionado este camino:
En mi Windows8 de 64 bits, simplemente restart
el servicio: postgresql-x64-9.5
MacOS, si postgresql fue instalado con brew :
brew services restart postgresql
No hay necesidad de dejarlo caer. Simplemente borre y vuelva a crear el esquema público. En la mayoría de los casos esto tiene exactamente el mismo efecto.
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
OSX, Postgres 9.2 (instalado con 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 su datadir está en otro lugar, puede averiguar dónde está examinando la salida de ps aux | grep postgres
ps aux | grep postgres
Puedes usar pg_terminate_backend() para matar una conexión. Tienes que ser superusuario para usar esta función. Esto funciona en todos los sistemas operativos de la misma manera.
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''
;
Antes de ejecutar esta consulta, tiene que REVOKE los privilegios de CONEXIÓN para evitar nuevas conexiones:
REVOKE CONNECT ON DATABASE dbname FROM PUBLIC, username;
Si está usando Postgres 8.4-9.1 use procpid en lugar 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''
;
Salga de postgres y reinícielo. Simple, pero funciona siempre para mí, donde a veces otros comandos cli no lo hacen.
Solo quería señalar que la respuesta de Haris podría no funcionar si algún otro proceso en segundo plano está utilizando la base de datos, en mi caso, se retrasaron los trabajos, lo hice:
script/delayed_job stop
Y solo entonces pude soltar / restablecer la base de datos.
Tal vez simplemente reinicie postgres
=> sudo service postgresql restart
Tenía este problema y el problema era que Navicat estaba conectado a mi db local de Postgres. Una vez desconectado Navicat el problema desapareció.
EDITAR:
Además, como último recurso , puede hacer una copia de seguridad de sus datos y luego ejecutar este comando:
sudo kill -15 `ps -u postgres -o pid`
... lo que matará todo lo que el usuario postgres está accediendo Evite hacer esto en una máquina de producción, pero no debería tener problemas con un entorno de desarrollo. Es vital que se asegure de que cada proceso de postgres
haya terminado realmente antes de intentar reiniciar PostgreSQL después de esto.
EDIT 2:
Debido a esta publicación de unix.SE , he cambiado de kill -9
a kill -15
.
Utilizo la siguiente tarea de rake para anular el método drop_database
Rails.
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
Edición: Esto es para Postgresql 9.2+
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