बल ड्रॉप डीबी जबकि अन्य जुड़े हो सकते हैं


103

मुझे PostgreSQL DB क्लस्टर से एक डेटाबेस को हटाने की आवश्यकता है। सक्रिय कनेक्शन होने पर भी मैं इसे कैसे कर सकता हूं? मुझे एक -forceध्वज की आवश्यकता है , जो सभी कनेक्शनों को छोड़ देगा और फिर डीबी।

मैं इसे कैसे लागू कर सकता हूं?

मैं dropdbवर्तमान में उपयोग कर रहा हूं , लेकिन अन्य उपकरण संभव हैं।

जवाबों:


154

PostgreSQL * में , आप एक डेटाबेस को नहीं छोड़ सकते जबकि ग्राहक इससे जुड़े हैं।

कम से कम, dropdbउपयोगिता के साथ नहीं - जो कि DROP DATABASEसर्वर क्वेरी के आसपास केवल एक साधारण आवरण है ।

काफी मजबूत समाधान इस प्रकार है:

सुपर सर्वर के रूप में , psqlया अन्य क्लाइंट का उपयोग करके अपने सर्वर से कनेक्ट करें । करो नहीं डेटाबेस आप ड्रॉप करना चाहते हैं का उपयोग करें।

psql -h localhost postgres postgres

अब सादे डेटाबेस क्लाइंट का उपयोग करके आप तीन आसान चरणों का उपयोग करके डेटाबेस को छोड़ सकते हैं:

  1. सुनिश्चित करें कि कोई भी इस डेटाबेस से जुड़ नहीं सकता है। आप निम्न विधियों में से एक का उपयोग कर सकते हैं (दूसरा अधिक सुरक्षित लगता है, लेकिन सुपरसर्स से कनेक्शन को नहीं रोकता है)।

    /* Method 1: update system catalog */
    UPDATE pg_database SET datallowconn = 'false' WHERE datname = 'mydb';
    
    /* Method 2: use ALTER DATABASE. Superusers still can connect!
    ALTER DATABASE mydb CONNECTION LIMIT 0; */
  2. इस डेटाबेस से जुड़े सभी क्लाइंट के फोर्स डिस्कनेक्ट का उपयोग करके pg_terminate_backend

    SELECT pg_terminate_backend(pid)
    FROM pg_stat_activity
    WHERE datname = 'mydb';
    
    /* For old versions of PostgreSQL (up to 9.1), change pid to procpid:
    
    SELECT pg_terminate_backend(procpid)
    FROM pg_stat_activity
    WHERE datname = 'mydb'; */
  3. डेटाबेस ड्रॉप करें।

    DROP DATABASE mydb;

चरण 1 के लिए 1 विधि के लिए सुपरसुसर विशेषाधिकारों की आवश्यकता है , और दूसरे के लिए डेटाबेस के मालिक के विशेषाधिकार। चरण 2 में सुपरसुसर विशेषाधिकारों की आवश्यकता होती है । चरण 3 के लिए डेटाबेस स्वामी विशेषाधिकार की आवश्यकता होती है ।


* यह PostgreSQL के सभी संस्करणों पर लागू होता है, संस्करण 11 तक।



इसलिए मुझे नहीं पता कि मैंने क्या गलत किया, लेकिन अब मैं उस डेटाबेस से भी नहीं जुड़ सकता जिसे मैंने लक्षित किया था! न ही मैं इसे छोड़ सकता हूं क्योंकि यह कहता है कि "रखरखाव डेटाबेस को गिराया नहीं जा सकता है"
मैट स्किल्डन

@MattSkeldon, इस संदेश का कोई मतलब नहीं पता है। वेनिला PostgreSQL में आप टेम्पलेट 0 और टेम्पलेट 1 को छोड़कर किसी भी डेटाबेस को छोड़ सकते हैं। शायद आप कुछ गैर-मुक्त / वाणिज्यिक संस्करण का उपयोग करें? शायद यह ग्राहक समस्या है सर्वर समस्या नहीं? आपने psql की कोशिश की?
filiprem

दुर्भाग्य से मैं एक एसक्यूएल पृष्ठभूमि से आता हूं, पीजीएसक्यूएल का उपयोग गैर वाणिज्यिक / मुक्त स्थिति के कारण किया जा रहा है।
मैट स्किल्डन

