PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment répliquer uniquement les INSERTs et non les DELETE/UPDATE sur Slony Slave Node ?

En premier lieu, nous devons savoir pourquoi une telle exigence était nécessaire. IMO, c'est absolument une nécessité commerciale pour maintenir une sorte de données historiques sur la base de données cible (nœud esclave). En particulier, parmi plusieurs nœuds esclaves, l'un des nœuds esclaves conserve la toute première forme des données lors de leur écriture initiale dans la base de données.

Pour répondre à cette exigence, nous devrions proposer une sorte de filtres tels que TRIGGERs/RULEs sur le nœud esclave afin qu'il évite de relayer les instructions DELETE et UPDATE. Puisque nous avons affaire à Slony-I, il ne dispose pas d'un tel mécanisme intégré pour filtrer les DML tout en les rejouant sur le nœud esclave bien qu'il ait rassemblé tous les événements du nœud maître. (AFAIK Mysql, Oracle, SQL Server prennent en charge les filtres ).

Pour être clair, la méthode traditionnelle Slony-I maintient l'unicité des lignes sur tous les nœuds avec son concept de base selon lequel les tables doivent avoir des clés primaires. Dans une telle conception d'architecture, il est difficile d'exclure les instructions DELETE/UPDATE, prenons un exemple de colonne de clé primaire "orderid" de la table "orders" a une première instruction INSERT avec la valeur 100 et elle a été répliquée en tant que première forme sur le nœud esclave filtré. Plus tard, une instruction DELETE exécutée pour "orderid =100" et une ligne supprimée, maintenant, si une instruction INSERT ou UPDATE tente d'utiliser le "orderid =100", le nœud esclave frappe avec une violation de clé en double et il interrompt simplement la réplication.

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

Ainsi, la règle de mise en œuvre n'est pas encore un problème, il faut être extrêmement prudent lorsqu'elle est en place. En réalité, cependant, l'application de ces filtres sur le nœud esclave Slony-I est très fragile, en particulier l'application/le développeur doit toujours garder cela à l'esprit. Toute entrée de ligne en double par INSERT OU UPDATE pourrait casser la réplication.

Comme les règles DML ne sont pas possibles seules avec Slony-I, nous pouvons utiliser PostgreSQL CREATE RULE…ON DELETE/ON UPDATE DO INSTEAD NOTHING et appliquer cette RULE sur la table par ALTER TABLE…ENABLE REPLICA RULE pour annuler l'instruction DELETE/UPDATE. L'utilisation de cette option demande beaucoup de discipline, vous pouvez donc vous assurer que votre candidature et les membres du personnel respectent vraiment ces règles.

Pour continuer avec les étapes, vous devriez avoir une configuration slony, au cas où vous auriez besoin de configurer, vous pouvez vous référer à mon précédent message ici.

Étapes sur le nœud esclave (base de données maître :postgres, base de données esclave :démo, port :5432) :

1. Arrêter les démons slon
2. Créer la règle ON DELETE et ON UPDATE DO INSTEAD NOTHING

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. Appliquer la RÈGLE sur la table

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

4. Démarrez les démons Slon

Maintenant, vous pouvez remarquer ci-dessous que UPDATE/DELETE n'a aucun impact sur le nœud esclave :

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)

Si l'instruction INSERT est exécutée avec la valeur 1, la réplication sera interrompue. Soyez noté…!!

N'oubliez pas qu'il existe d'autres moyens de remplir cette demande comme dblinks, des déclencheurs comme BEFORE DELETE… renvoient la valeur NULL de la fonction, mais je pense que le moyen le plus efficace serait d'utiliser RULE/ENABLE REPLICA RULE lorsque vous travaillez avec la réplication Slony.

À ce jour, vous avez peut-être lu de nombreux blogs sur la nouvelle fonctionnalité des slots de réplication de décodage logique dans PostgreSQL 9.4, espérons qu'à l'avenir, cela pourrait inclure le concept de filtres DML sur l'esclave.

Merci de votre visite.