CREATE PUBLICATION

CREATE PUBLICATION — создать публикацию

Синтаксис

CREATE PUBLICATION имя
    [ FOR ALL TABLES
      | FOR объект_публикации [, ... ] ]
    [ WITH ( параметр_публикации [= значение] [, ... ] ) ]

где объект_публикации может быть следующим:

    TABLE [ ONLY ] имя_таблицы [ * ] [ ( имя_столбца [, ... ] ) ] [ WHERE ( выражение ) ] [, ... ]
    TABLES IN SCHEMA { имя_схемы | CURRENT_SCHEMA } [, ... ]

Описание

CREATE PUBLICATION создаёт новую публикацию в текущей базе данных. Имя публикации должно отличаться от имён других существующих публикаций в текущей базе.

Публикация по сути является группой таблиц, изменения в данных которых должны реплицироваться с использованием логической репликации. Подробнее о том, как публикации вписываются в схему логической репликации, рассказывается в Разделе 29.1.

Параметры

имя #

Имя новой публикации.

FOR TABLE #

Задаёт список таблиц, добавляемых в публикацию. Если перед именем таблицы указано ONLY, в публикацию добавляется только заданная таблица. Без ONLY добавляется и заданная таблица, и все её потомки (если таковые есть). После имени таблицы можно добавить необязательное указание *, чтобы явно обозначить, что должны включаться и все дочерние таблицы. Однако это не распространяется на секционированные таблицы. Секции секционированной таблицы всегда неявно считаются частью публикации, поэтому они никогда не добавляются в публикацию явным образом.

Если указано необязательное предложение WHERE, оно определяет выражение фильтра строк. Строки, для которых выражение выдаёт false или null, не будут публиковаться. Заметьте, что выражение нужно заключать в круглые скобки. Это предложение не действует на команды TRUNCATE.

Если указан список столбцов, реплицируются только указанные столбцы. Если список столбцов не задан, через эту публикацию будут реплицироваться все столбцы таблицы, в том числе столбцы, добавленные позже. На команды TRUNCATE это ограничение не действуют. Подробнее о списках столбцов рассказывается в Разделе 29.5.

В публикацию могут включаться только постоянные базовые и секционированные таблицы. Временные, нежурналируемые и сторонние таблицы, а также материализованные и обычные представления не могут входить в публикацию.

Указать список столбцов в публикации, которая также публикует все таблицы в схеме (FOR TABLES IN SCHEMA), нельзя.

Когда в публикацию добавляется секционированная таблица, все её существующие и будущие секции неявно становятся частью публикации. Поэтому даже операции, выполняемые непосредственно с секцией, также публикуются через публикации, в которые включена её родительская таблица.

FOR ALL TABLES #

Устанавливает, что данная публикация охватывает изменения во всех таблицах в базе данных, включая таблицы, которые будут созданы позже.

FOR TABLES IN SCHEMA #

Устанавливает, что данная публикация охватывает изменения во всех таблицах в указанном списке схем, включая таблицы, которые будут созданы позже.

Указать схему, когда публикация также публикует таблицу со списком столбцом, нельзя.

В публикацию будут включены только постоянные базовые и секционированные таблицы, присутствующие в схеме. Временные, нежурналируемые, сторонние таблицы, материализованные представления и обычные представления из этой схемы в публикацию не войдут.

Когда секционированная таблица публикуется посредством публикации схемы, все её существующие и будущие секции неявно становятся частью публикации, независимо от того, относятся ли к опубликованной схеме или нет. Поэтому даже операции, выполняемые непосредственно с секцией, также публикуются через публикации, в которые включена её родительская таблица.

WITH ( параметр_публикации [= значение] [, ... ] ) #

В этом предложении могут задаваться следующие необязательные параметры публикации:

publish (string) #

Этот параметр определяет, какие операции DML будет передавать новая публикация её подписчикам. В качестве его значения через запятую задаётся список операций из следующих: insert, update, delete и truncate. По умолчанию публикуются все действия, так что этот параметр имеет значение по умолчанию 'insert, update, delete, truncate'.

Этот параметр влияет только на операции DML. В частности, он не учитывается, когда копируются существующие данные таблиц при начальной синхронизации данных (см. Подраздел 29.8.1) для логической репликации.

publish_via_partition_root (boolean) #

Этот параметр определяет, будут ли изменения в секции секционированной таблицы, включённой в публикацию, публиковаться как произошедшие в секционированной таблице (с её именем и схемой), а не в той секции, где они фактически имели место (это поведение по умолчанию). Включение этого параметра позволяет реплицировать изменения в несекционированную таблицу или в таблицу, состоящую из другого набора секций.

Иногда подписка связана с несколькими публикациями. Когда секционированная таблица публикуется в любой публикации, на которую оформлена подписка с publish_via_partition_root = true, изменения в этой секционированной таблице (или в её секциях) публикуются с указанием идентификатора или схемы этой секционированной таблицы, а не отдельной секции.

