30.4. Списки столбцов #
Для каждой публикации можно дополнительно задать, какие столбцы каждой таблицы реплицируются для подписчиков. При этом в таблице на стороне подписчика должны быть как минимум все публикуемые столбцы. Если список столбов не задан, реплицируются все столбцы публикуемой таблицы. Подробнее синтаксис рассматривается в описании CREATE PUBLICATION.
Ограничение множества столбцов может быть продиктовано соображениями производительности или требованиями к поведению. Однако из соображений безопасности использовать это не следует: злоумышленник на стороне подписчика может получить данные из столбцов, которые не были опубликованы явно. Когда важно обеспечить безопасность, надо применять защиту на стороне публикации.
Если список столбцов не задан, все столбцы, добавляемые в таблицу позднее, будут реплицироваться автоматически. Это означает, что наличие списка, включающего все столбцы, не равнозначно отсутствию списка столбцов.
Список столбцов может содержать только простые ссылки на столбцы. Порядок столбцов в этом списке не сохраняется.
Указать список столбцов в публикации, которая также публикует все таблицы в схеме (FOR TABLES IN SCHEMA
), нельзя.
Для секционированных таблиц параметр публикации publish_via_partition_root
определяет, какой список столбцов использовать. Если publish_via_partition_root
имеет значение true
, используется список столбцов корневой секционированной таблицы. В противном случае, если publish_via_partition_root
имеет значение false
(по умолчанию), используется список столбцов каждой секции.
Если через публикацию реплицируются операции UPDATE
или DELETE
, список столбцов должен содержать столбцы, которые входят в идентификатор реплики для данной таблицы (см. REPLICA IDENTITY
). Если же через публикацию реплицируются только операции INSERT
, столбцы идентификатора реплики в списке столбцов могут отсутствовать.
Для команды TRUNCATE
списки столбцов не имеют значения.
Во время начальной синхронизации данных копируются только публикуемые столбцы. Однако если на стороне подписчика используется версия ниже 15, при начальной синхронизации копируются все столбцы в таблице, то есть любые списки столбцов игнорируются.
Внимание: объединение списков столбцов из нескольких публикаций
В настоящее время не поддерживаются подписки, связанные с несколькими публикациями, в которых одна таблица опубликована с разными списками столбцов. Команда CREATE SUBSCRIPTION не допускает создание таких подписок, но это всё равно может произойти при добавлении или изменении списков столбцов на стороне публикации после создания подписки.
Это означает, что изменение списков столбцов таблиц в публикациях, у которых уже есть подписчики, может привести к возникновению ошибок на стороне подписчика.
Если подписка затронута этой проблемой, единственный способ возобновить репликацию — изменить один из списков столбцов на стороне публикации, чтобы все они совпадали; а затем либо заново создать подписку, либо использовать ALTER SUBSCRIPTION ... DROP PUBLICATION
, чтобы удалить одну из проблемных публикаций и добавить её снова.
30.4.1. Примеры #
Создайте таблицу t1
, которая будет использоваться в следующем примере.
test_pub=# CREATE TABLE t1(id int, a text, b text, c text, d text, e text, PRIMARY KEY(id)); CREATE TABLE
Создайте публикацию p1
, в которой для таблицы t1
определяется список столбцов, уменьшающий количество реплицируемых столбцов. Заметьте, что порядок имён столбцов в этом списке не имеет значения.
test_pub=# CREATE PUBLICATION p1 FOR TABLE t1 (id, b, a, d); CREATE PUBLICATION
Списки столбцов для каждой публикации можно просмотреть в psql
.
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
.
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)
Создайте на сервере подписчика таблицу t1
, которая теперь должна содержать лишь подмножество столбцов, существующих в публикуемой таблице t1
, а также создайте публикацию s1
, связанную с публикацией 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
Добавьте на стороне публикации в таблицу 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)
Как можно видеть, реплицировались только данные из списка столбцов в публикации p1
.
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)