После обновления PostgreSQL 17 до PostgreSQL 18 наш потребитель логической репликации перестает обновляться confirmed_flush_lsn в слоте репликации, когда рабочая нагрузка состоит в основном из пустых транзакций (транзакций, которые касаются только таблиц, не включенных в публикацию).
В PostgreSQL 17 это работает правильно.
Справочная информация
Мы используем специальный компонент Spring Boot, который считывает данные из логического слота репликации с помощью JDBC PGReplicationStream API с pgoutput плагин.
Компонент обнаруживает пустые транзакции, подсчитывая сообщения DML между TxBeginEvent и TxCommitEvent. Когда txMsgsCnt == 0 при фиксации он сбрасывает LSN слота вперед.
Упрощенная логика:
private void handleTxCommit(TxCommitEvent event) {
if (txMsgsCnt == 0 && flushOnEmptyTransactions) {
doFlush(); // advance confirmed_flush_lsn
}
}
Вызовы сброса:
stream.setAppliedLSN(lsn);
stream.setFlushedLSN(lsn);
stream.forceUpdateStatus();
Есть ли другой рекомендуемый подход к продвижению confirmed_flush_lsn когда нет опубликованных изменений?
Среда
- PostgreSQL 18.2 (Debian 18.2-1.pgdg12+1)
- Драйвер PostgreSQL JDBC 42.7.x
- pgoutput плагин, proto_version=4
- Java 17, Spring Boot 2.4.13
Параметры yml:
stream:
skip-commits: []
replication-slot-name: repslot_test
read-slot-timeout-ms: -1
flush-messages-size: 100
flush-on-empty-transactions: true
flush-on-commit: true
take-snapshot: false
decoding-plugin: PGOUTPUT
heart-beat-timeout-ms: 5000
status-interval-sec: 0
slot-options:
proto_version: 4
publication_names: test_publication
max-retries: 100
back-off-period: 500
ccl-enabled: true