Streaming (physical) replication tüm cluster'ı byte byte kopyalar — ya hep ya hiç. Ama bazen tek bir tabloyu (diyelim siparisler) başka bir cluster'a, hatta farklı bir PostgreSQL sürümüne canlı akıtmak istersin: raporlama replica'sı, kademeli sürüm yükseltme, ya da bir servisi ayırma. İşte bu logical replication'ın işi: nesne bazında, mantıksal değişiklikleri (INSERT/UPDATE/DELETE) yayınlar.
İki parça: PUBLICATION ve SUBSCRIPTION
Kaynakta bir yayın (publication) tanımlarsın, hedefte ona bir abonelik (subscription) açarsın. Abonelik açıldığı an önce mevcut veriyi kopyalar, sonra canlı akışa geçer.
Kaynakta — önce wal_level = logical (bu değişiklik restart ister):
-- postgresql.conf: wal_level = logical → restart
SHOW wal_level; -- 'logical' olmalı
CREATE PUBLICATION siparis_pub FOR TABLE siparisler;
Hedefte:
CREATE SUBSCRIPTION siparis_sub
CONNECTION 'host=10.0.0.11 dbname=shop user=repl password=***'
PUBLICATION siparis_pub;
-- Açılır açılmaz: önce initial copy, sonra streaming.
Hedef tabloyu (aynı isim + uyumlu şema) önceden oluşturmuş olman gerekir — logical replication şemayı taşımaz, sadece satırları.
Replica identity: UPDATE/DELETE için şart
INSERT her zaman çalışır. Ama UPDATE ve DELETE'in doğru satırı bulabilmesi için kaynağın satırı benzersiz kimliklemesi gerekir. Tabloda birincil anahtar varsa sorun yok. Yoksa:
-- PK yoksa: tüm satırı kimlik olarak kullan (maliyetli ama çalışır)
ALTER TABLE siparisler REPLICA IDENTITY FULL;
PK'sız bir tabloda bunu ayarlamadan UPDATE/DELETE gelirse abonelik hata verip durur.
Logical replication DDL'i taşımaz. Kaynakta ALTER TABLE siparisler ADD COLUMN ... yaparsan, hedefte aynı değişikliği elle ve doğru sırada (önce hedef, sonra kaynak) yapmazsan akış bozulur. Aynı şekilde sequence değerleri replike edilmez — hedefte nextval senkron değildir, bunu geçiş anında elle ayarla. Sadece satır verisi akar; şema yönetimi sende.
İzleme: nerede, ne kadar geride?
Abonelik tarafında (hedef):
SELECT subname, received_lsn, latest_end_lsn, last_msg_receipt_time
FROM pg_stat_subscription;
Yayın tarafında (kaynak) — replication slot'un ne kadar WAL tuttuğuna bak; tıkanırsa kaynakta disk şişer:
SELECT slot_name, active,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn)) AS geride
FROM pg_replication_slots;
Hızlı karar tablosu
| İhtiyaç | Physical (streaming) | Logical | |---|---|---| | Tüm cluster'ın birebir kopyası (HA/failover) | En iyi | Uygun değil | | Tek tablo / şema seçmek | Hayır | Evet | | Farklı major sürüme akıtmak | Hayır | Evet | | DDL otomatik taşınsın | Evet | Hayır — elle | | Yazılabilir hedef (rapor + yaz) | Hayır (read-only) | Evet |
Özet
Logical replication, "tüm cluster değil, şu tabloyu şuraya" dediğinde doğru araçtır: wal_level=logical, kaynakta PUBLICATION, hedefte SUBSCRIPTION, ve UPDATE/DELETE için mutlaka bir replica identity. En sık ısıran yer DDL ve sequence'lerdir — onları elle, doğru sırada yönetmen gerekir. Kurmadan önce test ortamında bir ALTER TABLE yapıp akışın bozulmadığını (ve nasıl toparladığını) gör; production'da öğrenmek pahalı.