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.
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.
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)