Anladığım kadarıyla, sorgumuzun bir kilit beklemesi, her zaman bir kilit beklediği anlamına geliyor ve hiçbir şey değiştirmedi.
Doğru - pg_stat_activity.waiting'in bir ALTER TABLE için "true" olduğunu görürseniz, neredeyse kesinlikle hedef tablosunda ACCESS EXCLUSIVE kilidini ve gerçek çalışmasını sabırla beklediği anlamına gelir (gerekirse tabloyu yeniden yazma, katalogları değiştirme , yeniden oluşturma dizinleri vb.) henüz başlamadı.
ALTER TABLE sorguyu açıkça iptal etmemiz güvenli midir? Veya sorgunun zaten bir şeyi değiştirmiş olması ve onu iptal etmesi veritabanımızı bir tür yarı yolda bırakabilir mi?
PostgreSQL'de sorguları iptal etmek (veya aynı şekilde bir işlemi geri almak), diğer bazı veritabanlarında (örneğin bu sayfanın altındaki korkunç uyarı) ürkmüş olabileceğiniz herhangi bir veritabanı bozulması tehlikesine sahip değildir . Bu nedenle süper kullanıcı olmayanlar, son sürümlerde, diğer arka uçlarda çalışan kendi sorgularını kullanmakta pg_cancel_backend()
ve pg_terminate_backend()
öldürmekte serbesttirler - veritabanı bozulması hakkında endişelenmeden kullanmak güvenlidir. Sonuçta, PostgreSQL en neyi Yani vb OOM katil, sunucu kapatma, örn SIGKILL kapalı öldürülme herhangi süreci ile başa çıkmak için hazır olmak zorunda WAL günlüğü içindir.
PostgreSQL'de, bir (çoklu ifade) işleminin içine yerleştirilmiş DDL komutlarının çoğunu gerçekleştirmenin de mümkün olduğunu görmüş olabilirsiniz, ör.
BEGIN;
ALTER TABLE foo ...;
ALTER TABLE bar ...;
-- more stuff
COMMIT; -- or ROLLBACK; if you've changed your mind
(şema geçişlerinin ya hep birlikte ya da hiç gitmediğinden emin olmak için harika.)
Biz did not sarın ALTER TABLE
bir işlemdeki.
Tek bir komut için bu iyi - dokümanlardan ,
PostgreSQL aslında her SQL deyimini bir işlem içinde yürütülüyor olarak ele alır. Bir BEGIN komutu vermezseniz, her bir ifadenin üstü kapalı bir BEGIN vardır ve (başarılıysa) COMMIT'in etrafına sarılır. BEGIN ve COMMIT ile çevrili bir ifade grubuna bazen işlem bloğu denir.
Dolayısıyla , kontrol eden psql isteminden verilen bir Ctrl-C'nin iptal edilmesi ALTER TABLE
, pg_cancel_backend()
yaptığınız gibi benzer bir etkiye sahip olacaktır.
BEGIN;
ALTER TABLE ... ;
ROLLBACK;
(umarım görebileceğiniz gibi, pahalı ALTER TABLE
olanı iptal etmek , veritabanını ROLLBACK
zaten gereksiz yere taşıyorsanız çok fazla gereksiz öğütmeden kurtarabilir .)