Postgresql - DB के लिए कुछ ऑटो कनेक्शन के कारण डेटाबेस को छोड़ने में असमर्थ


161

जब भी मैं डेटाबेस को प्राप्त करने की कोशिश करता हूं तो मुझे यह मिलता है:

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 से कनेक्शन को समाप्त कर दिया है, लेकिन अगर मैं डेटाबेस को छोड़ने की कोशिश करता हूं, तो किसी तरह कोई व्यक्ति स्वचालित रूप से उस डेटाबेस से जुड़ जाता है और यह त्रुटि देता है। वह क्या कर सकता है? मेरे अलावा कोई भी इस डेटाबेस का उपयोग नहीं करता है।

जवाबों:


194

आप भविष्य के कनेक्शन को रोक सकते हैं:

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;

19
यदि आप बाद में इसी नाम के साथ एक और डेटाबेस आयात करते हैं, तो जनता को वापस कनेक्ट करने की क्षमता प्रदान करें:GRANT CONNECT ON DATABASE thedb TO public;
मिखाइल वासिन

155

जब भी मैं डेटाबेस को प्राप्त करने की कोशिश करता हूं तो मुझे यह मिलता है:

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

यह निश्चित रूप से काम करेगा।


5
इसने मेरे लिए यह किया। धन्यवाद
rpivovar

सटीक! धन्यवाद! 🎉
slajma

सही काम किया। धन्यवाद।
मुस्तफा मगदी

34

मुझे इस समस्या का समाधान टर्मिनल में इस आदेश को चलाने के लिए मिला

ps -ef | grep postgres

इस कमांड द्वारा मार प्रक्रिया

sudo kill -9 PID

नहीं, यह बहुत मुश्किल है, क्या होगा यदि आप पीजी प्रक्रिया को रद्द नहीं कर सकते क्योंकि आपके पास अन्य डेटाबेस हैं जो एक्सेस किए जा रहे हैं?
व्लादिमीर स्टाज़िलोव

2
@VladimirStazhilov यह डेटाबेस का नाम और उस डेटाबेस के पिड को दिखाएगा। कोई व्यक्ति केवल उस विशेष डेटाबेस को विशिष्ट पीआईडी ​​किल चुन सकता है।
दिनेश पल्लपा

29

बस जांचें कि कनेक्शन क्या है, यह कहां से आ रहा है। आप यह सब देख सकते हैं:

select * from pg_stat_activity where datname = 'TARGET_DB';

शायद यह आपका कनेक्शन है?


4
sudo किल -9 PID इन टर्मिनल देखने के बाद परिणाम
Dan Rey Oquindo

25

इसका मतलब है कि एक अन्य उपयोगकर्ता डेटाबेस तक पहुंच रहा है। बस PostgreSQL को पुनः आरंभ करें। यह कमांड ट्रिक करेगा

root@kalilinux:~#sudo service postgresql restart

फिर डेटाबेस छोड़ने का प्रयास करें:

postgres=# drop database test_database;

यह चाल चलेगा।


11

UI का उपयोग करके pgAdmin 4 समाधान

अगर आपने नहीं किया है तो पहले डैशबोर्ड पर शो गतिविधि को सक्षम करें:

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

अब db का उपयोग करके सभी प्रक्रियाओं को अक्षम करें:

  1. DB नाम पर क्लिक करें
  2. डैशबोर्ड> सत्र पर क्लिक करें
  3. रिफ्रेश आइकन पर क्लिक करें
  4. उन्हें समाप्त करने के लिए प्रत्येक प्रक्रिया के पास हटाएं (x) आइकन पर क्लिक करें

अब db को डिलीट करने में सक्षम होना चाहिए।


यह अच्छी तरह से काम करता है - मैंने इसे PgAdmin 4.5 के साथ और PostgreSQL 11.2 के साथ, विजुअल C ++ बिल्ड 1914, 64-बिट (विंडोज) द्वारा संकलित किया।
vab2048

2
मेरे हिसाब से यह सबसे अच्छा उपाय है। यह वास्तव में अच्छी तरह से काम करता है!
लाहिरु

10

यदि आपकी मशीन पर अन्य सेवाओं पर कोई संभावित प्रभाव नहीं है, तो बस service postgresql restart


8

समाधान:
1. Pg सर्वर को शट डाउन करें । यह सभी सक्रिय कनेक्शन को डिस्कनेक्ट कर देगा । Pg सर्वर को पुनरारंभ करें 4. अपना कमांड आज़माएं
यहां छवि विवरण दर्ज करें




