sql >> Databáze >  >> RDS >> PostgreSQL

Jak replikovat pouze INSERTy, nikoli DELETE/UPDATE na Slony Slave Node?

V první řadě musíme vědět, proč je takový požadavek potřeba. IMO, jeho absolutně obchodní nutnost udržovat nějaký druh historických dat v cílové databázi (Slave Node). Zejména z více podřízených uzlů jeden z podřízených uzlů uchová úplně první formu dat při prvním zápisu do databáze.

Abychom tento požadavek splnili, měli bychom přijít s nějakým druhem filtrů, jako jsou TRIGGERs/RULEs na Slave Node, aby se zabránilo přenášení příkazů DELETE a UPDATE. Protože máme co do činění s Slony-I, nemá takový vestavěný mechanismus pro filtrování DML při jejich přehrávání na podřízeném uzlu, i když shromáždil všechny události z hlavního uzlu. (AFAIK Mysql, Oracle, SQL Server podporují filtry ).

Aby to bylo přímočaré, tradiční způsob Slony-I zachovává jedinečnost řádků napříč všemi uzly a jeho základní koncept tabulek musí mít primární klíče. V takovém návrhu architektury je těžké vyloučit příkazy DELETE/UPDATE, vezměte si příklad sloupce primárního klíče „orderid“ tabulky „orders“ má první příkaz INSERT s hodnotou 100 a byl replikován jako první formulář na filtrovaném Slave Node. Později byl proveden příkaz DELETE pro „orderid=100“ a odstraněný řádek, nyní, pokud se jakýkoli příkaz INSERT nebo UPDATE pokusí použít „orderid=100“, uzel Slave zasáhne duplicitní klíč a replikaci jednoduše přeruší.

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

Prováděcí pravidlo tedy nepředstavuje problém, ale když je zavedeno, je třeba být extrémně opatrný. Ve skutečnosti je však použití těchto filtrů na slave uzlu Slony-I velmi křehké, zvláště aplikace/vývojář by to měl mít vždy na paměti, jakékoli duplicitní zadání řádku příkazem INSERT NEBO UPDATE by mohlo replikaci přerušit.

Protože pravidla DML nejsou možná sama se Slony-I, můžeme použít PostgreSQL CREATE RULE…ON DELETE/ON UPDATE NEDĚLEJTE MÍSTO NIC a aplikujte toto PRAVIDLO na tabulku pomocí ALTER TABLE…ENABLE REPLICA RULE pro zrušení příkazu DELETE/UPDATE. Používání této možnosti vyžaduje hodně disciplíny, takže můžete zajistit, aby vaše aplikace a zaměstnanci skutečně dodržovali tato pravidla.

Chcete-li pokračovat v krocích, měli byste mít slony nastavení, v případě, že budete potřebovat nastavení, můžete se podívat na můj minulý příspěvek zde.

Kroky na Slave Node (Master DB:postgres, Slave DB:demo, Port:5432):

1. Zastavte démony slon
2. Vytvořte pravidlo ON DELETE a ON UPDATE NEDĚLEJTE 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. Aplikujte PRAVIDLO na stůl

demo=# ALTER TABLE reptest ENABLE REPLICA RULE void_delete;
ALTER TABLE
demo=# ALTER TABLE reptest ENABLE REPLICA RULE void_update ;
ALTER TABLE

4. Spusťte démony Slon

Nyní si níže můžete všimnout, že UPDATE/DELETE nemá žádný vliv na Slave Node:

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)

Pokud je příkaz INSERT proveden s hodnotou 1, přeruší replikaci. Pozor…!!

Pamatujte, že existují další způsoby, jak splnit tento požadavek, jako jsou dblinks, Triggers jako BEFORE DELETE...vracejí hodnotu NULL z funkce, ale věřím, že nejúčinnějším způsobem by bylo použití RULE/ENABLE REPLICA RULE, když pracujete s replikací Slony.

Nyní jste možná četli mnoho blogů o nové funkci slotů Logical Decoding Replication v PostgreSQL 9.4, doufáme, že v budoucnu bude zahrnovat koncept filtrování DML na Slave.

Děkujeme za návštěvu.


  1. Jak povolit režim protokolování archivace v databázi Oracle 19c

  2. Kdy použít Common Table Expression (CTE)

  3. Jak funguje funkce SPACE() na serveru SQL Server (T-SQL)

  4. Jak mohu procházet sadu výsledků MySQL více než jednou pomocí funkcí mysql_*?