यदि कोई सक्रिय कनेक्शन है तो PostgreSQL डेटाबेस को कैसे छोड़ें?




(7)

PostgreSQL 9.2 और बाद में, डेटाबेस से अपने सत्र को छोड़कर सब कुछ डिस्कनेक्ट करने के लिए आप कनेक्ट हैं:

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

पुराने संस्करणों में यह वही है, केवल procpid pid बदलें। किसी भिन्न डेटाबेस से डिस्कनेक्ट करने के लिए बस current_database() को उस डेटाबेस के नाम पर बदलें जिसे आप उपयोगकर्ताओं से डिस्कनेक्ट करना चाहते हैं।

आप उपयोगकर्ताओं को डिस्कनेक्ट करने से पहले डेटाबेस के उपयोगकर्ताओं से सीधे CONNECT करना चाहते हैं, अन्यथा उपयोगकर्ता फिर से कनेक्ट हो जाएंगे और आपको डीबी को छोड़ने का मौका कभी नहीं मिलेगा। इस टिप्पणी और प्रश्न के साथ जुड़े प्रश्न को देखें, मैं डेटाबेस से अन्य सभी उपयोगकर्ताओं को कैसे अलग कर सकता हूं

यदि आप निष्क्रिय उपयोगकर्ताओं को डिस्कनेक्ट करना चाहते हैं, तो यह प्रश्न देखें।

मुझे एक स्क्रिप्ट लिखनी है जो PostgreSQL डेटाबेस को छोड़ देगा। इसके साथ बहुत सारे कनेक्शन हो सकते हैं, लेकिन लिपि को इसे अनदेखा करना चाहिए।

खुले कनेक्शन होने पर मानक DROP DATABASE db_name क्वेरी काम नहीं करती है।

मैं समस्या को कैसे हल कर सकता हूँ!


Postgresql के आपके संस्करण के आधार पर आप एक बग में भाग सकते हैं, जो गिराए गए उपयोगकर्ताओं से सक्रिय कनेक्शन को छोड़ने के लिए pg_stat_activity बनाता है। ये कनेक्शन pgAdminIII के अंदर भी नहीं दिखाए जाते हैं।

यदि आप स्वचालित परीक्षण कर रहे हैं (जिसमें आप उपयोगकर्ता भी बनाते हैं) यह एक संभावित परिदृश्य हो सकता है।

इस मामले में आपको प्रश्नों पर वापस लौटना होगा जैसे:

 SELECT pg_terminate_backend(procpid) 
 FROM pg_stat_get_activity(NULL::integer) 
 WHERE datid=(SELECT oid from pg_database where datname = 'your_database');

नोट: 9.2+ में आप procpid को pid बदल देंगे।


मेरे मामले में मुझे अपने सक्रिय व्यवस्थापक कनेक्शन सहित सभी कनेक्शन ड्रॉप करने के लिए कमांड निष्पादित करना पड़ा

SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE datname = current_database()

जिसने सभी कनेक्शन को समाप्त कर दिया और मुझे एक घातक 'त्रुटि' संदेश दिखाया:

FATAL: terminating connection due to administrator command SQL state: 57P01

उसके बाद डेटाबेस छोड़ना संभव था


मैं बस जुड़े ग्राहकों को डिस्कनेक्ट करने के लिए उबंटू में सेवा को पुनरारंभ करता हूं।

sudo service postgresql stop
sudo service postgresql start

psql
DROP DATABASE DB_NAME;

यह आपके अलावा सिवाय मौजूदा कनेक्शन छोड़ देगा:

क्वेरी pg_stat_activity और उन पिड वैल्यू प्राप्त करें जिन्हें आप मारना चाहते हैं, फिर उन्हें SELECT pg_terminate_backend(pid int)

PostgreSQL 9.2 और ऊपर:

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 9.1 और नीचे:

SELECT pg_terminate_backend(pg_stat_activity.procpid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'TARGET_DB' ← change this to your DB
  AND procpid <> pg_backend_pid();

एक बार जब आप सभी को डिस्कनेक्ट कर लेते हैं तो आपको किसी अन्य डेटाबेस से कनेक्शन से ड्रॉप डाटाबेस कमांड को डिस्कनेक्ट और जारी करना होगा, जिसे आप छोड़ने की कोशिश नहीं कर रहे हैं।

procpid कॉलम का नाम बदलकर नोट करें। यह मेलिंग सूची धागा देखें।


यहाँ मेरा हैक ... = डी

# Make sure no one can connect to this database except you!
sudo -u postgres /usr/pgsql-9.4/bin/psql -c "UPDATE pg_database SET datallowconn=false WHERE datname='<DATABASE_NAME>';"

# Drop all existing connections except for yours!
sudo -u postgres /usr/pgsql-9.4/bin/psql -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '<DATABASE_NAME>' AND pid <> pg_backend_pid();"

# Drop database! =D
sudo -u postgres /usr/pgsql-9.4/bin/psql -c "DROP DATABASE <DATABASE_NAME>;"

मैंने यह जवाब दिया क्योंकि नए कनेक्शन को अवरुद्ध करने के लिए एक कमांड (उपरोक्त) शामिल है और क्योंकि कमांड के साथ कोई प्रयास ...

REVOKE CONNECT ON DATABASE <DATABASE_NAME> FROM PUBLIC, <USERS_ETC>;

... नए कनेक्शन को ब्लॉक करने के लिए काम नहीं करता है!

@araqnid @GoatWalker के लिए धन्यवाद! = D

https://.com/a/3185413/3223785


PostgreSQL 9.2 और ऊपर:

SELECT pg_terminate_backend(pid)FROM pg_stat_activity WHERE datname = 'YOUR_DATABASE_NAME_HERE'





postgresql