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와의 연결을 종료했지만, 그 이후에 데이터베이스를 삭제하려고 하면 어떤 사람이 자동으로 해당 데이터베이스에 연결하여 이 오류를 표시합니다.무엇이 그렇게 할 수 있을까요?나를 제외하고는 아무도 이 데이터베이스를 사용하지 않습니다.
포스트그레스 13+
사용하다WITH (force)
대신 https://stackoverflow.com/a/68982312/398670 을 참조하십시오.
포스트그레스 12 이상
다음과의 연결을 방지할 수 있습니다.
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를 삭제할 수 있습니다.
일반적인 작업에 슈퍼 사용자 연결을 사용하는 경우에는 이 기능이 작동하지 않지만, 슈퍼 사용자 연결을 사용하는 경우에는 먼저 문제를 해결해야 합니다.
데이터베이스를 삭제한 후 데이터베이스를 다시 작성할 경우 아래 명령을 실행하여 액세스 권한을 복원할 수 있습니다.
GRANT CONNECT ON DATABASE thedb TO public;
데이터베이스를 삭제할 때마다 다음 메시지가 나타납니다.
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
Postgresql의 업데이트 13
이 명령을 사용하여 데이터베이스를 강제로 삭제하여 데이터베이스에 연결된 각 사용자/앱의 연결을 끊을 수 있습니다.
DROP DATABASE db_name WITH (FORCE)
자세한 내용은 설명서를 참조하십시오.
강제 - 대상 데이터베이스에 대한 기존 연결을 모두 종료합니다.준비된 트랜잭션, 활성 논리 복제 슬롯 또는 구독이 대상 데이터베이스에 있는 경우 종료되지 않습니다.
다른 사용자가 데이터베이스에 액세스하고 있음을 의미합니다.Postgre를 다시 시작하기만 하면 됩니다.SQL. 이 명령어는 다음과 같은 효과를 발휘합니다.
root@kalilinux:~#sudo service postgresql restart
그런 다음 데이터베이스를 삭제합니다.
postgres=# drop database test_database;
이 정도면 효과가 있을 겁니다.
연결이 무엇인지, 어디에서 왔는지 확인하기만 하면 됩니다.이 모든 것은 다음에서 확인할 수 있습니다.
SELECT * FROM pg_stat_activity WHERE datname = 'TARGET_DB';
아마도 그것이 당신의 연결고리인가요?
pgAdmin 4를 사용한 GUI 솔루션
다음이 없는 경우 먼저 대시보드에서 활동 표시를 활성화합니다.
File > Preferences > Dashboards > Display > Show Activity > true
이제 db를 사용하여 모든 프로세스를 비활성화합니다.
- DB 이름 클릭
- 대시보드 > 세션 클릭
- 새로 고침 아이콘 클릭
- 각 프로세스 옆에 있는 삭제(x) 아이콘을 클릭하여 프로세스를 종료합니다.
이제 DB를 삭제할 수 있습니다.
에는 간단히 "" "" "" "" "" ""를 하십시오.service postgresql restart
솔루션:
Pg ( 서버 종료)
연결이 끊어집니다.
Pg 는 서버
명령어를 사용해 보십시오.
macOS에서 다음 명령을 사용하여 콘솔을 통해 postgresql 데이터베이스를 다시 시작해 봅니다.
brew services restart postgresql
그것처럼 간단함
sudo service postgresql restart
REVOKE CONNECT
DB 소유자 또는 수퍼유저로부터의 연결을 차단하지 않습니다.따라서 아무도 DB를 연결하지 않으려면 follow 명령을 사용하는 것이 유용할 수 있습니다.
alter database pilot allow_connections = off;
다음을 사용합니다.
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'pilot';
첫 번째:
sudo systemctl restart postgresql
그러면:
drop database DATABASE_NAME;
이것이 포스트 12에서 우리에게 효과가 있었던 것입니다.pgadmin, pgbouncer 및 다중 클라이언트 응용 프로그램 사용.
REVOKE CONNECT ON DATABASE <mydbname> FROM public;
ALTER DATABASE <mydbname> allow_connections = off;
SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '<mydbname>';
DROP DATABASE <mydbname>;
저의 경우 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 유닛/시스템 테스트를 작성하고 있습니다. 이 테스트는 허용 가능한 것으로 간주됩니다.이것은 생산 코드에 허용되지 않습니다.
이것은 자바로 된 완전한 해킹입니다 (내 테스트/유틸리티 클래스는 무시합니다).)
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);
}
}
백그라운드에서 실행 중인 유휴 쿼리가 있다고 생각합니다.
- 실행 중인 쿼리를 먼저 표시해 보십시오.
SELECT pid, age(clock_timestamp(), query_start), usename, query FROM pg_stat_activity WHERE query != '<IDLE>' AND query NOT ILIKE '%pg_stat_activity%' ORDER BY query_start desc;
- kill idle query (해당 데이터베이스를 참조하는지 확인하거나 선택한 결과의 pid를 사용하여 모두 죽이거나 특정 데이터베이스를 죽일 수 있습니다.)
선택 pg_terminate_backend(procpid);
참고: 선택 쿼리를 종료해도 나쁜 영향을 미치지 않습니다.
도커를 사용하여 postgresql 서버를 실행하는 경우 컨테이너를 재시작합니다.
이 유용하다는 방법은 을 계속 수 것을 이었습니다. 제가 "PyCharm"을 클릭했다면, "PyCharm"을 클릭했을 때입니다.Stop
파이참에서, 그것은 도움이 될 것입니다.브라우저에서 pgAdmin4를 열었을 때, 저는 그렇게 했고, 거의 즉시 데이터베이스 세션 통계가 0으로 떨어지는 것을 보았고, 그 시점에서 데이터베이스를 삭제할 수 있었습니다.
IntelliJ에서 이 오류가 발생할 경우 아래 표시된 버튼을 클릭하여 모든 창에서 연결을 닫아야 합니다.
저의 경우, 실행 후 바로 다른 사용자 연결이 생성되었기 때문에 아래 명령을 사용한 후에도 계속 오류가 발생했습니다.
REVOKE CONNECT ON DATABASE <db_name> FROM public;
연결을 방지하기 위해 위(아래)의 inferno 솔루션을 사용한 것이 해결되었습니다.
ALTER DATABASE <db_name> allow_connections = off
이를 통해 프로세스를 즉시 다시 만들지 않고 프로세스를 종료할 수 있었습니다.
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을 다시 시작합니다.
systemctl restart postgresql
Postgresql12
인기 있는 대답은 나에게 도움이 되지 않습니다.
나에게는 분명하지 않은 해결책: 카프카/토끼를 사용하는 경우 DROP TABLE 전에 감독자를 비활성화합니다.
sudo service supervisor stop
터미널에서 다음 명령을 사용해 보십시오.
ps -ef | grep postgres
다음과 같이 표시됩니다.
501 1445 3645 0 12:05AM 0:00.03 postgres: sasha dbname [local] 유휴
세 번째 숫자(3645)는 PID입니다.
삭제할 수 있습니다.
sudo kill -9 3645
그리고 그 후에 당신의 Postgre를 시작합니다.SQL 연결.
수동으로 시작:
pg_ctl -D /usr/local/var/postgres start
실행 중인 응용 프로그램을 중지합니다.(이클립스에서) 다시 시도한 후에.
DB를 사용하는 서비스가 실행되고 있지 않은지 확인해야 합니다.
일부 Java 앱을 실행하는 등 동일한 문제가 발생했으며, 위의 옵션 중 어떤 것도 작동하지 않았으며, 다시 시작하지도 않았습니다.
실행 aps aux
DB를 사용하여 메인 서비스를 종료합니다.
kill -9 'PID'
신청의- 또는 응용 프로그램이 서비스로 실행되는 경우 반드시
service stop
사용 중인 OS의 cmd.
그런 다음 테이블을 삭제하는 기본 방법이 완벽하게 작동합니다.
제 예에서는 다음과 같은 문제가 있었습니다.
언급URL : https://stackoverflow.com/questions/17449420/postgresql-unable-to-drop-database-because-of-some-auto-connections-to-db
'programing' 카테고리의 다른 글
C# 6.0은 에 적용됩니까?NET 4.0? (0) | 2023.05.07 |
---|---|
피쳐 분기를 다른 피쳐 분기로 기본 재배치 (0) | 2023.05.07 |
Ubuntu에서 Tkinter 모듈을 찾을 수 없습니다. (0) | 2023.05.07 |
와일드카드가 있는 폴더를 도커 컨테이너에서 호스트로 복사 (0) | 2023.05.07 |
WPF 바인딩 명령 매개 변수="{Binding}" 이해 (0) | 2023.05.07 |