Как ограничить размер WAL при использовании слота Postgres Logical Replication? - PullRequest
0 голосов
/ 04 марта 2020

Я создаю слот репликации и транслирую изменения с AWS Postgres RDS на java процесс через драйвер JDB C.

Мой код создания слота репликации выглядит следующим образом.

final ReplicationSlotInfo replicationSlotInfo = pgConnection.getReplicationAPI()
                    .createReplicationSlot()
                    .logical()
                    .withSlotName(replicationSlotName)
                    .withOutputPlugin("wal2json")
                    .make();

и я получаю поток репликации, используя следующий код.

pgConnection.getReplicationAPI()
                .replicationStream()
                .logical()
                .withSlotName(replicationSlotName)
                .withSlotOption("include-xids", true)
                .withSlotOption("include-timestamp", true)
                .withSlotOption("pretty-print", false)
                .withSlotOption("add-tables", "public.users")
                .withStatusInterval(10, TimeUnit.SECONDS)
                .start()

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

SELECT
    slot_name,
    pg_size_pretty(pg_xlog_location_diff(pg_current_xlog_location(), restart_lsn)) AS replicationSlotLag,
    active
FROM
    pg_replication_slots;

Вывод:

slot_name   replicationslotlag  active
data_stream_slot    100 GB  f

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

Я думал, что wal_keep_segments позаботится об этом, который был установлен на 32. Но это не сработало. Есть ли какое-либо другое свойство, которое мне нужно установить, чтобы избежать этой ситуации, даже если Java Процесс репликации не запущен.

Ответы [ 3 ]

1 голос
/ 04 марта 2020

wal_keep_segments не имеет значения для логического декодирования.

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

Именно поэтому ваш каталог WAL увеличивается, если вы не используете изменения.

wal_keep_segments указывает минимальное количество старых сегментов WAL для сохранения. Он используется для таких целей, как потоковая репликация, pg_receivewal или pg_rewind.

0 голосов
/ 04 марта 2020

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

Тем временем, все, что вы можете сделать, это отслеживать ситуацию, а затем опустить слот, если он запускается. отставать слишком далеко. Конечно, это означает, что у вас будет проблема с восстановлением синхронизации позже, но нет никакого способа обойти это (кроме исправления того, что вызывает процесс репликации на go удалении и / или отставании).

Поскольку вы говорите, что процесс java не запущен, удалить слот легко. Если бы он работал, но просто не успевал, то вам нужно было бы исполнить грустный маленький танец, где вы убили отправителя wal, а затем попытались бы сбросить слот до его перезапуска (и я не знаю, как вы это делаете на RDS)

wal_keep_segments применимо только к физической репликации, не логично. И это для использования вместо слотов, а не в дополнение к ним. Если у вас есть оба, то WAL сохраняется до тех пор, пока оба критерия не будут выполнены. Действительно, это проблема, с которой вы сталкиваетесь; Логическая репликация не может быть выполнена без использования слотов, как физическая репликация.

0 голосов
/ 04 марта 2020

wal_keep_segments указывает минимум количество сегментов PostgreSQL должно храниться в каталоге pg_xlog. Может быть несколько причин, по которым PostgreSQL не удаляет сегменты:

  1. В расположении WAL, более старом, чем файлы WAL, имеется слот репликации, его можно проверить с помощью этого запроса:
SELECT slot_name,
       lpad((pg_control_checkpoint()).timeline_id::text, 8, '0') ||
       lpad(split_part(restart_lsn::text, '/', 1), 8, '0') ||
       lpad(substr(split_part(restart_lsn::text, '/', 2), 1, 2), 8, '0')
       AS wal_file
FROM pg_replication_slots;

Архивирование WAL включено, а archive_command не удается. Пожалуйста, проверьте PostgreSQL журналы в этом случае.

Долгое время не было контрольной точки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...