यह मेरे लिए काम नहीं करता जहां लंबे समय तक चलने वाले ज़ोंबी सत्र हैं। pg_terminate_backend () उन सत्रों को नहीं मारता है, इसलिए मैं अभी भी कुछ करने के बारे में थोड़ा अटक गया हूं: मैं एक पोस्टग्रेज सु हूं, लेकिन मेरे पास उस सर्वर तक पहुंच नहीं है जो यह चल रहा है।
अलेक्जेंडर

6

वहाँ है खोल उपयोगिताओं के साथ यह करने के लिए एक तरह से dropdbऔर pg_ctl(या pg_ctlclusterडेबियन और derivates में)। लेकिन @ filiprem का तरीका कई कारणों से बेहतर है:

  • यह केवल प्रश्न में डेटाबेस से उपयोगकर्ताओं को डिस्कनेक्ट करता है।
  • इसे पूरे क्लस्टर को पुनरारंभ करने की आवश्यकता नहीं है।
  • यह तत्काल पुनर्निर्माण को रोकता है, संभवतः dropdbकमांड को खराब कर रहा है ।

मैं बोली man pg_ctlcluster:

साथ --forceविकल्प "तेज" मोड प्रयोग किया जाता है जो वापस रोल सभी सक्रिय लेनदेन, ग्राहकों तुरंत डिस्कनेक्ट और इस तरह सफाई से बंद हो जाता है। यदि वह काम नहीं करता है, तो शटडाउन को "तत्काल" मोड में फिर से करने का प्रयास किया जाता है, जो क्लस्टर को असंगत स्थिति में छोड़ सकता है और इस तरह अगली शुरुआत में एक रिकवरी रन होगा। यदि यह अभी भी मदद नहीं करता है, तो पोस्टमास्टर प्रक्रिया को मार दिया जाता है। सफलता के साथ 0 पर बाहर निकलता है, 2 के साथ यदि सर्वर नहीं चल रहा है, और 1 अन्य विफलता की स्थिति के साथ। इस मोड का उपयोग केवल तब किया जाना चाहिए जब मशीन बंद होने वाली हो।

pg_ctlcluster 9.1 main restart --force

या

pg_ctl restart -D datadir -m fast

या

pg_ctl restart -D datadir -m immediate

तुरंत बाद:

dropdb mydb

संभवतः तत्काल उत्तराधिकार के लिए एक स्क्रिप्ट में।


4
न केवल यह आदर्श से कम है क्योंकि यह पूर्ण पोस्टग्रेज उदाहरण को मारता है, लेकिन यह काम करने की गारंटी नहीं है। क्लाइंट द्वारा सर्वर को पुनरारंभ करने और ड्रॉपडाउन को फिर से चलाने के प्रयास के बीच कनेक्ट करना संभव है। @filiprem का उत्तर डेटाबेस से सभी कनेक्शनों को डिस्कनेक्ट करने से पहले निष्क्रिय कर देता है और अन्य डेटाबेस को ऊपर रखेगा।
जिम मिचनर

6

मेरे मामले में @ filiprem के उत्तर का उपयोग करना और इसे सरल बनाना:

-- Connecting to the current user localhost's postgres instance
psql

-- Making sure the database exists
SELECT * from pg_database where datname = 'my_database_name'

-- Disallow new connections
UPDATE pg_database SET datallowconn = 'false' WHERE datname = 'my_database_name';
ALTER DATABASE my_database_name CONNECTION LIMIT 1;

-- Terminate existing connections
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'my_database_name';

-- Drop database
DROP DATABASE my_database_name

0

यदि आप RDS जैसी किसी चीज़ पर हैं, जहाँ बिना चुने गए डेटाबेस के कनेक्शन आपको उस DB में डाल देते हैं, जिसे आपने डिफ़ॉल्ट रूप से बनाने के लिए कहा है, तो आप इस संस्करण को अपने आप को अंतिम खुले कनेक्शन के रूप में प्राप्त करने के लिए कर सकते हैं।

 DROP DATABASE IF EXISTS temporary_db_that_shouldnt_exist; 

 CREATE DATABASE temporary_db_that_shouldnt_exist with OWNER your_user; 

 \connect temporary_db_that_shouldnt_exist 
 SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'the_db_you_want_removed'; 


 DROP DATABASE IF EXISTS the_db_you_want_removed; 
 -- 
 -- Name: the_db_you_want_removed; Type: DATABASE; Schema: -; Owner: your_user 
 -- 

 CREATE DATABASE savings_champion WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8'; 


 ALTER DATABASE the_db_you_want_removed OWNER TO your_user; 

 \connect the_db_you_want_removed 

 DROP DATABASE IF EXISTS temporary_db_that_shouldnt_exist;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.