Postgresql - unable to drop database because of some auto connections to DB

橙三吉。 提交于 2019-11-29 18:45:33

You can prevent future connections:

REVOKE CONNECT ON DATABASE thedb FROM public;

(and possibly other users/roles; see \l+ in psql)

You can then terminate all connections to this db except your own:

SELECT pid, pg_terminate_backend(pid) 
FROM pg_stat_activity 
WHERE datname = current_database() AND pid <> pg_backend_pid();

On older versions pid was called procpid so you'll have to deal with that.

Since you've revoked CONNECT rights, whatever was trying to auto-connect should no longer be able to do so.

You'll now be able to drop the DB.

This won't work if you're using superuser connections for normal operations, but if you're doing that you need to fix that problem first.

Whenever I try to drop database I get:

ERROR:  database "pilot" is being accessed by other users
DETAIL:  There is 1 other session using the database.

First You need to revoke

REVOKE CONNECT ON DATABASE TARGET_DB FROM public;

Then use:

SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'TARGET_DB';

It will surely work.

Simply check what is the connection, where it's coming from. You can see all this in:

select * from pg_stat_activity where datname = 'TARGET_DB';

Perhaps it is your connection?

I found a solution for this problem try to run this command in terminal

ps -ef | grep postgres

kill process by this command

sudo kill -9 PID

It means other user is accessing the database... Simply, restart the postgresql. This command will do the trick

root@kalilinux:~#sudo service postgresql restart

Then Try dropping the database:

postgres=# drop database test_database

This will do the trick. Happy coding

If no potential impact on other services on your machine, simply service postgresql restart

pgAdmin 4 solution using UI

First enable show activity on dashboard if you haven't:

File > Preferences > Dashboards > Display > Show Activity > true

Now disable all the processes using the db:

  1. Click the DB name
  2. Click Dashboard > Sessions
  3. Click refresh icon
  4. Click the delete (x) icon beside each process to end them

Should now be able to delete the db.

Simple as that

sudo service postgresql restart

Solution:
1. Shut down Pg server


2. It will disconnect all active connection
3. Restart Pg Server
4. Try your command

In my case, I am using AWS Redshift (based on Postgres). And it appears there are no other connections to the DB, but I am getting this same error.

ERROR:  database "XYZ" is being accessed by other users

In my case, it seems the database cluster is still doing some processing on the database, and while there are no other external/user connections, the database is still internally in use. I found this by running the following:

SELECT * FROM stv_sessions;

So my hack was to write a loop in my code, looking for rows with my database name in it. (of course the loop is not infinite, and is a sleepy loop, etc)

SELECT * FROM stv_sessions where db_name = 'XYZ';

If rows found, proceed to delete each PID, one by one.

SELECT pg_terminate_backend(PUT_PID_HERE);

If no rows found, proceed to drop the database

DROP DATABASE XYZ;

Note: In my case, I am writing Java unit/system tests, where this could be considered acceptable. This is not acceptable for production code.


Here is the complete hack, in Java (ignore my test/utility classes).

  int i = 0;
  while (i < 10) {
    try {
      i++;
      logStandardOut("First try to delete session PIDs, before dropping the DB");
      String getSessionPIDs = String.format("SELECT stv_sessions.process, stv_sessions.* FROM stv_sessions where db_name = '%s'", dbNameToReset);
      ResultSet resultSet = databaseConnection.execQuery(getSessionPIDs);
      while (resultSet.next()) {
        int sessionPID = resultSet.getInt(1);
        logStandardOut("killPID: %s", sessionPID);
        String killSessionPID = String.format("select pg_terminate_backend(%s)", sessionPID);
        try {
          databaseConnection.execQuery(killSessionPID);
        } catch (DatabaseException dbEx) {
          //This is most commonly when a session PID is transient, where it ended between my query and kill lines
          logStandardOut("Ignore it, you did your best: %s, %s", dbEx.getMessage(), dbEx.getCause());
        }
      }

      //Drop the DB now
      String dropDbSQL = String.format("DROP DATABASE %s", dbNameToReset);
      logStandardOut(dropDbSQL);
      databaseConnection.execStatement(dropDbSQL);
      break;
    } catch (MissingDatabaseException ex) {
      //ignore, if the DB was not there (to be dropped)
      logStandardOut(ex.getMessage());
      break;
    } catch (Exception ex) {
      logStandardOut("Something went wrong, sleeping for a bit: %s, %s", ex.getMessage(), ex.getCause());
      sleepMilliSec(1000);
    }
  }

While I found the two top-upvoted answers useful on other occasions, today, the simplest way to resolve the issue was to realize that PyCharm might be keeping a session open, and if I clicked Stop in PyCharm, that might help. With pgAdmin4 open in the browser, I did so, and almost immediately saw the Database sessions stats drop to 0, at which point I was able to drop the database.

In terminal try this command:

ps -ef | grep postgres

you will see like:

501 1445 3645 0 12:05AM 0:00.03 postgres: sasha dbname [local] idle

The third number (3645) is PID.

You can delete this

sudo kill -9 3645

And after that start your PostgreSQL connection.

Start manually:

pg_ctl -D /usr/local/var/postgres start
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!