यह मेरे लिए भी Postgrad.app के साथ एक मैक पर काम किया। उस स्थिति में आप सर्वर को रोकते / शुरू करते हैं
जुआन जोस रामिरेज़


3

मेरे मामले में, मैं 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;

नोट: मेरे मामले में, मैं जावा यूनिट / सिस्टम परीक्षण लिख रहा हूं, जहां इसे स्वीकार्य माना जा सकता है। यह उत्पादन कोड के लिए स्वीकार्य नहीं है।


यहाँ जावा में पूर्ण हैक है, (मेरे परीक्षण / उपयोगिता वर्गों को अनदेखा करें)।

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

2

मेरी राय में बैकग्राउड में कुछ निष्क्रिय प्रश्न चल रहे हैं।

  1. पहले चल रहे प्रश्नों को दिखाने का प्रयास करें
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;
  1. आइडल क्वेरी को मारें (चेक करें कि क्या वे प्रश्न में डेटाबेस को संदर्भित कर रहे हैं या आप उन सभी को मार सकते हैं या चुनिंदा परिणामों से पिड का उपयोग करके विशिष्ट को मार सकते हैं)

चयनित pg_terminate_backend (procpid);

नोट: चुनिंदा क्वेरी को मारने से कोई बुरा प्रभाव नहीं पड़ता है


2

REVOKE CONNECTdb मालिक या सुपरयुसर से कनेक्शन को नहीं रोकेगा। तो अगर आप नहीं चाहते कि कोई भी db को जोड़े, तो कमांड का पालन उपयोगी हो सकता है।

alter database pilot allow_connections = off;

फिर उपयोग करें:

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

1
धन्यवाद ... REVOKE CONNECT मेरे परिदृश्य पर पर्याप्त नहीं था।
ज्वालामुखी

1

जबकि मुझे अन्य अवसरों पर उपयोगी दो टॉप-अपवॉट किए गए उत्तर मिले, आज, इस मुद्दे को हल करने का सबसे सरल तरीका यह महसूस करना था कि PyCharm एक सत्र खुला रख सकता है, और यदि मैं StopPyCharm में क्लिक करता हूं, तो इससे मदद मिल सकती है। ब्राउज़र में pgAdmin4 के खुले होने के साथ, मैंने ऐसा किया, और लगभग तुरंत डेटाबेस सत्र के आँकड़े को 0 पर देखा, जिस बिंदु पर मैं डेटाबेस को छोड़ने में सक्षम था।


"PyCharm एक सत्र खुला रख सकता है"? कैसे? मैं PyCharm के टर्मिनल (पेवे, बैकेंड पोस्टग्रेज के साथ फ्रंट पायथन) में यूनिट टेस्ट चलाता हूं, अर्थात "स्टॉप" बटन को बाहर निकाल दिया जाता है और मैं इन त्रुटियों को फिर भी रखता हूं ...
Laryx Decidua

@LaryxDecidua मुझे विश्वास है कि, मेरे मामले में, मुझे PyCharm में चल रही एक सेवा का उदाहरण अवश्य मिला होगा जिसमें db का उपयोग किया गया था। यदि आप Pyharm से बाहर निकलते हैं, तो क्या उदाहरणों की संख्या 0 पर गिरती है, जिससे आप db को छोड़ सकते हैं? यदि ऐसा है, तो कुछ होना चाहिए (डेटाबेस एक्सप्लोरर, SQL क्वेरी, कुछ और) जो अभी भी जुड़ा हुआ है।
hlongmore

1

MacOS में कमांड का उपयोग करके कंसोल के माध्यम से पोस्टग्रैसक्ल डेटाबेस को पुनः आरंभ करने का प्रयास करें:

brew services restart postgresql

-1

टर्मिनल में इस कमांड को आज़माएं:

ps -ef | grep postgres

आप इस तरह देखेंगे:

501 1445 3645 0 12:05 AM 0: 00.03 पोस्टग्रैड्स: साशा dbname [स्थानीय] निष्क्रिय

तीसरा नंबर (3645) पीआईडी ​​है।

आप इसे हटा सकते हैं

sudo kill -9 3645

और इसके बाद अपना PostgreSQL कनेक्शन शुरू करें।

मैन्युअल रूप से प्रारंभ करें:

pg_ctl -D /usr/local/var/postgres start
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.