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

前端 未结 17 1632
一向
一向 2020-12-12 08:18

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.


        
相关标签:
17条回答
  • 2020-12-12 08:56

    What you need to be certain is that the service using the DB is not running.

    Experienced same issue, running some Java apps, and none of the above options worked, not even restart.

    Run a ps aux kill the main service using the DB.

    • kill -9 'PID' of the application
    • or if the application runs as a service make sure to run the service stop cmd for your OS.

    After that the default way to drop a table will work flawlessly.

    In my example were issues with

    0 讨论(0)
  • 2020-12-12 08:57

    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
    
    0 讨论(0)
  • 2020-12-12 08:57

    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.

    0 讨论(0)
  • 2020-12-12 08:58

    In macOS try to restart postgresql database through the console using the command:

    brew services restart postgresql
    
    0 讨论(0)
  • 2020-12-12 09:00

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

    0 讨论(0)
  • 2020-12-12 09:02

    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);
        }
      }
    
    0 讨论(0)
提交回复
热议问题