Bir PostgreSQL veritabanı bırakacak bir komut dosyası yazmak gerekiyor. Çok fazla bağlantı olabilir, ancak komut dosyası bunu görmezden gelmelidir.
DROP DATABASE db_name
Açık bağlantılar olduğunda standart sorgu çalışmaz.
Sorunu nasıl çözebilirim?
Bir PostgreSQL veritabanı bırakacak bir komut dosyası yazmak gerekiyor. Çok fazla bağlantı olabilir, ancak komut dosyası bunu görmezden gelmelidir.
DROP DATABASE db_name
Açık bağlantılar olduğunda standart sorgu çalışmaz.
Sorunu nasıl çözebilirim?
Yanıtlar:
Bu sizinki dışında mevcut bağlantıları bırakacaktır:
pg_stat_activity
Öldürmek istediğiniz pid değerlerini sorgulayın ve alın, sonra SELECT pg_terminate_backend(pid int)
onlara verin.
PostgreSQL 9.2 ve üstü:
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 ve altı:
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();
Herkesin bağlantısını kestikten sonra bağlantıyı kesip DROP DATABASE komutunu başka bir veritabanından, yani bırakmaya çalıştığınız bir bağlantıdan çıkarmanız gerekir.
procpid
Sütunun yeniden adlandırılmasını not edin pid
. Bu posta listesi konusuna bakın .
; drop database TARGET_DB;
db'nin işler yeniden denemeye başladığı zaman gittiğinden emin olmak için benim durumumda iyi çalıştı.
dropdb --force
.
PostgreSQL 9.2 ve üzeri sürümlerde, oturumunuz dışındaki her şeyin bağlı olduğunuz veritabanından bağlantısını kesmek için:
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE datname = current_database()
AND pid <> pg_backend_pid();
Eski sürümlerde aynı, sadece bir değişiklik pid
için procpid
. Farklı bir veritabanının current_database()
bağlantısını kesmek için, kullanıcıların bağlantısını kesmek istediğiniz veritabanının adını değiştirin .
Sen isteyebilirsiniz , kullanıcıları ayırmadan önce veritabanının kullanıcılardan hakkı aksi kullanıcılar sadece yeniden bağlanma devam edecektir ve siz DB düşmesi şans asla. Bkz Bu yorumu ve o ilişkilendirilmiş soru veritabanından ben ayırmak nasıl diğer tüm kullanıcılar .REVOKE
CONNECT
Sadece boştaki kullanıcıların bağlantısını kesmek istiyorsanız, bu soruya bakın .
pg_terminate_backend(int)
İşlevi kullanarak veritabanını bırakmadan önce tüm bağlantıları öldürebilirsiniz .
Sistem görünümünü kullanarak tüm çalışan arka uçları alabilirsiniz pg_stat_activity
Tam olarak emin değilim, ancak aşağıdakiler muhtemelen tüm oturumları öldürür:
select pg_terminate_backend(procpid)
from pg_stat_activity
where datname = 'doomed_database'
Tabii ki kendinizi bu veritabanına bağlı olmayabilir
Postgresql sürümünüze bağlı olarak pg_stat_activity
, bırakılan kullanıcılardan etkin bağlantıları atlamayı sağlayan bir hata ile karşılaşabilirsiniz . Bu bağlantılar pgAdminIII içinde de gösterilmez.
Otomatik sınama (kullanıcı da oluşturduğunuz) yapıyorsanız bu olası bir senaryo olabilir.
Bu durumda aşağıdaki gibi sorgulara geri dönmeniz gerekir:
SELECT pg_terminate_backend(procpid)
FROM pg_stat_get_activity(NULL::integer)
WHERE datid=(SELECT oid from pg_database where datname = 'your_database');
NOT: 9.2+ size değişiklik olur procpid
için pid
.
procpid
hiç pid
9.3 bu pasajı eserleri.
Postgres 9.2'nin şimdi procpid yerine sütun pid'i çağırdığını fark ettim.
Kabuktan çağırma eğilimindeyim:
#!/usr/bin/env bash
# kill all connections to the postgres server
if [ -n "$1" ] ; then
where="where pg_stat_activity.datname = '$1'"
echo "killing all connections to database '$1'"
else
echo "killing all connections to database"
fi
cat <<-EOF | psql -U postgres -d postgres
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
${where}
EOF
Umarım faydalıdır. Sql için @JustBob'a teşekkürler.
Linux komut isteminde, önce bu sudo /etc/init.d/postgresql restart komutunu yazarak çalışan tüm postgresql işlemlerini durdururum
diğer postgresql işlemlerinin hala çalışıp çalışmadığını kontrol etmek için bg komutunu yazın
sonra veritabanını bırakmak için dropdb dbname
sudo /etc/init.d/postgresql restart
bg
dropdb dbname
Bu benim için linux komut isteminde çalışıyor
PostgreSQL 9.2 ve üstü:
SELECT pg_terminate_backend(pid)FROM pg_stat_activity WHERE datname = 'YOUR_DATABASE_NAME_HERE'
İşte benim hack ... = D
# 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>;"
Bu cevabı, yeni bağlantıları engellemek için bir komut (yukarıda) içerdiğinden ve komutla yapılan herhangi bir girişimden dolayı ...
REVOKE CONNECT ON DATABASE <DATABASE_NAME> FROM PUBLIC, <USERS_ETC>;
... yeni bağlantıları engellemek için çalışmıyor!
@Araqnid @GoatWalker sayesinde! = D
Yaklaşan PostgreSQL 13 FORCE
seçeneği tanıtılacak .
DROP DATABASE bir veritabanını bırakır ... Ayrıca, hedef veritabanına başka biri bağlıysa , aşağıda açıklanan FORCE seçeneğini kullanmadığınız sürece bu komut başarısız olur .
GÜÇ
Hedef veritabanına var olan tüm bağlantıları sonlandırmayı deneyin. Hedef veritabanında hazırlanmış işlemler, etkin mantıksal çoğaltma yuvaları veya abonelikler mevcutsa sonlandırılmaz.
DROP DATABASE db_name WITH (FORCE);
Benim durumumda, aktif yönetici bağlantım dahil tüm bağlantıları bırakmak için bir komut yürütmek zorunda kaldım
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE datname = current_database()
tüm bağlantıları sonlandırdı ve bana ölümcül bir '' hata '' mesajı gösterdi:
FATAL: terminating connection due to administrator command SQL state: 57P01
Bundan sonra veritabanını bırakmak mümkün oldu
Benim için hiçbir şey işe yaramadı, pgAdmin4 kullanarak oturum açtım ve Gösterge Tablosunda pgAdmin4 dışındaki tüm bağlantıların bağlantısını kestim ve sonra veritabanına ve özelliklere sağa yatarak yeniden adlandırabiliyordum ve yeni bir ad yazabildim.