deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak dev.to (home feed)

PostgreSQL 19 REPACK CONCURRENTLY, şişkinlik temizliğindeki kilit beklemelerini beş saniyeden bir saniyenin altına indiriyor

PostgreSQL 19 beta 4 üzerinde yapılan bir dev.to benchmark'ı, REPACK CONCURRENTLY'nin istemcileri bir saniyenin altında tuttuğunu, VACUUM FULL'un ise neredeyse tüm çalışma süresi boyunca engellediğini gösteriyor; bedeli ise ek WAL ve iş başına bir replication slot.

PostgreSQL 19 REPACK CONCURRENTLY, şişkinlik temizliğindeki kilit beklemelerini beş saniyeden bir saniyenin altına indiriyor

REPACK, şişkinlik konusunda neyi değiştiriyor

PostgreSQL'de satır silmek tablo dosyasını küçültmez. Normal VACUUM, boşalan alanı içeride yeniden kullanılabilir olarak işaretler, ancak işletim sistemi bu byte'ların geri verildiğini hiç görmez. Bir relation'ı fiilen küçültmenin bilinen iki yolu vardı: tablonun tamamını yeniden yazma süresince ACCESS EXCLUSIVE kilidi tutan VACUUM FULL veya çevrimiçi yeniden inşa için üçüncü taraf pg_repack extension'ı. PostgreSQL 19 yerleşik üçüncü bir yol ekliyor: CONCURRENTLY seçeneğiyle tabloyu normal trafik devam ederken yeniden yazan ve exclusive kilidi yalnızca sona yakın kısa bir takas anı için tutan bir REPACK komutu.

Test nasıl yapıldı

dev.to'da yayımlanan, PostgreSQL 19 beta 4 üzerinde koşturulan bir benchmark'a göre yazar, 200 byte'lık metinden oluşan iki milyon satırlık bir tablo oluşturmuş ve çift numaralı satırların tamamını silerek bir milyon satırı kaldırmış. Relation, silmelerden önce ve sonra 531 MB ölçülmüş; basit bir VACUUM'tan sonra bile bu değer değişmemiş. Hem VACUUM FULL hem de REPACK CONCURRENTLY tabloyu 266 MB'a indirmiş. Sonuç aynı; ilginç olan, bu yolda eşzamanlı istemcilerin neler yaşadığı.

Her komut çalışırken, arka planda bir istemci tabloya karşı tek satırlık UPDATE ve SELECT döngüsü koşturmuş ve 250 ms'yi aşan her bekleme engellenmiş sayılmış. Komut başına üç denemede, istemci VACUUM FULL altında toplam 4,35 ila 5,31 saniye engellenmiş — bu komut kilidini yeniden yazma bitene kadar tuttuğu için neredeyse deyimin tamamı. REPACK CONCURRENTLY altında aynı istemci 0,35 ile 0,93 saniye arasında engellenmiş. Deyimlerin kendisi her iki durumda da karşılaştırılabilir 3 ila 6 saniye geçek zaman almış.

Farkın ardındaki mekanizma şu: REPACK CONCURRENTLY tabloyu arka planda kopyalar ve kopya devam ederken orijinale uygulanan her değişikliği yakalamak için logical decoding kullanır; böylece exclusive kilit yalnızca sonda dosyalar takas edilirken ortaya çıkar.

Çekişme ve dürüst sayı

Tek istemci yerine on istemciyle tekrar koşturulduğunda, REPACK CONCURRENTLY altındaki en kötü istemci başına duraksama 0,28 saniye oldu; tek istemcili durumdan neredeyse hiç kötü değil, buna karşılık VACUUM FULL için 5,44 saniye. On istemcinin tamamında toplam engellenme süresi 54,4'e karşı 2,73 saniyeydi. Yazar, toplam rakamın kapasite planına yazılması gereken sayı olduğunu belirtiyor: aynı anda gelen çok sayıda kısa duraksama, tek bir istemcinin bir kez duraklamasından farklı bir üretim olayıdır.