Этот параметр также определяет, какие фильтры строк и списки столбцов выбираются для секций; подробности описаны ниже.

Когда этот параметр включён, операции TRUNCATE, выполняемые непосредственно с секциями, не реплицируются.

Если для параметра типа boolean опустить = значение, это равнозначно указанию значения TRUE.

Примечания

Если не задано ни FOR TABLE, ни FOR ALL TABLES, ни FOR TABLES IN SCHEMA, публикация создаётся с пустым набором таблиц. Это полезно, если таблицы или схемы будут добавляться позднее.

Создание публикации не влечёт немедленный запуск репликации. Эта операция только определяет логику группирования и фильтрации для будущих подписчиков.

Чтобы создать публикацию, пользователь должен иметь право CREATE в текущей базе данных. (Разумеется, на суперпользователей это условие не распространяется.)

Чтобы добавить таблицу в публикацию, пользователь должен иметь права владельца этой таблицы. Использовать предложения FOR ALL TABLES и FOR TABLES IN SCHEMA могут только суперпользователи.

Таблицы, добавляемые в публикацию, которая охватывает операции UPDATE и/или DELETE, должны иметь свойство REPLICA IDENTITY. В противном случае отслеживание этих операций для таблиц будет запрещено.

Для публикации операций UPDATE или DELETE необходимо, чтобы список столбцов включал столбцы идентификатора реплики (REPLICA IDENTITY). Если публикация создаётся только для операций INSERT, ограничений на список столбцов нет.

Для публикации операций UPDATE и DELETE требуется, чтобы выражение фильтра строк (то есть предложение WHERE) содержало только столбцы, входящие в идентификатор реплики (REPLICA IDENTITY). Для публикации операции INSERT в выражении WHERE может использоваться любой столбец. В фильтре строк допускаются простые выражения, не использующие пользовательские функции, пользовательские операторы, пользовательские типы, пользовательские правила сортировки, а также непостоянные встроенные функции и ссылки на системные столбцы.

Фильтр строк таблицы становится избыточным, когда добавляется указание FOR TABLES IN SCHEMA и таблица принадлежит указанной схеме.

Для опубликованных секционированных таблиц фильтр строк для каждой секции берётся из опубликованной секционированной таблицы, если параметр публикации publish_via_partition_root равен true, или из самой секции, если он равен false (по умолчанию). Подробнее фильтры строк описаны в Разделе 29.4. Аналогично, для опубликованных секционированных таблиц список столбцов для каждой секции берётся из опубликованной секционированной таблицы, если параметр публикации publish_via_partition_root равен true, или из самой секции, если он равен false.

Для команды INSERT ... ON CONFLICT публикация будет выдавать операцию, к которой сводится команда. В зависимости от исхода команды, она может быть опубликована либо как INSERT, либо как UPDATE, либо не будет опубликована вовсе.

Для команды MERGE публикация будет выдавать INSERT, UPDATE или DELETE для каждой вставляемой, изменяемой или удаляемой строки.

Присоединение (ATTACH) таблицы к дереву секционирования, корень которого включён в публикацию со свойством параметра publish_via_partition_root равным true, не приводит к репликации существующего содержимого таблицы.

Команды COPY ... FROM публикуются в виде операций INSERT.

Операции DDL не публикуются.

Выражение предложения WHERE вычисляется от имени роли, используемой для подключения репликации.

Примеры

Создание публикации, охватывающей изменения в двух таблицах:

CREATE PUBLICATION mypublication FOR TABLE users, departments;

Создание публикации, охватывающей все изменения, которые относятся к действующим отделам:

CREATE PUBLICATION active_departments FOR TABLE departments WHERE (active IS TRUE);

Создание публикации, охватывающей все изменения во всех таблицах:

CREATE PUBLICATION alltables FOR ALL TABLES;

Создание публикации, охватывающей только операции INSERT в одной таблице:

CREATE PUBLICATION insert_only FOR TABLE mydata
    WITH (publish = 'insert');

Создание публикации, охватывающей все изменения в таблицах users, departments и все изменения во всех таблицах, присутствующих в схеме production:

CREATE PUBLICATION production_publication FOR TABLE users, departments, TABLES IN SCHEMA production;

Создание публикации, охватывающей все изменения во всех таблицах, присутствующих в схемах marketing и sales:

CREATE PUBLICATION sales_publication FOR TABLES IN SCHEMA marketing, sales;

Создание публикации, которая охватывает все изменения для таблицы users, но реплицирует только столбцы user_id и firstname:

CREATE PUBLICATION users_filtered FOR TABLE users (user_id, firstname);

Совместимость

CREATE PUBLICATION является расширением PostgreSQL.