Documentation PostgreSQL 15.15 » Administration du serveur » Réplication logique » Listes de colonnes

Précédent | Niveau supérieur | Suivant
31.3. Filtres de lignes | Sommaire | 31.5. Conflits

## 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éplica 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éplica.

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)