PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 15.9 » Administration du serveur » Réplication logique » Listes de colonnes

31.4. Listes de colonnes

Chaque publication peut indiquer en option aux abonnés les colonnes à répliquer pour chaque table. La table du côté abonné doit avoir au moins toutes les colonnes publiées. Si aucune liste de colonnes n'est indiquée, alors toutes les colonnes du côté du publieur sont répliquées. Voir CREATE PUBLICATION pour les détails sur la syntaxe.

Le choix des colonnes peut être basé sur des raisons de comportement ou de performance. Néanmoins, ne vous basez pas sur cette fonctionnalité pour de la sécurité : un abonné mal intentionné est capable d'obtenir des données des colonnes qui ne sont pas spécifiquement publiées. D'un point de vue sécurité, des protections peuvent être mises en place du côté du publieur.

Si aucune liste de colonne n'est indiquée, toutes les colonnes ajoutées ultérieurement à la table sont automatiquement répliquées. Cela signifie qu'avoir une liste de colonnes qui nomme toutes les colonnes n'aboutit pas au même comportement que ne pas avoir de liste de colonnes.

Une liste de colonnes peut contenir seulement des références de colonnes. L'ordre des colonnes dans la liste n'est pas préservé.

Préciser une liste de colonnes n'est pas possible quand la publication publie aussi toutes les tables d'un schéma (clause FOR TABLES IN SCHEMA).

Pour les tables partitionnées, le paramètre de publication publish_via_partition_root détermine quel liste de colonnes utiliser. Si publish_via_partition_root vaut true, la liste de colonnes utilisée est celle de la table partitionnée. Sinon, si publish_via_partition_root vaut false (valeur par défaut), la liste de colonnes utilisée est celle de la partition concernée.

Si une publication publie des opérations UPDATE ou DELETE, toute liste de colonnes doit inclure les colonnes d'identité de réplicat de la table (voir REPLICA IDENTITY). Si une publication publie seulement des opérations INSERT, alors la liste de colonnes peut omettre les colonnes d'identité de réplicat.

Les listes de colonnes n'ont pas d'effet sur la commande TRUNCATE.

Lors de la synchronisation initiale des données, seules les colonnes publiées sont copiées. Néanmoins, si l'abonné est d'une version antérieure à la 15, alors toutes les colonnes dans la table sont copiées lors de la synchronisation initiale des données, ignorant en cela les liste de colonnes.

Attention : Combiner des listes de plusieurs publications

Actuellement, il n'est pas possible qu'une souscription soit entreprise auprès de plusieurs publications quand la même table a été publiée avec des listes de colonnes différentes. CREATE SUBSCRIPTION interdit la création de telles souscriptions mais il est toujours possible d'arriver dans cette situation par l'ajout ou la modification de listes de colonnes du côté publication une fois que la souscription a été créée.

Ceci signifie que la modification de liste de colonnes sur les publications déjà souscrites peut amener à des erreurs du côté souscripteur.

Si ce problème affecte une souscription, la seule façon de reprendre la réplication est d'ajuster une des listes de colonnes côté publication pour que les listes correspondent ; puis soit de créer de nouveau la souscription, soit utiliser ALTER SUBSCRIPTION ... DROP PUBLICATION pour supprimer une des publications problématiques et l'ajouter de nouveau après.

31.4.1. Exemples

Créer une table t1 à utiliser dans l'exemple suivant.

test_pub=# CREATE TABLE t1(id int, a text, b text, c text, d text, e text, PRIMARY KEY(id));
CREATE TABLE

Créer une publication p1. Une liste de colonnes est définie pour la table t1 pour réduire le nombre de colonnes qui seront répliquées. Notez que l'ordre des noms de colonnes dans la liste de colonnes n'a pas d'importance.

test_pub=# CREATE PUBLICATION p1 FOR TABLE t1 (id, b, a, d);
CREATE PUBLICATION

psql peut être utilisé pour afficher les listes de colonnes (si définies) pour chaque publication.

test_pub=# \dRp+
                               Publication p1
  Owner   | All tables | Inserts | Updates | Deletes | Truncates | Via root
----------+------------+---------+---------+---------+-----------+----------
 postgres | f          | t       | t       | t       | t         | f
Tables:
    "public.t1" (id, a, b, d)

psql peut être utilisé pour afficher les listes de colonnes (si définies) pour chaque table.

test_pub=# \d t1
                 Table "public.t1"
 Column |  Type   | Collation | Nullable | Default
--------+---------+-----------+----------+---------
 id     | integer |           | not null |
 a      | text    |           |          |
 b      | text    |           |          |
 c      | text    |           |          |
 d      | text    |           |          |
 e      | text    |           |          |
Indexes:
    "t1_pkey" PRIMARY KEY, btree (id)
Publications:
    "p1" (id, a, b, d)

Sur le nœud abonné, créer une table t1 qui maintenant a seulement besoin d'un sous-ensemble des colonnes qui sont sur la table côté publieur t1, et crée aussi l'abonnement s1 qui cible la publication p1.

test_sub=# CREATE TABLE t1(id int, b text, a text, d text, PRIMARY KEY(id));
CREATE TABLE
test_sub=# CREATE SUBSCRIPTION s1
test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s1'
test_sub-# PUBLICATION p1;
CREATE SUBSCRIPTION

Sur le nœud publieur, insérer quelques lignes dans la table t1.

test_pub=# INSERT INTO t1 VALUES(1, 'a-1', 'b-1', 'c-1', 'd-1', 'e-1');
INSERT 0 1
test_pub=# INSERT INTO t1 VALUES(2, 'a-2', 'b-2', 'c-2', 'd-2', 'e-2');
INSERT 0 1
test_pub=# INSERT INTO t1 VALUES(3, 'a-3', 'b-3', 'c-3', 'd-3', 'e-3');
INSERT 0 1
test_pub=# SELECT * FROM t1 ORDER BY id;
 id |  a  |  b  |  c  |  d  |  e
----+-----+-----+-----+-----+-----
  1 | a-1 | b-1 | c-1 | d-1 | e-1
  2 | a-2 | b-2 | c-2 | d-2 | e-2
  3 | a-3 | b-3 | c-3 | d-3 | e-3
(3 rows)

Seules les données de la liste de colonnes de la publication p1 sont répliquées.

test_sub=# SELECT * FROM t1 ORDER BY id;
 id |  b  |  a  |  d
----+-----+-----+-----
  1 | b-1 | a-1 | d-1
  2 | b-2 | a-2 | d-2
  3 | b-3 | a-3 | d-3
(3 rows)