postgresql - saber - postgres no sabe dónde encontrar el archivo de configuración del servidor
¿Cómo eliminar una base de datos PostgreSQL si hay conexiones activas a ella? (10)
Necesito escribir un script que deje caer una base de datos PostgreSQL. Puede haber muchas conexiones con él, pero la secuencia de comandos debería ignorarlo.
La consulta estándar DROP DATABASE db_name
no funciona cuando hay conexiones abiertas.
¿Cómo puedo solucionar el problema?
Acabo de reiniciar el servicio en Ubuntu para desconectar los clientes conectados.
sudo service postgresql stop
sudo service postgresql start
psql
DROP DATABASE DB_NAME;
Aquí está mi truco ... = D
# Make sure no one can connect to this database except you!
sudo -u postgres /usr/pgsql-9.4/bin/psql -c "UPDATE pg_database SET datallowconn=false WHERE datname=''<DATABASE_NAME>'';"
# Drop all existing connections except for yours!
sudo -u postgres /usr/pgsql-9.4/bin/psql -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = ''<DATABASE_NAME>'' AND pid <> pg_backend_pid();"
# Drop database! =D
sudo -u postgres /usr/pgsql-9.4/bin/psql -c "DROP DATABASE <DATABASE_NAME>;"
Pongo esta respuesta porque incluye un comando (arriba) para bloquear nuevas conexiones y porque cualquier intento con el comando ...
REVOKE CONNECT ON DATABASE <DATABASE_NAME> FROM PUBLIC, <USERS_ETC>;
... no funciona para bloquear nuevas conexiones!
Gracias a @araqnid @GoatWalker! = D
https://.com/a/3185413/3223785
Dependiendo de su versión de postgresql, puede encontrarse con un error, que hace que pg_stat_activity
omita las conexiones activas de los usuarios eliminados. Estas conexiones tampoco se muestran dentro de pgAdminIII.
Si está realizando pruebas automáticas (en las que también crea usuarios), este podría ser un escenario probable.
En este caso, debe volver a consultas como:
SELECT pg_terminate_backend(procpid)
FROM pg_stat_get_activity(NULL::integer)
WHERE datid=(SELECT oid from pg_database where datname = ''your_database'');
NOTA: En 9.2+ tendrás que cambiar procpid
a pid
.
En PostgreSQL 9.2 y superior, para desconectar todo excepto la sesión de la base de datos a la que está conectado:
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE datname = current_database()
AND pid <> pg_backend_pid();
En versiones anteriores es lo mismo, solo cambia pid
a procpid
. Para desconectarse de una base de datos diferente, simplemente cambie current_database()
al nombre de la base de datos de la que desea desconectar a los usuarios.
Es posible que desee REVOKE
el derecho de CONNECT
de los usuarios de la base de datos antes de desconectar a los usuarios; de lo contrario, los usuarios seguirán conectándose y nunca tendrá la oportunidad de abandonar la base de datos. Vea este comentario y la pregunta a la que está asociado: ¿Cómo puedo separar a todos los demás usuarios de la base de datos ?
Si solo quiere desconectar a los usuarios inactivos, vea esta pregunta .
En la solicitud de comando de Linux, primero detendría todos los procesos postgresql que se estén ejecutando al vincular este comando sudo /etc/init.d/postgresql restart
escriba el comando bg para verificar si otros procesos postgresql todavía se están ejecutando
luego seguido de dropdb dbname para eliminar la base de datos
sudo /etc/init.d/postgresql restart
bg
dropdb dbname
Esto funciona para mí en el símbolo del sistema de Linux
En mi caso, tuve que ejecutar un comando para eliminar todas las conexiones, incluida mi conexión de administrador activa
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE datname = current_database()
que terminó todas las conexiones y me muestra un mensaje de "error" fatal:
FATAL: terminating connection due to administrator command SQL state: 57P01
Después de eso fue posible eliminar la base de datos.
Esto eliminará las conexiones existentes, excepto la tuya:
Consulte pg_stat_activity
y obtenga los valores pid que desea eliminar, luego emita SELECT pg_terminate_backend(pid int)
para ellos.
PostgreSQL 9.2 y superior:
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = ''TARGET_DB'' -- ← change this to your DB
AND pid <> pg_backend_pid();
PostgreSQL 9.1 y más abajo:
SELECT pg_terminate_backend(pg_stat_activity.procpid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = ''TARGET_DB'' -- ← change this to your DB
AND procpid <> pg_backend_pid();
Una vez que desconecte a todos, deberá desconectar y emitir el comando DROP DATABASE desde una conexión desde otra base de datos, también conocida como la que no intenta eliminar.
Tenga en cuenta el cambio de nombre de la columna procpid
a pid
. Ver este hilo de la lista de correo .
Noté que postgres 9.2 ahora llama a la columna pid en lugar de procpid.
Tiendo a llamarlo desde la cáscara:
#!/usr/bin/env bash
# kill all connections to the postgres server
if [ -n "$1" ] ; then
where="where pg_stat_activity.datname = ''$1''"
echo "killing all connections to database ''$1''"
else
echo "killing all connections to database"
fi
cat <<-EOF | psql -U postgres -d postgres
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
${where}
EOF
Espero que sea de ayuda. Gracias a @JustBob por el sql.
Podría matar todas las conexiones antes de eliminar la base de datos utilizando la función pg_terminate_backend(int)
.
Puede obtener todos los backends en ejecución utilizando la vista del sistema pg_stat_activity
No estoy completamente seguro, pero lo siguiente probablemente matará todas las sesiones:
select pg_terminate_backend(procpid)
from pg_stat_activity
where datname = ''doomed_database''
Por supuesto que no puede estar conectado a esa base de datos
PostgreSQL 9.2 y superior:
SELECT pg_terminate_backend(pid)FROM pg_stat_activity WHERE datname = ''YOUR_DATABASE_NAME_HERE''