İki işlem aynı anda MALZEMELİ GÖRÜNÜMÜ İLETİŞİMLE YENİLEMEYE çalışırsa ne olur?


13

Dokümanlara göre:

SONUÇLAR Malzeme görünümünde eşzamanlı seçimleri kilitlemeden materyal görünümünü yenileyin. (...)

... DİĞER İÇERİKLER ...

Bu seçenekle bile, somutlaştırılmış herhangi bir görüşe karşı aynı anda yalnızca bir YENİLEME gerçekleştirilebilir .

Ben vardı gerçekleşen bakış için son yenileme süresi kontrol işlevi ve 60'dan fazla saniye geçmişti eğer, onu yenilemek için olur.

Ancak, aynı anda iki ayrı işlemden gerçekleşen bir görünümü yenilemeye çalışırsam ne olur? sıraya koyacaklar mı yoksa bir hata mı yapacaklar?

MALZEMELİ BİR GÖRÜNÜMün ne zaman yenilendiğini tespit etmenin ve dolayısıyla dokunmaktan kaçınmanın bir yolu var mı?

Şu anda, (ayar yenilemeden önce bir tablo rekor doldurmak için başvurdular refreshingiçin true) ve daha sonra bunu ayarı falseişlemi tamamlandığında.

EXECUTE 'INSERT INTO refresh_status (last_update, refreshing) 
         VALUES (clock_timestamp(), true) RETURNING id') INTO refresh_id;
EXECUTE 'REFRESH MATERIALIZED VIEW CONCURRENTLY my_mat_view';
EXECUTE 'UPDATE refresh_status SET refreshing=false WHERE id=$1' USING refresh_id;

Sonra, bu prosedürü her çağırışımda, en son last_updateve refreshingdeğerini kontrol ederim . Eğer refreshingdoğruysa, o zaman materialized görünümü yenilemek için çalışmayın.

EXECUTE 'SELECT 
           extract(epoch FROM now() - (last_update))::integer, 
           refreshing
         FROM refresh_status
         ORDER BY last_update DESC
         LIMIT 1' INTO update_seconds_ago, refreshing;

IF(updated_seconds_ago > 60 AND refreshing = FALSE) THEN
  -- the refresh block above
END IF;

Ancak, yenileme bayrağının senkronize olarak güncellendiğinden emin değilim (yani, yenilemenin gerçekten tamamlanmasını bekler)

Bu yaklaşım mantıklı mı yoksa burada bir şey mi kaçırıyorum?

Yanıtlar:


13

Bahsedildiği gibi bu cevap , " REFRESH MATERIALIZED VIEW CONCURRENTLYbir sürer EXCLUSIVEmasaya kilidi". Belgelere göre kırıntı izini takip ederek EXCLUSIVE, bir tablodaki bir kilidin "sadece eşzamanlı ACCESS SHAREkilitlere izin verdiğini , yani sadece tablodaki okumaların devam edebileceğini" okuyabiliriz. Aynı paragrafta, " EXCLUSIVE... ile çakışıyor EXCLUSIVE" REFRESH MATERIALIZED VIEW CONCURRENTLYifadesini görebiliriz. Bu, aynı EXCLUSIVEkilidi isteyen başka bir ifadenin, önceki EXCLUSIVEkilit açılana kadar beklemek zorunda kalacağı anlamına gelir .

Bu kilidi tanımsız bir süre beklemekten kaçınmak istiyorsanız, oturum değişkeninilock_timeout makul bir değere ayarlamak isteyebilirsiniz .


Not: MAT VIEW'ın meşgul olduğu ve bu nedenle yenilenmesi gerekse bile yalnız bırakılması gereken bu yardımcı tabloyu eşzamanlı (pun amaçlı değil) anlatmak için herhangi bir anlam ifade ediyor mu?
ffflabs

Bu bir görüş meselesi; eğer yardımcı olduğunu düşünüyorsanız elbette mantığınızı koruyabilirsiniz. Bununla birlikte, işlevinizin yarış koşullarına tabi olduğunu ve bu nedenle% 100 güvenilir olmadığını unutmayın.
mustaccio

Paspas görünümüne atıfta bulunup bulunmadığını görmek için pg_locks'u kontrol etmenin uygun olduğunu düşünüyor musunuz?
ffflabs

Yine, yarış durumu mümkün: pg_locksyenilemenizi kontrol edip başlatmanız arasında bir kilit yerleştirme şansı var . Kilit çakışmalarını gidermenin uygun bir yolu zaman aşımı süresini ayarlamak ve hatayı işlemektir.
mustaccio

3

Bıyık tarafından belirtildiği gibi , bu soru Postgres Yenileme Materyalleştirilmiş Görünüm Kilitleri ile önemli ölçüde örtüşmektedir .

Ancak, bu sorunun kabul edilen cevabının buna cevap veren bir bağlantısı olsa da, bu sorunun cevabı doğrudan bu soruya dahil edilmez.

Yani, açık söylemek gerekirse: Açık kilitleme PostgreSQL kılavuz sayfasına göre (Bağlantı mevcut sürüm sayfasına, PostGres 10 için), REFRESH MATERIALIZED VIEW CONCURRENTLYbir EXCLUSIVEkilit alır . EXCLUSIVEKilit diğer tüm kilitleri engellemek için görünür hariç ACCESS SHARE diğer içerdiğini - EXCLUSIVEkilitler.

Dolayısıyla REFRESH MATERIALIZED VIEW CONCURRENTLYaynı görünümde ikinci bir istek, ilkinin elde ettiği kilidin serbest bırakılmasını bekleyecektir.


Teşekkür ederim. Metnimi soruma daha özel olacak şekilde düzenlediğinden, @ mustaccio'nun cevabını hala kabul edilmiş olarak işaretledim.
ffflabs

0

Moustaccio ve RDFozz'un cevapları sayesinde , sonunda REFRESH ... CONCURRENTLYözel bir kilit almanın PostgreSQL belgelerinin söylediği neden olduğunu anladım :

Bu seçenekle bile, somutlaştırılmış herhangi bir görüşe karşı aynı anda yalnızca bir YENİLEME gerçekleştirilebilir .

Bunun eşzamanlı bir yenileme yapmak için herhangi bir girişimin bir hataya yol açacağından korktum , ancak cevaplarının ışığında, herhangi bir özel hata yok. Sadece eşzamanlı girişimleri körükleyecek bir kilit meselesi. Böylece dokümantasyon bunun yerine şu şekilde yorumlanabilir:

Bu işlem sırasında edinilen kilit, MALZEME GÖRÜNÜMÜNDEN okuma dışında herhangi bir işlemi önleyecektir. Bir YENİLEME ... CONCURRENTLY çalışıyorken Malzeme Görünümü'nü yenileme girişimleri, ilk kilit açılana kadar sıraya girecektir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.