Hızın bedeli

Kilit süresindeki iyileşmenin bedeli WAL ile ödeniyor. Her çalıştırmadan önce pg_stat_wal sıfırlanarak ölçüldüğünde, VACUUM FULL aynı 531'den 266 MB'a dönüş için 655 ila 783 MB WAL yazmış; REPACK CONCURRENTLY ise 816 MB yazmış ve büyük varyasyon göstermemiş; VACUUM FULL çalışmasına bağlı olarak kabaca yüzde 4 ila 25 daha fazla. Ek yük, decoding worker'ının eşzamanlı değişiklikleri yeni kopyaya yeniden oynatmasından geliyor ve bu oynatma herhangi bir yazma gibi WAL'dan geçiyor. Replica'lara WAL aktarımının dar kaynağı olduğu sistemlerde, çevrimiçi seçenek o hatta daha fazla byte itiyor.

Geçici alan ise bu testte anlamlı bir fark göstermedi: tepe veri dizini büyümesi REPACK CONCURRENTLY için 276 MB, VACUUM FULL için 279 MB oldu. Dokümantasyon, kopya sırasında eski tabloya yazılan satırlar için ek bir geçici dosyadan söz ediyor; ancak yazarın yazma yükü — saniyede birkaç bin tek satırlık update — görünür boyuta ulaşacak kadar bu dosyayı doldurmamış olmalı; daha ağır yazma hızları bu tabloyu değiştirebilir.

Slotlar ve görünürlük

Her eşzamanlı repack kendi logical decoding oturumunu çalıştırır ve varsayılanı 5 olan max_repack_replication_slots ile yönetilen boş bir slota ihtiyaç duyar. Ayar 1'e sabitlenip farklı tablolar üzerinde iki repack 150 ms arayla başlatıldığında, ikincisi 5 milisaniye içinde, operatöre slot boşaltmasını ya da ayarı yükseltmesini öneren spesifik bir hatayla başarısız olurken, ilki etkilenmeden tamamlanmış. Bu slotlar max_wal_senders ve max_replication_slots ile aynı kapasiteyi kullandığından, çok sayıda tabloyu paralel repack eden bakım işleri, replication'ın kendisiyle aynı boyutlandırma disiplinine ihtiyaç duyuyor.

PostgreSQL 19 ayrıca mevcut fazı ve heap_blks_scanned ile heap_blks_total gibi sayaçları açıklayan pg_stat_progress_repack adlı bir ilerleme görünümü ekliyor; bu da gerçek bir tamamlanma yüzdesi hesaplamaya, bir sürecin çıkmayı reddetmesini izlemeye kıyasla yetiyor. Yol boyunca yazarın kendi düzeltmesine de değinmek gerek: pg_stat_activity'nin kaba yoklaması başlangıçta sunucu başına aynı anda yalnızca bir repack çalışabileceğini düşündürmüş, ancak doğrulama ikisinin eşzamanlı çalıştığını göstermiş; gerçek sınır slot sayısıymış.

Neden önemli

Şişkinlik temizliği uzun süre tablo genelinde kilitleme ile harici bir araç arasında bir seçim dayatıyordu. İstemci başına kilit duraksamalarının yaklaşık beş saniyeden bir saniyenin çok altına inmesi, bu sayılarla rutin bakım için karar çok daha kolay hale geliyor; yeter ki WAL ek yükü ve slot bütçesi hesaba katılsın. Beta yazılımda yapılan tek yazarlı her benchmark gibi, sonuçlar tek bir tablo biçimini ve orta düzey bir yazma hızını kapsıyor; ancak ilerleme görünümü ve slotlar tükendiğindeki açık, hızlı başarısız olma davranışı, PostgreSQL 19 yükseltmesi planlayan operatörlerin koşullardan bağımsız olarak değerlendirebileceği özellikler.

  • #postgresql
  • #database
  • #performance
  • #postgres-19
  • #database-ops