ฉันต้องการลบฐานข้อมูลออกจากคลัสเตอร์ PostgreSQL DB ฉันจะทำอย่างไรแม้ว่าจะมีการเชื่อมต่อที่ใช้งานอยู่? ฉันต้องการเรียงลำดับของ-force
ธงที่จะลดการเชื่อมต่อทั้งหมดแล้ว DB
ฉันจะใช้มันได้อย่างไร
ฉันกำลังใช้งานdropdb
อยู่ แต่เครื่องมืออื่นเป็นไปได้
ฉันต้องการลบฐานข้อมูลออกจากคลัสเตอร์ PostgreSQL DB ฉันจะทำอย่างไรแม้ว่าจะมีการเชื่อมต่อที่ใช้งานอยู่? ฉันต้องการเรียงลำดับของ-force
ธงที่จะลดการเชื่อมต่อทั้งหมดแล้ว DB
ฉันจะใช้มันได้อย่างไร
ฉันกำลังใช้งานdropdb
อยู่ แต่เครื่องมืออื่นเป็นไปได้
คำตอบ:
ใน PostgreSQL *คุณไม่สามารถวางฐานข้อมูลในขณะที่ลูกค้าเชื่อมต่อกับมัน
อย่างน้อยไม่ได้มีdropdb
ยูทิลิตี้ - ซึ่งเป็นเพียง wrapper ง่าย ๆ รอบDROP DATABASE
แบบสอบถามเซิร์ฟเวอร์
วิธีแก้ปัญหาที่แข็งแกร่งค่อนข้างดังต่อไปนี้:
เชื่อมต่อกับเซิร์ฟเวอร์ของคุณเป็นsuperuserใช้psql
หรือไคลเอนต์อื่น ๆ ไม่ได้ใช้ฐานข้อมูลที่คุณต้องการที่จะลดลง
psql -h localhost postgres postgres
ตอนนี้ใช้ไคลเอนต์ฐานข้อมูลธรรมดาคุณสามารถบังคับให้ปล่อยฐานข้อมูลโดยใช้สามขั้นตอนง่าย ๆ :
ตรวจสอบให้แน่ใจว่าไม่มีใครสามารถเชื่อมต่อกับฐานข้อมูลนี้ คุณสามารถใช้หนึ่งในวิธีต่อไปนี้ (วิธีที่สองดูปลอดภัยกว่า แต่ไม่ได้ป้องกันการเชื่อมต่อจากผู้ใช้ระดับสูง)
/* 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; */
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'; */
ปล่อยฐานข้อมูล
DROP DATABASE mydb;
ขั้นตอนที่ 1 ต้องการสิทธิ์ superuserสำหรับวิธีที่ 1 และสิทธิ์ของเจ้าของฐานข้อมูลสำหรับวิธีที่ 2 ขั้นตอนที่ 2 ต้องใช้สิทธิ์superuser ขั้นตอนที่ 3 ต้องใช้สิทธิ์ของเจ้าของฐานข้อมูล
* สิ่งนี้ใช้กับ PostgreSQL ทุกเวอร์ชันจนถึงเวอร์ชัน 11
มีเป็นวิธีการที่จะทำเช่นนี้กับสาธารณูปโภคเปลือกdropdb
และpg_ctl
(หรือpg_ctlcluster
ใน Debian และสารอนุพันธ์) แต่วิธีการของ @ filipremนั้นเหนือกว่าด้วยเหตุผลหลายประการ:
dropdb
คำสั่งเสียฉันพูดman pg_ctlcluster
:
ด้วย
--force
ตัวเลือกโหมด "เร็ว" จะใช้ซึ่งย้อนกลับธุรกรรมที่ใช้งานอยู่ทั้งหมดให้ยกเลิกการเชื่อมต่อไคลเอ็นต์ทันทีและปิดเครื่องอย่างหมดจด หากไม่ได้ผลระบบจะพยายามปิดระบบอีกครั้งในโหมด "ทันที" ซึ่งอาจทำให้คลัสเตอร์อยู่ในสถานะไม่สอดคล้องกันและจะทำให้การกู้คืนทำงานในการเริ่มต้นครั้งถัดไป หากสิ่งนี้ยังไม่ช่วยกระบวนการ postmaster จะถูกฆ่า ออกด้วย 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
อาจเป็นสคริปต์สำหรับการทดแทนอย่างฉับพลัน
ใช้คำตอบของ @ 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
หากคุณอยู่ในประเภท RDS ที่การเชื่อมต่อที่ไม่มีฐานข้อมูลถูกเลือกจะนำคุณไปสู่ฐานข้อมูลที่คุณขอให้สร้างขึ้นโดยค่าเริ่มต้นคุณสามารถทำสิ่งนี้ได้เพื่อให้คุณได้รับการเชื่อมต่อล่าสุดที่เปิดอยู่
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;