Bu yazıda PostgreSQL’de WAL dosyalarından, veritabanında çalıştırılmış SQL’leri bind değerleri ile birlikte nasıl elde edebileceğimizi inceleyeceğiz. Veritabanında yapılan yanlış DELETE, UPDATE, INSERT işlemleri bu yöntem ile WAL dosyalarından çıkarılarak, hatalı işlemler geri alınabilirler. Logical Decoding özelliği PostgreSQL’e 11 sürümü ile gelmiştir.
WAL dosyalarını inceleyebilmek için öncelikle bir replikasyon slotu oluşturmamız gereklidir.
Slot ismi log_decode, çıktılar için test_decoding plug-in’i kullanıyoruz, false ile slot’un kalıcı olması gerektiğini belirtiyoruz. Bu fonksiyon bize slot’un başladığı LSN’i ve slot ismini geri döner.
Slot’a ait bilgileri görelim.
1 |
SELECT slot_name, plugin, slot_type, database, active, restart_lsn, confirmed_flush_lsn FROM pg_replication_slots; |
Aşağıdaki sorgu ile slot üzerinden okuma yapmaya başlayabiliriz. Birinci parametresi slot adı, ikinci parametre (NULL verilmiş) upto_lsn, üçüncü parametre (NULL) upto_nchanges değerlerini ifade eder. Ancak bu iki parametre için NULL verilirse slot oluştuğundan güncel ana kadar olan değişiklikleri görebiliriz. Özel bir zaman aralığı veya belli sayıda değişiklik istenirse bu parametrelere değer verilebilir. Gerçek ortam veritabanında sorgu sonucunda veriler anında sorgudan döner. Ancak test ortamında DML yapılıncaya kadar sorgu boş sonuç döner.
1 |
SELECT * FROM pg_logical_slot_get_changes('log_decode', NULL, NULL); |
Örnek bir tablo oluşturalım. DDL’ler replikasyona dahil olmadığından üstteki sorgu hala boş sonuç döner.
1 |
create table Users (id int, name text, surname text, email text); |
Şimdi tabloya kayıt ekleyip silelim ve durumu inceleyelim.
1 2 3 4 |
insert into Users (id, name, surname, email) values (1, 'John', 'Ally', 'jalley@example.com'); insert into Users (id, name, surname, email) values (2, 'Bill', 'Gates', 'jalley@example.com'); insert into Users (id, name, surname, email) values (3, 'Henry', 'Ford', 'jalley@example.com'); insert into Users (id, name, surname, email) values (4, 'Mark', 'Sennt', 'jalley@example.com'); |
Yeniden slot’u sorgulayalım ve yaptığımız değişiklikleri görelim.
1 |
SELECT * FROM pg_logical_slot_get_changes('log_decode', NULL, NULL); |
Sorguyu yeniden çalıştırdığımızda boş döndüğünü görürüz. Bunun nedeni, biz bu sorgu ile değişiklileri tüketen noktadayız (queue consumer). Son sorgumuzdan sonra değişiklik yoksa, sorgu sonucu boş gelir.
Eğer sorgulayınca sonuçların kalmasını istersek, farklı bir fonksiyonu aşağıdaki gibi kullanabiliriz. Şimdi bir kayıt daha ekleyelim ve sonuçlar kaybolmayacak şekilde sorgulayalım.
1 2 3 |
insert into Users (id, name, surname, email) values (6, 'Larry', 'Mock', 'jalley@example.com'); SELECT * FROM pg_logical_slot_peek_changes('log_decode', NULL, NULL, 'include-timestamp', 'on'); |
Yeniden sorgulayınca kayıtlar hala mevcut haldedir.
Fazla DML yapılan veritabanlarında çok fazla kayıt geleceği için sorgu sonucunu tabloya çıkarıp o tablo üzerinde işlemlere devam edilebilir. Çünkü her defasında WAL dosyalarından sonuçları çıkarıp göstermesi zaman alacaktır.