[Документация Yandex Cloud](../../index.md) > [Yandex Managed Service for PostgreSQL](../index.md) > [Концепции](index.md) > Репликация

# Репликация в Managed Service for PostgreSQL

В кластерах Managed Service for PostgreSQL используется _кворумная репликация_ (quorum-based synchronous replication):

1. Среди хостов кластера выбирается мастер, а все остальные хосты становятся репликами.
1. Транзакция считается успешной только в том случае, если ее подтвердили хост-мастер и кворум реплик. Кворум составляет половина всех реплик кластера. Реплики для кворума выбираются случайным образом (_кворумные реплики_).

    Если количество реплик нечетное, значение округляется вниз, кроме случая с одной репликой. Например, в кластере с 17 репликами для формирования кворума необходимы 8, а в кластере с одной репликой — 1.

{% note warning %}

Реплики, для которых [вручную задан источник репликации](#replication-manual), не могут становиться мастером или участвовать в кворуме.

{% endnote %}

Количество кворумных реплик обновляется при любом изменении количества доступных хостов кластера, например, [добавлении](../operations/hosts.md#add) и [удалении](../operations/hosts.md#remove) хостов, плановом или внеплановом обслуживании. Добавленный в кластер хост сначала синхронизируется с мастером и только потом может участвовать в кворуме.

Подробнее о том, как организована репликация в PostgreSQL, читайте в [документации СУБД](https://www.postgresql.org/docs/current/static/warm-standby.html).

## Управление репликацией {#replication}

Для обеспечения сохранности данных в кластере реализовано автоматическое управление репликацией — каждый хост-реплика получает поток репликации от хоста-мастера. При необходимости источник репликации можно [указать вручную](../operations/hosts.md#update).

В кластере допустимо комбинировать автоматическое и ручное управление потоками репликации.

### Автоматическое управление потоками репликации {#replication-auto}

После создания кластера PostgreSQL из нескольких хостов в нем находятся один хост-мастер и реплики. Реплики используют хост-мастер в качестве источника репликации.

Особенности автоматической репликации в Managed Service for PostgreSQL:

* При выходе из строя хоста-мастера наименее отстающая реплика становится новым мастером.
* При смене мастера источник репликации для всех хостов-реплик автоматически переключается на новый хост-мастер.

### Ручное управление потоками репликации {#replication-manual}

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

Таким образом, в кластере PostgreSQL со сложной топологией можно настроить _каскадную репликацию_, при которой часть реплик использует другие хосты кластера в качестве источника потока репликации. Управление потоком репликации для таких хостов-источников может осуществляться как автоматически средствами Managed Service for PostgreSQL, так и вручную.

{% note warning %}

Реплики, для которых вручную установлен источник репликации, не могут:

* Становиться мастером при автоматической или [ручной смене хоста-мастера](../operations/update.md#start-manual-failover).
* Участвовать в кворумной репликации.
* Выбираться как наименее отстающие при использовании [особого FQDN](../operations/connect/fqdn.md#fqdn-replica).

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

{% endnote %}

## Синхронность записи и консистентность чтения {#write-sync-and-read-consistency}

За синхронизацию записи данных в PostgreSQL отвечает [параметр](settings-list.md#setting-synchronous-commit) `synchronous_commit`, управляющий синхронностью передачи WAL (Write-Ahead Log) — [журнала опережающей записи](https://www.postgresql.org/docs/current/wal-intro.html). По умолчанию установлено значение `synchronous_commit = on`. В этом случае транзакция подтверждается, только если WAL записан и на диск мастера, и на диск каждой кворумной реплики.

В зависимости от количества реплик в кластере возможны следующие варианты поведения:

* В кластере с одной репликой кворум состоит только из нее, а ручное управление потоками репликации недоступно. Если реплика выйдет из строя, транзакции на запись будут ожидать подтверждения до ее возвращения в кластер.
* В кластере с двумя репликами транзакция подтверждается, когда WAL записан на диск кворумной реплики. При выходе ее из строя кворум будет составлен из оставшейся реплики, если у нее не указан источник репликации. В таком случае никаких изменений в результатах запросов к хосту-мастеру не произойдет.
* В кластере с нечетным количеством реплик `N > 1` кворум состоит из `N-1 / 2` реплик. Для остальных реплик можно настроить источник репликации вручную.
* В кластере с четным количеством реплик `N > 2` кворум состоит из `N / 2` реплик. Для остальных реплик можно настроить источник репликации вручную.

Чтобы гарантировать постоянную консистентность чтения данных между мастером и кворумной репликой, [в настройках кластера](../operations/update.md#change-postgresql-config) задайте значение `synchronous_commit = remote_apply`. При таком значении запись не считается успешной, пока кворумная реплика не применит изменения из WAL. В этом случае операция чтения, выполненная на мастере и на этой реплике, всегда возвращает один и тот же результат.

Недостаток этого решения — операции записи в кластер будут занимать больше времени. Если мастер и кворумная реплика расположены в разных [зонах доступности](../../overview/concepts/geo-scope.md), то задержка подтверждения транзакции (latency) будет не меньше, чем время передачи данных туда и обратно (Round-Trip Time, RTT) между дата-центрами. Это снизит производительность кластера при записи в один поток и при включенном режиме `AUTOCOMMIT`.

Для повышения производительности ведите запись в несколько потоков, где это возможно, а также [отключите `AUTOCOMMIT`](https://www.postgresql.org/docs/current/ecpg-sql-set-autocommit.html) и группируйте запросы в транзакции.

## Логическое декодирование {#logical-decoding}

Кластер Managed Service for PostgreSQL поддерживает [логическое декодирование](https://www.postgresql.org/docs/current/logicaldecoding.html), которое позволяет передавать во внешние сервисы информацию об изменениях в базе данных. В частности, оно используется для [захвата изменения данных (CDC)](../../data-transfer/concepts/cdc.md).

Информация об изменениях в базе данных в формате WAL передается в [слот репликации](https://www.postgresql.org/docs/current/logicaldecoding-explanation.html), который преобразует ее в понятный внешнему сервису формат с помощью [выходного плагина](https://www.postgresql.org/docs/current/logicaldecoding-output-plugin.html).

Managed Service for PostgreSQL поддерживает следующие плагины WAL:

* [test_decoding](https://www.postgresql.org/docs/current/test-decoding.html) — преобразует данные из WAL в текстовое представление.
* [wal2json](https://github.com/eulerto/wal2json) — преобразует данные из WAL в JSON-представление.
* [pgoutput](https://www.npgsql.org/doc/replication.html#logical-streaming-replication-protocol-pgoutput-plugin) — преобразует данные из WAL в [формат протокола логической репликации](https://www.postgresql.org/docs/current/protocol-logicalrep-message-formats.html).

[Создавать](../operations/replication-slots.md#create) слоты репликации могут пользователи с [ролью `mdb_replication`](roles.md#mdb-replication).

## Примеры использования {#examples}

* [Миграция базы данных из стороннего кластера PostgreSQL в Managed Service for PostgreSQL](../tutorials/data-migration.md)
* [Миграция данных из Yandex Managed Service for MySQL® в Managed Service for PostgreSQL с помощью Yandex Data Transfer](../tutorials/mmy-to-mpg.md)
* [Миграция данных из Managed Service for PostgreSQL в Yandex Managed Service for MySQL® с помощью Yandex Data Transfer](../tutorials/mpg-to-mmy.md)
* [Миграция базы данных из Managed Service for PostgreSQL](../tutorials/outbound-replication.md)
* [Асинхронная репликация данных из PostgreSQL в ClickHouse®](../tutorials/rdbms-to-clickhouse.md)