Aby spełnić to wymaganie, powinniśmy wymyślić pewnego rodzaju filtry, takie jak TRIGGER/RULE w węźle podrzędnym, aby uniknąć przekazywania instrukcji DELETE i UPDATE. Ponieważ mamy do czynienia ze Slony-I, nie ma on takiego wbudowanego mechanizmu do filtrowania DML podczas odtwarzania ich w węźle podrzędnym, chociaż zebrał wszystkie zdarzenia z węzła głównego. (AFAIK Mysql, Oracle, SQL Server obsługują filtry ).
Aby uzyskać to prosto, tradycyjny sposób Slony-I utrzymuje niepowtarzalność wierszy we wszystkich węzłach, a jego podstawowa koncepcja tabel musi mieć klucze podstawowe. W takim projekcie architektury trudno jest wykluczyć instrukcje DELETE/UPDATE, na przykład kolumna klucza podstawowego „orderid” tabeli „orders” ma pierwszą instrukcję INSERT o wartości 100 i została zreplikowana jako pierwsza forma na filtrowanym węźle Slave. Później instrukcja DELETE wykonana dla „orderid=100” i usunięty wiersz, teraz, jeśli jakakolwiek instrukcja INSERT lub UPDATE spróbuje użyć „orderid=100”, wtedy węzeł Slave trafi z naruszeniem zduplikowanego klucza i po prostu przerwie replikację.
ERROR: duplicate key value violates unique constraint "reptest_pkey"
DETAIL: Key (id)=(2) already exists.
CONTEXT: SQL statement "INSERT INTO "public"."reptest" ("id", "name") VALUES ($1, $2);"
.....
or
....
CONTEXT: SQL statement "UPDATE ONLY "public"."reptest" SET "id" = $1 WHERE "id" = $2;"
2014-11-17 23:18:53 PST ERROR remoteWorkerThread_1: SYNC aborted
W związku z tym, wdrożenie przepisu nie jest jeszcze kwestią, należy być niezwykle ostrożnym, gdy jest na miejscu. W rzeczywistości jednak stosowanie tych filtrów w węźle podrzędnym Slony-I jest bardzo delikatne, szczególnie aplikacja/programista powinien zawsze o tym pamiętać, każdy zduplikowany wpis wiersza przez INSERT LUB UPDATE może przerwać replikację.
Ponieważ reguły DML nie są możliwe same w Slony-I, możemy skorzystać z PostgreSQL CREATE RULE…ON DELETE/ON UPDATE DO INSTEAD NOTHING i zastosować tę RULE na stole poprzez ALTER TABLE…ENABLE REPLICA RULE, aby unieważnić instrukcję DELETE/UPDATE. Korzystanie z tej opcji wymaga dużej dyscypliny, więc możesz upewnić się, że Twoja aplikacja i członkowie personelu naprawdę przestrzegają tych zasad.
Aby kontynuować, powinieneś mieć slony konfiguracji, jeśli nie będziesz musiał skonfigurować, możesz zapoznać się z moim poprzednim postem tutaj.
Kroki w węźle Slave (Master DB:postgres, Slave DB:demo, Port:5432):
1. Zatrzymaj demony slon
2. Utwórz regułę PRZY USUNIĘCIU i PRZY AKTUALIZACJI ZAMIAST NIC
demo=# CREATE RULE void_delete AS ON DELETE TO reptest DO INSTEAD NOTHING;
CREATE RULE
demo=# CREATE RULE void_update AS ON UPDATE TO reptest DO INSTEAD NOTHING;
CREATE RULE
3. Zastosuj REGUŁĘ na stole
demo=# ALTER TABLE reptest ENABLE REPLICA RULE void_delete;
ALTER TABLE
demo=# ALTER TABLE reptest ENABLE REPLICA RULE void_update ;
ALTER TABLE
4. Uruchom demony Slon
Teraz możesz zauważyć, że UPDATE/DELETE nie ma wpływu na węzeł Slave:
postgres=# delete from reptest where id =2;
DELETE 1
postgres=# update reptest set id=2 where id=1;
UPDATE 1
--On Master
postgres=# select * from reptest ;
id | name
----+------------
2 | A
(1 row)
--On Slave
demo=# select * from reptest ;
id | name
----+------------
1 | A
2 | C
(2 rows)
Jeśli instrukcja INSERT zostanie wykonana z wartością 1, przerwie replikację. Należy zauważyć…!!
Pamiętaj, że istnieją inne sposoby pełnego wypełnienia tego żądania, takie jak dblinks, wyzwalacze, takie jak BEFORE DELETE…zwróć wartość NULL z funkcji, ale uważam, że najbardziej wydajnym sposobem byłoby użycie RULE/ENABLE REPLICA RULE podczas pracy z replikacją Slony.
Być może przeczytałeś już wiele blogów na temat nowej funkcji slotów Logical Decoding Replication w PostgreSQL 9.4, mam nadzieję, że w przyszłości może ona zawierać koncepcję filtrów DML w Slave.
Dziękujemy za odwiedzenie.