IT

PostgreSQL-DB에 대한 자동 연결로 인해 데이터베이스를 수 없습니다.

lottoking 2020. 7. 18. 09:44
반응형

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에서 데이터베이스를 삭제했지만 누군가 자동으로 해당 데이터베이스에 연결하여 발생합니다. 무엇을 할 수 있습니까? 나 외에는 아무도이 데이터베이스를 사용하지 않습니다.


연결을 방지 할 수 있습니다.

REVOKE CONNECT ON DATABASE thedb FROM public;

(그리고 아마도 다른 사용자 / 역할; 참조 \l+에서 psql)

그런 다음 자신을 제외하고 db에 대한 모든 연결을 종료 할 수 있습니다.

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

이전 버전에서는 pid호출이 procpid처리되어야합니다.

CONNECT권한을 철회하기 때문에 자동 연결을 시도한 모든 것이 더 이상 그렇게 할 수 없습니다.

이제 DB를 사용하십시오.

다음 작업에 수퍼 유저 연결을 사용하는 경우에는 작동하지 않지만 그렇게 먼저 해당 문제를 해결해야합니다.


데이터베이스를 삭제하려고 할 때마다 다음을 얻습니다.

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';

반드시 작동합니다.


이 문제에 대한 해결책을 찾았습니다. 터미널 에서이 명령을 실행하십시오.

ps -ef | grep postgres

이 명령으로 프로세스를 종료하십시오.

sudo kill -9 PID

연결이 어디에서 왔는지 확인하십시오. 이 모든 것을 다음에서 볼 수 있습니다.

select * from pg_stat_activity where datname = 'TARGET_DB';

아마도 당신의 연결입니까?


다른 사용자가 데이터베이스에 액세스하고 있음을 의미합니다 ... 간단히 postgresql을 다시 시작하십시오. 이 명령은 트릭을 수행합니다

root@kalilinux:~#sudo service postgresql restart

그런 다음 데이터베이스를 삭제하십시오.

postgres=# drop database test_database

이것은 트릭을 할 것입니다. 행복한 코딩


컴퓨터의 다른 서비스에 영향을 미치는 영향을 간단히 service postgresql restart


UI를 용매 pgAdmin 4 솔루션

다음을 수행하지 않은 경우 먼저 대시 보드에서 활동 표시를 활성화하십시오.

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

이제 db를 사용하여 모든 프로세스를 시작하십시오.

  1. DB 이름을 클릭하십시오
  2. 대시 보드> 세션을 클릭하십시오.
  3. 새로 고침 아이콘 클릭
  4. 각 프로세스 옆의 삭제 (x) 아이콘을 클릭하여 종료하십시오.

이제 db를 누르세요.


그렇게 간단

sudo service postgresql restart

해결 방법 :
1. Pg 서버를 종료합니다 . 2. 모든 활성 연결이 더러워집니다. 3. Pg 서버를 다시 시작합니다 . 4. 명령을 시도합니다
여기에 이미지 설명 입력




필자의 경우 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를 하나씩 삭제하십시오.

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

다른 경우에 두 개의 상위 투표 답변이 유용하다는 것을 알았지 만 오늘 문제를 해결하는 가장 간단한 방법은 PyCharm이 세션을 열어 둘 수 있음을 깨닫는 것이었고 PyCharm을 클릭하면 Stop도움이 될 수 있습니다. 브라우저에서 pgAdmin4를 연 상태에서 그렇게했고 거의 즉시 데이터베이스 세션 통계가 0으로 떨어지는 것을 보았습니다.이 시점에서 데이터베이스를 삭제할 수있었습니다.


터미널에서 다음 명령을 시도하십시오.

ps -ef | grep postgres

다음과 같이 표시됩니다.

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

세 번째 숫자 (3645)는 PID입니다.

이것을 삭제할 수 있습니다

sudo kill -9 3645

그 후 PostgreSQL 연결을 시작하십시오.

수동으로 시작 :

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

참고 URL : https://stackoverflow.com/questions/17449420/postgresql-unable-to-drop-database-because-of-some-auto-connections-to-db

반응형