Bu yazımda,Centos 7 üzerine Postgresql 12 streaming replikasyon kurulumunu anlataya çalışacağım. Bu kısma devam etmeden önce eğer okumadıysanız repliksayon ile ilgili yazdığım yazıyı okumanızı tavsiye ederim.
Hostname
IP
Açıklama
primary
192.168.10.105
Primary Cluster
standby
192.168.10.106
Standby Cluster
Primary Sunucu İşlemleri
Öncelikle primary sunucu üzerine clustarımızı kuralım.
Standby üzerinden primary sunucuya bağlanmak için REPLICATION rolüne sahip kullanıcı oluşturulur.
CREATE ROLE replicationuser WITH LOGIN PASSWORD '112233ee' REPLICATION;
--\du komutu ile kullanıcıları görebiliriz
Oluşturduğumuz replica_user kullanıcısının erişimi için pg_hba.conf dosyasını düzenlememiz gerekiyor. pg_hba.conf dosyasında yapılan bir değişikliğin etkin olabilmesi için Postgres sunucusu reload işlemine ihtiyaç duyar.
echo "host replication replicationuser 192.168.10.106/32 md5">>/var/lib/pgsql/12/data/pg_hba.conf
--Aşağıdaki komutlardan birini kullanarak reload işlemini yaparız;
SELECT pg_reload_conf();
pg_ctl reload
systemctl reload postgresql-12
PostgreSQL varsayılan olarak localhost adresini dinler. Dışardan gelen talepleri dinleyecek IP adresini yazabileceğimiz gibi * işaretini koyarak sunucudaki tüm ip adreslerini dinlemesinide sağlayabiliriz. Ayrıca değiştirmek istersek varsayılan olarak gelen 5432 portunu düzenlemeliyiz, ben portu değiştirmeden devam ediyorum.
listen_addresses = '*'
port = 5432
postgresql.conf dosyasında yer alan wal_level, max_wal_senders, max_replication_slots parametrelerinin değerleri postgresql-10 sürümünden itibaren varsayılan olarak replikasyon işlemi için ayarlanmış olarak gelir;
wal_level : wal_level parametresi ile WAL’a ne kadar bilgi yazılacağını belirler. Varsayılan değer, yedek bir sunucuda salt okunur sorguların çalıştırılması dahil, WAL arşivlemeyi ve çoğaltmayı desteklemek için yeterli veriyi yazan replica’dır. minimal, bir çökme veya anında kapanma durumundan kurtarmak için gereken bilgiler dışındaki tüm log kaydını kaldırır. logical, logical decoding için gerekli bilgileri ekler.
max_wal_senders : Eş zamanlı olan replikasyon bağlantısı sayısını belirtir. Bu sayı en az slave sunucu sayısı +1 olmalıdır. Varsayılan 10’dur. 0 değeri, replikasyonun devre dışı bırakıldığı anlamına gelir. Standby sunucu çalıştırırken, bu parametreyi primary sunucudakiyle aynı veya daha yüksek bir değere ayarlamalısınız. Aksi takdirde, standby sunucusunda sorgulara izin verilmeyecektir.
max_replication_slots : Sunucunun destekleyebileceği maksimum replikasyon slot sayısını Varsayılan 10’dur. Mevcut slot sayısından daha düşük bir değere ayarlamak, sunucunun başlamasını engeller.
Bu parametrelerin dışında primary sunucuda replikasyon ile ilgili aşağıdaki paramtreleride düzenleyebiliriz, özellikle varsayılan olarak gelen asenkron replikasyonu değiştimek istersek synchronous_standby_names parametresini düzenlemeliyiz; (devamı..)
Günümüz dünyasında veri kritik bir emtiadır ve bu nedenle verileri tek bir yerde saklamak risklidir, bu nedenle bir arızadan mümkün olan en kısa sürede kurtulmanızı sağlamak için bir stratejiniz ve bir planınız olması gerekir.
Replikasyon, yüksek kullanılabilirlik (HA- High Availability) ve etkili felaket kurtarma (DR – Disaster Recovery) stratejisi sağlamayı amaçlayan herhangi bir veritabanı sisteminin kritik bir parçasıdır. HA ve DR’ın yanında replikasyon performans, yedeklilik, veri aktarımı ve test sistemlerinin kurulumu içinde kullanılabilir.
Replikasyon terimi, bir veya daha fazla yazılım veya donanım sistemi arasında bilgi paylaşımı sürecini tanımlamak için kullanılır; güvenilirlik, kullanılabilirlik ve hata toleransı sağlamak için. Bu sistemler aynı veri merkezinde olabileceği gibi, tek bir makinede olabilir veya farklı veri merkezinde olup ağ üzerinden bağlanabilir. Replikasyon, genel olarak Donanım ve Yazılım kategorilerine ayrılabilir, bu kategorileri kısaca inceleyeceğiz, ancak ana odak noktası veritabanı replikasyonudur. Önce kısaca veritabanı replikasyonu tanımını yapmak istiyorum; Veritabanı replikasyonu, verilerin veritabanı instance’ından bir veya daha fazla veritabanı instance’ına kopyalanması sürecini açıklar.
Donanım Tabanlı Replikasyon
Donanım tabanlı replikasyon, birden çok bağlı sistemi senkronize tutar. Bu veri senkronizasyonu, sistemde bir I/O gerçekleştirilir gerçekleştirilmez depolama düzeyinde yapılır, yapılandırılmış depolama modüllerine/cihazlarına/sistemlerine yayılır. Bu tür bir replikasyon, depolama alanının tamamı veya seçilen partition için yapılabilir. Bu tür bir çözümün en büyük avantajı, (genellikle) kurulumunun kolay olması ve yazılımdan bağımsız olmasıdır. Bu, çok daha iyi performans göstermesini sağlar, ancak replikasyon üzerindeki esnekliği ve kontrolü azaltır. Bu tür çoğaltmanın artıları;
Gerçek zamanlı : Tüm değişiklikler sonraki sistemlere hemen uygulanır.
Kurulumu Kolay : Hiçbir komut dosyası veya yazılım yapılandırması gerekmez.
Uygulamadan Bağımsız : Replikasyon, depolama katmanında gerçekleşir ve işletim sistemi/yazılım uygulamasından bağımsızdır.
Veri Bütünlüğü ve Tutarlılığı : Mirror işlemi, depolama diskinin tam bir kopyasını depolama katmanında gerçekleştiğinden, veri bütünlüğü ve tutarlılığı otomatik olarak sağlanır.
Donanım tabanlı replikasyonun bazı avantajları olmasına rağmen, yine de kendi sınırlamaları ile birlikte gelir. Genellikle donanım üreticisi firma bağımlılığına dayanır, yani aynı tip donanım kullanılmalıdır ve buda çoğu zaman çok uygun maliyetli olamıyor.
Yazılım Tabanlı Replikasyon
Bu replikasyon tipi genel çözümlerden ürüne özgü çözümlere kadar değişebilir. Genel çözümler, verileri yazılım düzeyinde farklı sistemler arasında kopyalayarak donanım çoğaltmasını taklit etme eğilimindedir. Replikasyonun gerçekleştirilmesinden sorumlu olan yazılım, yazılan her biti kaynak depolamaya kopyalar ve hedef sistemlere yayar. Oysa ürüne özgü çözümler, ürün gereksinimlerine daha duyarlıdır ve genellikle belirli bir ürün içindir. Yazılım tabanlı çoğaltmanın artıları ve eksileri vardır. Bir yandan, replikasyonun nasıl yapıldığına ilişkin esneklik ve kontrol sağlar ve genellikle donanım tabanlı repliksayona göre düşük maliyetlidir ve çok daha iyi bir dizi özellik sağlar. Ancak öte yandan, çok fazla konfigürasyon gerektirir ve sürekli izleme ve bakım gerektirir.
Veritabanı Replikasyonu
Şimdi asıl konumuz olan veritabanına replikasyonuna girmeden önce veritabanı dünyasındaki bir replikasyon sisteminin farklı bileşenlerini tanımlamak için kullanılan terminolojilerden bahsedelim; Primary-Standby, Master-Slave, Publisher-Subscriber, Master-Master/Multimaster replikasyon kurulumuna katılan veritabanı sunucularını tanımlamak için en sık kullanılan terimlerdir. Primary, Master ve Publisher terimleri kendisi tarafından alınan değişiklikleri diğer düğümlere yaymaya çalışan aktif düğümü tanımlamak için kullanılır. Standby, Slave ve Subscriber terimleri aktif düğümlerden yayılan değişiklikleri alacak pasif düğümleri tanımlamak için kullanılır. Ben aktif düğümü tanımlamak için Primary ve pasif düğüm için Standby terimlerini kullanacağım.
Veritabanı Replikasyonun nasıl çalıştığı hakkında anlamamız gereken bazı temel noktalar vardır;
Postgres, primary sunucu arızalandığında otomatik olarak yük devretme işlevi sağlamaz. Yük devretmeyi yönetmek için 3. parti araç kullanmadığınız sürece bu manuel bir işlemdir.
Standby ile yük denegeleme(load balancing) otomatik değildir. Yük dengeleme, uygulamanız için bir gereksinimse, read-write işlemleri için primary sunucuyu ve read only işlemler için standby sunucuyu kullanan bir yük dengeleme çözümü sağlamalısınız.
Primary-Standby (Single Master) ve Multi Master Replikasyon
Veritabanı replikasyonu Primary-Standby ve Multi-Master olmak üzere 2 model ile kurgulanabilir.
Primary-Standby Replikasyon : Belirlenen primary veritabanındaki değişiklikler bir veya daha fazla standby sunucusuna çoğaltılır. Standby veritabanının read write kullanımına izin verilmez. (Bir şekilde standby veritabanında read write yapılsa bile bu değişiklikler primary veritabanına kopyalanmaz) Bu kullanımda, uygulamaların trafiği primary veritabanına yönlendirmesi gerektir. Tek primary’dan dolayı çatışma(conflict) ihtimali yoktur. Yapılandırma ve yönetme daha az karmaşık olduğu için çoğu zaman tek primary yeterlidir.
Multi-Master Replikasyon : Master görevi gören birden fazla sunucu olduğu anlamına gelir. Veriler, sunucular arasında çoğaltılır ve read write işlemleri bir grup master sunucu üzerinde mümkün olabilir. Bu durumda, verilerin birden çok kopyası vardır. Sistem aynı zamanda eşzamanlı değişiklikler arasında meydana gelen herhangi bir çatışmanın(conflict) çözümünden de sorumludur.
NOT : Yukarıdada yazdığım gibi, primary-standby replikasyon çoğu durumda yeterlidir, ancak yine de, multi-master replikasyon gereksiniminin olduğu bazı durumlar vardır. PostgreSQL internal olarak multi-master replikasyon modeline sahip değildir. Bazı Multimaster replikasyon çözümleri (BDR, xDB, PostgreSQL-XL, PostgreSQL-XC2, Rubyrep, Bucardo) mevcuttur, bunlardan bazıları uygulama olarak geliştirilmiş ve bazıları PostgreSQL fork larıdır. Bu forkların kendi toplulukları vardır ve çoğunlukla tek bir şirket tarafından yönetilir, ancak bunlar ana PostgreSQL community tarafından yönetilmez.
Senkron ve Asenkron Replikasyon
Veritabanı replikasyonu Senkron ve Asenkron olmak üzere iki strateji ile kurgulanabilir;
Senkron Replikasyon : Maksimum veri koruması için bir koruma yöntemidir, standby veritabanı bu modda kullanıcıya sıfır veri kaybı özelliği sağlar. Bu stratejide kullanıcı başlattığı bir transaction için commit koyduğu anda başlatılan transaction Standby’a uygulanmadan kullanıcıya commit edildiği bilgisi dönmez. Senkron replikasyon, anlık yük devretme gereksinimleri olan üst düzey ortamlarda kullanılır diyebiliriz.
Asenkron Replikasyon : Bu stratejide kullanıcı commit yaptığı anda standby veritabanları beklenmeden(sadece primary veritabanınında wal kaytlarının diske yazılması beklenir) commit edildiği bilgisi kullanıcıya döner, yani transaction commit edildiğinde sadece primary veritabnına verinin yazılacağının garantisi vardır. Primary veritabanının çöküp standby veritabanlarından devam etme durumunda veri kaybı meydana gelebilir, ancak bu strateji primary veritabanına çok az ek yük sağlar ve bu nedenle çoğu durumda kabul edilebilir.
NOT : Bazı sistemler ayrıca karar vermek için quorum kullanır. Quorum kullanılırsa, veritabanlarının yarısından fazlasının cluster içindeki bir eylem üzerinde anlaşması gerekir. Örneğin 3 PostgreSQL sunucusundan (master, slave-1, slave-2) oluşan bir clusterı düşünürsek, synchronous_standby_names’i ANY 1 (slave-1,slave-2) ayarlayarak quorum replication ayarlayabiliriz. Bu şekilde üç node’dan ikisi daima en yeni verilere sahip olacaktır.
Amacınıza uygun olanı seçebilmeniz için her iki tür replikasyon modunun nasıl çalıştığını anlamak önemlidir. Herhangi bir seçimde performans dikkate alınmalıdır. İşlevsellik ve performans arasında genellikle bir denge vardır. Örneğin, yavaş bir ağ üzerinden tamamen senkron bir çözüm, performansı yarıdan fazla düşürebilirken, asenkron bir çözümün performansı minimum düzeyde etkileyebilir. (devamı..)
MVCC (Multi Version Concurrent Control), veri tabanına eşzamanlı erişim sağlamak için veritabanı yönetim sistemleri tarafından kullanılan eşzamanlılık kontrol yöntemidir, yani MVCC postgresql veri tabanında eş zamanlı olarak okuma ve yazma işlemlerinin sorunsuz yapılabilmesi adına geliştirilen bir modeldir. Aslında amaç basit veritabanında read yapanlar write yapanları engeleyemesin, yazma yapanlarda okuma yapanları engeleyemesin. Bu teknik Postgres’e özgü değildir Oracle, Berkeley DB, CouchDB vb veritabanları bir tür MVCC’yi uygularlar.
Eşzamanlılık kontrolü olmadan, bir transaction yazarken aynı anda başka bir transaction veriyi okursa, okuyucunun yarı yazılı veya tutarsız bir veri parçası görmesi mümkündür. Örneğin, iki banka hesabı arasında bir banka havalesi yaparken, bir okuyucu, para orijinal hesaptan çekildiğinde ve hedef hesaba yatırılmadan önce bankadaki total bakiyeyi okursa, paranın hesaptan kaybolduğunu düşünür.
İzolasyon, verilere eşzamanlı erişimlerde garantiler sağlayan özelliktir. İzolasyon, eşzamanlılık kontrol protokolü aracılığıyla gerçekleştirilir. İzolosyanu sağlamanın en basit yoluRead/Write locks, Two-Phase Locking gibi lock mekanizmalarıdır ancak lock contentiona(çekişme) neden olur ve contention ölçeklenebilirliği etkiler. Bu nedenle, veritabanı araştırmacıları, locklamayı minimuma indirmeye çalışan farklı bir Eşzamanlılık Kontrolü modeli geliştirdiler, böylece:
Write Ahead Logging (WAL), veri bütünlüğünü(data integrity) sağlamaya yönelik standart bir yöntemdir. Postgresql, üzerlerinde yapılan, insert/update/delete işlemlerini, bilgilerin asıl tutulduğu diskteki Data Page’lere yazmanın yanında Transaction Log adı verilen log dosyalarına da yazarlar. Hatta verilerin tutulduğu data page’den önce transaction log’u diske yazar, sonrasında ihtiyaca göre data page’e yazar. Hatta commit edilen uygulama başarılı bir şekilde Commit edildi bilgisini Transcation Log dosyası diske yazıldığında verirler, data Page’lere diske yazılmasını beklemezler. Transaction Log’lar ardışıl disk Page’lerinde oldukları için onların diske yazılması muhtemelen dağınık durumda bulunan Data Page’lerin diske yazılmasından daha hızlı olacaktır.
NOT : PostgreSQL performans için Atomicity ve Durability’den taviz vermek isteyenlere özel Transcation Log’ların diske yazılma işleminin Asenkron yapılmasına da olanak tanır. Bu durumda Postgresql, Transaction Log’un diske yazılmasını beklemeden Transaction’ın başarılı olduğunu uygulamaya bildirir ancak tam bu sırada sunucu çökmesi durumunda veri kaybı yaşanabilir.
Transaction log, veritabanının önemli bir parçasıdır, çünkü veritabanı yönetim sisteminin bir sistem arızası meydana geldiğinde bile herhangi bir veriyi kaybetmemesi gerekir. Elektrik kesintisi veya sunucu çökmesine neden olan başka bir sunucu arızası gibi arızalar nedeniyle hiçbir verinin kaybolmamasını sağlamak için bir veritabanı sistemindeki tüm değişikliklerin ve eylemlerin bir geçmiş logudur. Log, halihazırda yürütülen her transaction hakkında yeterli bilgi içerdiğinden, veritabanı sunucusunun, sunucu çökmesi durumunda transaction log’daki değişiklikleri ve eylemleri yeniden çalıştırarak veritabanı clusterı kurtarabilmesi gerekir. Veri tabanında transaction log kayıtlarının tutulmadığı durumu düşündüğümüzde, shared buffer poolda değiştirilmiş ama diske henüz değişikliklerin kalıcı olarak yazılmadığı durumlarda bir kesinti veya veri tabanı kapanması olduğunda transactionların tabloya eklediği veriler kaybedilir.
NOT : Bu arada, crash durumunda recovery işleminin nasıl yapıldığına delecek olursak; Her bir checkpoint işleminden sonra transaction log dosyası sıfırlanır ve checkpoint ile ilgili bilgiler pg_control dosyasına yazılır, recovery işlemi yapılacağında sunucu öncelikle pg_control dosyasını ve checkpoint kaydını okur ve checkpoint kaydından sonraki transactionları REDO işleminden geçirir yani wal dosyalarından okur. pg_controldata ile controlfile’ın içine baktığımızda yukarıdada yazdığım gibi en sonki checkpointin LSN yazacaktır.
VACUUM, dead tuple ların bulunduğu depolama alanını geri kazanır. Öncelikle Postgres üzerinde bir tabloda Update veya Delete çalıştırdığımızda neler olduğuyla başlayalım. DELETE işlemleri gerçekleştirildiğinde, verilerin bulunduğu tupleları fiziksel olarak silmek yerine mevcut tuple’ı DEAD olarak işaretler. Benzer şekilde, GÜNCELLEME işlemi gerçekleştirildiğinde, karşılık gelen mevcut tuple’ı DEAD olarak işaretler ve yeni bir tuple ekler.(Aslında Update = Hide/Unvisible + Insert demektir.)
Bu nedenle, her bir DELETE ve UPDATE komutu, asla kullanılmayacak olan bir DEAD tuple ile sonuçlanacaktır. Bu dead tuple lar, veriler aynı veya daha az sayıda olsa bile gereksiz fazladan alan kullanımına yol açacaktır.
İşte vacuum DEAD tuple ile ilgilenmeyi sağlayan bakım sürecidir. Vacuum işlemi sequential scan sırasında okunan tuple sayısını azaltacağı için okuma işlemlerinde de hızlanmaya sebep olacaktır. Sequential scan sıralı okuma işlemidir ve dead tuple’ları atlamaz. Dolayısı ile dead tuple’ların temizlenmesi daha az satır okunması anlamına gelir.
Vacuum, tüm tabloların taranmasını içerdiğinden, maliyetli bir işlemdir. 8.4 (2009) sürümünde, Visibility Map (VM), dead tupleların işaretlenme verimliliğini artırmak için tanıtıldı. 9.6 (2016) sürümünde, VM geliştirilerek freeze prosesi iyileştirildi.
Visibility Map
VM’in temel konsepti basittir. Her tablonun, tablo dosyasındaki her page’in görünürlüğünü tutan ayrı bir görünürlük haritası vardır. Pagelerin görünürlüğü, her page’de dead tuple olup olmadığını belirler. Vacuum, dead tuple içermeyen pageleri atlayabilir. Aşağıdaki şekildeki gibi bir tablomuz olduğunu düşünelim; Tablonun üç page’den oluştuğunu ve 0. ve 2. sayfaların dead tuplelar içerdiğini ve 1. sayfanın olmadığını varsayalım. Bu tablonun görünürüülük haritası(vm), hangi pagelerin dead tuplelar içerdiği hakkında bilgi içerir. Bu durumda, vacuum, VM’nin bilgilerine başvurarak 1. sayfayı atlar.
Her VM bir veya daha fazla 8 KB page’den oluşur ve bu dosya ‘vm’ sonekiyle saklanır. Örnek olarak, FSM (18751_fsm) ve VM (18751_vm) dosyaları ile relfilenode 18751 olan bir tablo dosyası aşağıda gösterilmiştir.
Free space map, her veri dosyasının boş alanı hakkındaki bilgileri depolar. Yukarıdada gördüğümüz gibi anadosyaya paralel ‘fsm’ soneki ile biten dosyada saklanır bilgiler. FSM’nin amacı yeterli alan içeren bir page’i hızlı bir şekilde bulmaktır veya böyle bir page’in bulunmadığını veri dosyasının bir page kadar büyütülmesi gerektiğini belirlemek içindir.
Freeze Tuple
Postgresql’deki her yazma işlemi veya bağımsız ifadeye benzersiz bir transaction id (veya XID) atanır. Bu XID, diğer eşzamanlı kullanıcıların transactionla ilişkili satır değişikliklerini görebileceğini belirleyerek öncelik görünürlüğünü(precedence visibility) belirler. Salt okunur işlemlere XID atanmaz. Bu XID’ler, depolamadaki her satıra xmin ve xmax biçiminde damgalanır ve satırı “görebilen” minimum ve maksimum eşzamanlı transactionları belirtir. Bunları row header lerine yerleştirerek, Postgresql’in eşzamanlılık(concurrency) yeteneklerini destekleyen transaction çakışması çözümünü merkezileştiriyor.
Ancak, XID’lerle ilgili bir sorun var: bunlar dört baytlık bir tamsayıdır. Bu, 2,1 milyar işlemden sonra başa sarmaları gerektiği anlamına gelir. Ve XID sayacı başa sardığında, eski XID’lerin tüm eski row headerlarından çıkarılması gerekir. Bu, XID’nin xmin ve xmax’tan kaldırılması ve özel RelFrozenXID değeriyle değiştirilmesi anlamına gelir; bu, herkesin görebileceği çok eski bir transactionı belirtir. (devamı..)
2003 yılında, SQL standardına SQL Management of External Data (SQL/MED) adı verilen uzak verilere erişim özelliği eklendi. Bu özellik, 9.1 sürümünden beri SQL / MED’in bir bölümünü gerçekleştirmek için PostgreSQL tarafından geliştirilmektedir. SQL / MED’de, uzak sunucudaki bir tabloya foreign tablo denir. PostgreSQL Foreign Data Wrapper (FDW), local tablolara benzer foreign tabloları yönetmek için SQL / MED kullanırlar.
Yani kısaca FDW, Postgres içerisinden harici/uzak/farklı veri sistemlerine doğrudan bağlanmanızı, sorgulamanızı sağlayan tercümanlardır diyebiliriz. Bir eklenti olarak kurulan FDW ile sadece uzak farklı veritabanı sistemlerine bağlanmak ve veri alabilmenin, sorgu gönderebilmenin yanı sıra aynı zamanda yazma işlemi de yapabilmekteyiz. FWD’yi, farklı veri kaynaklarından verileri normalize ederek merkezi bir veritabanına join sorgular oluşturarak çekmek için ETL aracı olarak da kullanmak da mümkün olmakla birlikte, belki en performanslı araç olmayabilir ama şurası kesin ki en hızlı yöntemdir.
FWD eklentilerinin bir kısmı Postgres üzerinde hazır olarak gelirken, bazıları açık kaynaklı paketin içine dahil edilemezler ve ayrıca indirilmelidirler. Buna örnek MySQL FWD’yi aktif hale getirmeden önce indirip kurmanız gerekir ki bu çok basit bir işlemdir. Bazı FWD Eklentilerine kısaca göz atalım:
Postgres FDW : Şüphesiz en kolay ve hızlı giriş yapabileceğimiz FWD, Postgres’in kaynak olarak farklı bir host üzerinde olan yine PostgreSQL veritabanına bağlanmak için kullandığımız Potgres FWD olacak.
MySQL FDW : Bu PostgreSQL extensionı MySQL için Foreign Data Wrapper (FDW) uygular.
Oracle FDW : oracle_fdw, WHERE koşullarının ve gerekli sütunların pushdown ve kapsamlı EXPLAIN desteği dahil olmak üzere Oracle veritabanlarına kolay ve verimli erişim için Foreign Data Wrapper sağlayan bir PostgreSQL extensionıdır.
CSV : File_fdw modülü, sunucunun dosya sistemindeki veri dosyalarına erişmek veya sunucudaki programları çalıştırmak ve çıktılarını okumak için kullanılabilen FDW file_fdw sağlar.