web-dev-qa-db-ja.com

Postgresql-DBへの自動接続が原因でデータベースを削除できない

データベースを削除しようとするたびに、私は得る:

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

私が使用する場合:

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

そのDBからの接続を終了しましたが、その後データベースをドロップしようとすると、誰かがそのデータベースに自動的に接続し、このエラーが発生します。それは何をしているのでしょうか?私以外は誰もこのデータベースを使用していません。

116
Andrius

将来の接続を防ぐことができます:

REVOKE CONNECT ON DATABASE thedb FROM public;

(そしておそらく他のユーザー/ロール。psql\l+を参照)

次に、自分のデータベースを除く、このデータベースへのすべての接続を終了できます。

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

古いバージョンではpidprocpidと呼ばれていましたので、それに対処する必要があります。

CONNECTの権利を取り消したため、自動接続しようとしていたものはすべて無効になります。

これで、DBを削除できるようになります。

通常の操作にスーパーユーザー接続を使用している場合、これは機能しませんが、その場合は最初にその問題を修正する必要があります。

133
Craig Ringer

データベースを削除しようとするたびに、私は得る:

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

最初に取り消す必要があります

REVOKE CONNECT ON DATABASE TARGET_DB FROM public;

次に使用します:

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

確実に機能します。

91
Suneel Kumar

接続がどこにあるのかを確認するだけです。これはすべて以下で見ることができます:

select * from pg_stat_activity where datname = 'TARGET_DB';

おそらくあなたの接続ですか?

26
user80168

私はこの問題の解決策を見つけましたターミナルでこのコマンドを実行してみてください

ps -ef | grep postgres

このコマンドによるプロセスの強制終了

Sudo kill -9 PID
25
Dinesh Pallapa

他のユーザーがデータベースにアクセスしていることを意味します...単に、postgresqlを再起動してください。このコマンドはトリックを行います

root@kalilinux:~#Sudo service postgresql restart

次に、データベースをドロップしてみてください。

postgres=# drop database test_database

これでうまくいきます。ハッピーコーディング

13
Suman Astani

マシン上の他のサービスに潜在的な影響がない場合は、単にservice postgresql restart

9
ScotchAndSoda

pgAdmin 4 UIを使用したソリューション

まだしていない場合は、ダッシュボードでショーアクティビティを有効にします。

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

次に、dbを使用してすべてのプロセスを無効にします。

  1. DB名をクリックします
  2. [ダッシュボード]> [セッション]をクリックします
  3. 更新アイコンをクリックします
  4. 各プロセスの横にある削除(x)アイコンをクリックして終了します

これで、データベースを削除できるはずです。

8
Andrew

解決:
1。 Pgサーバーをシャットダウンします
enter image description here
2。アクティブな接続をすべて切断します
3。 Pgサーバーを再起動
4。コマンドを試してください

4
amoljdv06

そのような単純な

Sudo service postgresql restart
4
OdkoPP

私の場合、AWS Redshift(Postgresベース)を使用しています。 DBへの他の接続はないようですが、この同じエラーが発生しています。

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

私の場合、データベースクラスターはまだデータベースに対して何らかの処理を行っているようで、他の外部/ユーザー接続はありませんが、データベースはまだ内部的に使用されています。次を実行してこれを見つけました。

SELECT * FROM stv_sessions;

それで、私のハックは、コードにループを記述し、データベース名が含まれる行を探すことでした。 (もちろん、ループは無限ではなく、眠いループなどです)

SELECT * FROM stv_sessions where db_name = 'XYZ';

行が見つかった場合は、各PIDを1つずつ削除します。

SELECT pg_terminate_backend(PUT_PID_HERE);

行が見つからない場合は、データベースの削除に進みます

DROP DATABASE XYZ;

注:私の場合、Javaユニット/システムテストを書いています。これは製品コードでは受け入れられません。


完全なハックはJavaにあります(私のテスト/ユーティリティクラスは無視してください)。

  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);
    }
  }
3
Sagan

上位の2つの回答が他の機会に役立つことがわかったが、今日、問題を解決する最も簡単な方法は、PyCharmがセッションを開いたままにしておくことであり、PyCharmでStopをクリックすると、 。 pgAdmin4をブラウザーで開いた状態で開いたところ、ほとんどすぐにデータベースセッションの統計が0に低下し、その時点でデータベースを削除できました。

1
hlongmore

ターミナルで次のコマンドを試してください:

ps -ef | grep postgres

次のように表示されます。

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

3番目の番号(3645)はPIDです。

これを削除できます

Sudo kill -9 3645

その後、PostgreSQL接続を開始します。

手動で開始:

pg_ctl -D /usr/local/var/postgres start
0
Alexandr