sql >> Database >  >> RDS >> PostgreSQL

Hoe repliceer je alleen INSERT's en niet DELETEs/UPDATEs op Slony Slave Node?

In de eerste plaats moeten we weten waarom een ​​dergelijke vereiste nodig was. IMO, het is absoluut een zakelijke noodzaak om een ​​soort historische gegevens op de doeldatabase (Slave Node) bij te houden. Vooral van meerdere slave-knooppunten behoudt een van de slave-knooppunten de allereerste vorm van de gegevens toen deze voor het eerst in de database werden geschreven.

Om aan deze vereiste te voldoen, moeten we een soort van filters bedenken, zoals TRIGGERs/RULEs op Slave Node, zodat de instructies DELETE en UPDATE niet worden doorgegeven. Aangezien we met Slony-I te maken hebben, heeft het niet zo'n ingebouwd mechanisme om DML's te filteren terwijl ze op slave-knooppunt worden afgespeeld, hoewel het alle gebeurtenissen van het hoofdknooppunt heeft verzameld. (AFAIK Mysql, Oracle, SQL Server ondersteunen wel filters ).

Om dit recht te zetten, handhaaft de traditionele Slony-I-manier het unieke karakter van rijen over alle knooppunten, waarbij het kernconcept van tabellen primaire sleutels moet hebben. In een dergelijk architectuurontwerp is het moeilijk om DELETE/UPDATE-instructies uit te sluiten, neem een ​​voorbeeld van een primaire sleutelkolom "orderid" van de "orders"-tabel met een eerste INSERT-instructie met waarde 100 en deze is gerepliceerd als eerste vorm op gefilterde Slave Node. Later werd een DELETE-instructie uitgevoerd voor "orderid=100" en verwijderde rij, nu als een INSERT- of UPDATE-instructie de "orderid=100" probeert te gebruiken, dan raakt het slaveknooppunt met dubbele sleutelovertreding en verbreekt het eenvoudig de replicatie.

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

Het implementeren van regels is dus geen probleem, maar men moet uiterst voorzichtig zijn wanneer het op zijn plaats is. In werkelijkheid is het toepassen van deze filters op het Slony-I slave-knooppunt echter erg kwetsbaar, vooral de applicatie/ontwikkelaar moet hier altijd rekening mee houden dat elke dubbele invoer van een rij door INSERT OF UPDATE de replicatie kan verbreken.

Aangezien DML-regels niet alleen mogelijk zijn met Slony-I, kunnen we gebruik maken van PostgreSQL CREATE RULE...ON DELETE/ON UPDATE DO INSTEAD NOTHING en pas die RULE toe op de tafel door ALTER TABLE...ENABLE REPLICA RULE om de DELETE/UPDATE-instructie ongeldig te maken. Het gebruik van deze optie vergt veel discipline, dus u kunt ervoor zorgen dat uw aanvraag en medewerkers zich echt aan deze regels houden.

Om door te gaan met de stappen, zou je een slony setup moeten hebben, als je de kans hebt dat je moet instellen, kun je mijn eerdere bericht hier raadplegen.

Stappen op Slave Node (Master DB:postgres, Slave DB:demo, Port:5432):

1. Stop slon-daemons
2. Maak ON DELETE en ON UPDATE DO IN PLAATS NIETS regel

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. Pas REGEL toe op tafel

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

4. Start Slon-daemons

Nu kun je hieronder zien dat UPDATE/DELETE geen invloed heeft op 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)

Als de INSERT-instructie met waarde 1 wordt uitgevoerd, wordt de replicatie verbroken. Let op...!!

Onthoud dat er andere manieren zijn om aan dit verzoek te voldoen, zoals dblinks, triggers zoals BEFORE DELETE ... retourneer de NULL-waarde van de functie, maar ik geloof dat de meest efficiënte manier zou zijn om RULE/ENABLE REPLICA RULE te gebruiken wanneer u met Slony-replicatie werkt.

Inmiddels heb je misschien al veel blogs gelezen over de nieuwe functie van Logical Decoding Replication-slots in PostgreSQL 9.4, in de hoop dat het in de toekomst het concept van filter-DML's op Slave kan bevatten.

Bedankt voor uw bezoek.


  1. Aggregatie van (x,y) coördinaatpuntenwolken in PostgreSQL

  2. Grootte van groot object ophalen in PostgreSQL-query?

  3. Oracle Database TLS1.2 / SSL-verbinding met JDBC thin en JKS

  4. MySQL-database migreren van Amazon RDS naar DigitalOcean