- PostgreSQL 18, dosya kopyalama stratejisi (FILE_COPY) ile dosya sistemi klonlama özelliğini birleştirerek veritabanlarını neredeyse anında klonlayabiliyor
- Yeni
file_copy_method = clone ayarı kullanıldığında XFS, ZFS, APFS gibi modern dosya sistemlerinin klonlama özelliğinden (FICLONE) yararlanılabiliyor
- Benchmark sonuçlarına göre 6GB'lık bir veritabanını klonlarken mevcut WAL_LOG yöntemi yaklaşık 67 saniye, klon yöntemi ise 0,2 saniye sürüyor
- Klonlanan veritabanları başlangıçta aynı fiziksel blokları paylaşsa da, yazma işlemi olduğunda copy-on-write ile ayrılıyor
- Ancak yalnızca etkin bağlantı yokken klonlama yapılabiliyor ve sadece tek bir dosya sistemi içinde çalışıyor
PostgreSQL'in şablon tabanlı klonlama yapısı
- PostgreSQL,
CREATE DATABASE dbname komutunu çalıştırdığında dahili olarak template1 veritabanını klonlayarak yeni veritabanını oluşturur
- Bu,
CREATE DATABASE dbname TEMPLATE template1 ile aynı davranıştır
template1 yerine başka bir veritabanı belirtilebildiği için kullanıcı tanımlı şablonlar ile klonlama yapılabilir
- PostgreSQL 18'de bu şablon sistemi anında klonlamayı mümkün kılan bir yapıya genişletildi
CREATE DATABASE ... STRATEGY
- PostgreSQL 15'ten itibaren
CREATE DATABASE ... STRATEGY parametresi eklendi ve klonlama yönteminin seçilmesi mümkün oldu
- Varsayılan değer
WAL_LOG olup Write-Ahead Log üzerinden blok düzeyinde kopyalama yapar
- Bu yöntem I/O yükünü azaltır ve eşzamanlılık desteğini iyileştirir, ancak büyük veritabanlarında yavaştır
STRATEGY=FILE_COPY belirtildiğinde geleneksel dosya kopyalama yöntemine dönülebilir; PostgreSQL 18'de bunun üzerine yeni bir klonlama seçeneği eklendi
FILE_COPY ve file_copy_method
- PostgreSQL 18'deki
file_copy_method ayarı, işletim sistemi düzeyindeki dosya kopyalama yöntemini kontrol eder
- Varsayılan değer
copy'dir; tüm baytları okuyup yeni konuma yazar
clone olarak değiştirildiğinde dosya sisteminin klonlama özelliği (FICLONE) kullanılır; böylece anlık klonlama yapılır ve ek alan tüketilmez
- Desteklenen dosya sistemleri: XFS, ZFS, APFS, FreeBSD ZFS
- Kurulum adımları
- PostgreSQL kümesini ilgili dosya sistemi üzerinde kurun
file_copy_method = clone ayarını yapıp yeniden yükleyin
Benchmark sonuçları
- Yaklaşık 6GB boyutunda bir test veritabanı (
source_db) oluşturulduktan sonra iki yöntem karşılaştırıldı
WAL_LOG yöntemi: 67.000ms (yaklaşık 67 saniye)
FILE_COPY + clone yöntemi: 212ms
- Aynı veri boyutunda 300 kattan fazla hız artışı görüldü
- Klonlanan veritabanı (
fast_clone) neredeyse hiç ek disk alanı kullanmıyor
Klonlanan verinin çalışma mantığı
file_copy_method = clone kullanıldığında yalnızca dosya sistemi metadata'sı kopyalanır ve iki veritabanı aynı fiziksel blokları paylaşır
- PostgreSQL'in raporladığı veritabanı boyutu mantıksal boyut olarak aynı kalır (yaklaşık 6GB)
- Yazma işlemi olduğunda copy-on-write (COW) devreye girer ve ilgili sayfa ayrılır
- Değiştirilen satırı içeren sayfa
- Yeni tuple'ın yazıldığı sayfa
- İndeks sayfaları ile FSM, visibility map sayfaları gibi diğer sayfalar
VACUUM çalıştırıldığında da ek sayfa ayrışmaları olur
XFS üzerinde paylaşılan blokların doğrulanması
filefrag -v komutuyla iki veritabanının fiziksel blokları paylaşıp paylaşmadığı doğrulanabilir
- Başlangıç durumunda tüm extent'ler
shared olarak görünür
- Bazı satırlar güncellendiğinde ilk 40 blok (yaklaşık 160KB) ayrılır ve farklı fiziksel adreslere taşınır
- Kalan extent'ler ise paylaşılmaya devam eder
Dikkat edilmesi gerekenler ve kısıtlar
- Klonlama sırasında kaynak veritabanında etkin bağlantı olmamalıdır
- Bu, dosya sisteminden değil PostgreSQL'in kendi kısıtından kaynaklanır
- Gerçek üretim ortamlarında genellikle ayrı bir şablon veritabanı kullanılır
- Yalnızca tek bir dosya sistemi içinde klonlama yapılabilir
- Birden fazla tablespace farklı bağlama noktalarındaysa normal kopyalamaya geri dönülür
- Bulut yönetimli servislerde (AWS RDS, Google Cloud SQL vb.) dosya sistemine erişim olmadığı için bu özellik kullanılamaz
- Kendi VM veya bare metal ortamınızda ise tam kontrol mümkündür
Sonuç
- PostgreSQL 18'deki
file_copy_method = clone özelliği, işletim sistemi düzeyindeki klonlama yeteneğini doğrudan kullanarak
büyük veritabanlarının klonlama süresini dramatik biçimde kısaltır
- Test, geliştirme ve öğrenme ortamlarında anında klonlanabilen ve sıfırlanabilen veritabanı iş akışları kurulabilir
- Ancak işletim tasarımında etkin bağlantı kısıtı ve tek dosya sistemi şartı dikkate alınmalıdır
1 yorum
Hacker News yorumları
Bekleyemeyen ya da PG18'in tam örnek yalıtımına ihtiyaç duyanlar için, ZFS snapshot kullanarak anında dallanma yapan Velo adlı bir araç yaptım
Herhangi bir PostgreSQL sürümünde çalışıyor ve her dalın bağımsız bir container'ı ve portu var
100GB'lık bir DB için yaklaşık 2~5 saniyede oluşturulabiliyor
PG18 yaklaşımından farkı, tek bir örneği paylaşmaması ve tam sunucu yalıtımı sağlaması
GitHub bağlantısı
Geçmişte şirket RDS'e migration yaparken buna benzer bir sistemi kendimiz kurmuştuk
Production migration sırasında sık sık sorun çıktığı için, bunu önlemek amacıyla şu adımları otomatikleştirmiştik
Bu süreç sayesinde local'de ya da CI'da yakalanmayan pek çok production'a özgü bug yakalayabildik
Sonrasında bunu basit bir Ruby script ile otomatikleştirdik ve duyduğuma göre o script hâlâ kullanılıyormuş
Template cloning stratejisinin yapılandırılabilir olduğunu bunu okuyunca ilk kez öğrendim
Ben Neon ile gerçek zamanlı entegre ortamlar kurdum ve Golang projem pgtestdb içinde her test için tam schema migration uygulanmış bir Postgres DB oluşturuyorum
Daha önce bir startup'ta btrfs ile anında staging DB oluşturulduğunu görmüştüm; benzer fikirlerin tekrar tekrar ortaya çıkması ilginç
Bu tür hızlı kopyalama ve test yetenekleri Postgres ve Sqlite'ın büyük avantajlarından biri; keşke Clickhouse ve MySQL'de de mümkün olsa
Son zamanlarda PostgreSQL neredeyse tüm SQL kullanım alanlarını kapsayan genel amaçlı bir DB hâline gelmiş gibi görünüyor
Üstelik ücretsiz
Artık başka bir SQL DB kullanmak için gerçekten bir neden kalıp kalmadığını merak ediyorum
Clickhouse analitik için çok daha hızlı, Cassandra gibi DB'ler ise write-ağırlıklı workload'larda avantajlı
Yani her DB'nin hâlâ kendine özgü güçlü yanları var
Veri büyüdükçe performans düşüşü ya da migration sorunları ortaya çıkıyor
Benim durumumda yerleşik partitioning performansı yetersizdi, bu yüzden özel partition yapısını kendim uygulamak zorunda kaldım
Bu tercih, yük arttığında çeşitli olumsuz etkilere yol açıyor
Uber'in blog yazısında da bu konu ele alınmıştı
Buna rağmen cloud ortamında en çok Postgres'e güveniyorum
Bu yüzden büyük ölçekli OLTP deployment'larda MySQL hâlâ daha yaygın kullanılıyor (ör. YouTube, Uber)
Değişmez veri yapıları (HAMT) kullanılırsa dosya sistemi türünden bağımsız olarak anında klonlanabilen bir DB yapılabilir
Bunu teori olarak söylemiyorum; gerçekten uyguladım
Neden daha fazla HAMT tabanlı DB olmadığını anlayamıyorum
İlgili doküman bağlantısı
Postgres v15'te WAL_LOG'un varsayılan hâle geldiğini bilmiyordum
Paralel CI test ortamlarında FILE_COPY stratejisine geri dönmek daha mantıklı
Eski projem integresql için bununla ilgili bir issue açmıştım
Local'de Postgres tabanlı uygulamaları test etmek için basit bir GUI aracı pgtt yapmıştım
Geliştirme ortamı kurulumunu ciddi biçimde basitleştiriyor
SQL migration tekrarlarında işe yarayabilir gibi görünüyor
Blogdaki diğer yazıları da okudum; genel olarak çok iyiler
Özellikle Postgres'in range type özelliğini ilk kez öğrendim
MariaDB'de de buna benzer bir özellik olup olmadığını merak ediyorum
Her testte DB'yi başlangıç durumuna döndürmek yavaş olduğu için uğraşıyorum
Production'da MariaDB kullandığımız için DB değiştirmek zor
Yine de Postgres tarafı daha iyi görünüyor
Bu yöntem oldukça verimli
AWS de benzer bir özellik sunuyor
Aurora clone dokümanı
Entegrasyon testleri için gerçekçi değil