Поведение логической репликации при failover на synchronous standby
Логическая реплкация может обгонять synchronous standby, так как информация о завершенных транзакциях берется из локальных WAL-файлов, и, по умолчанию, не учитывается факт доставки этой информации на synchronous standby.
Поэтому в случае аварийного failover на приемнике логической репликации могут оказаться данные (транзакции), которых нет на synchronous standby (новый мастер), на который произошел failover.
Начиная с 7-й версии, в Pangolin реализован механизм «Logical Replication Failover» (отказоустойчивость логической репликации). Он гарантирует, что приемник логической репликации не получит данные, которые еще не были доставлены на synchronous standby. Это исключает риск возникновения расхождений в данных между новым мастером и приемником после переключения».
Более подробную информацию об этом механизме и о том как его настроить можно найти по следующим ссылкам: Logical Replication Failover, Replication Slot Synchronization.
В момент проведения failover, характерным случаем является возникновение на стороне пользовательских автоматизированных систем предупреждения типа:
"WARNING: canceling wait for synchronous replication due to user request
DETAILS: The transaction has already committed locally, but might not have been replicated to the standby."
Это предупреждение/поведение является стандартным поведением PostgreSQL при synchronous_commit = on и наличии имен серверов в synchronous_standby_names, которые все недоступны для получения WAL.
Это поведение обусловлено описанным в документации алгоритмом работы доставки WAL изменений на synchronous standby.
Соответственно, предупреждение:
"WARNING: canceling wait for synchronous replication due to user request
DETAILS: The transaction has already committed locally, but might not have been replicated to the standby."
Может преимущественно возникать в следующих условиях:
synchronous_commit = onи все сервера изsynchronous_standby_namesнедоступны, при этом приложение самостоятельно прервало транзакцию и получило предупреждение;- произошел сбой и выполняется failover на резервный сервер, в ходе которого текущий основной сервер аварийно останавливается.
Чтобы не потерять или не задублировать данные в подобной ситуации, нужно чтобы приложение самостоятельно обрабатывало данное предупреждение за счет логики встроенной в код приложения. То есть, разработчики приложения, зная архитектуру системы, должны предусмотреть в коде приложения компенсационные алгоритмы, в том числе с учетом используемых приложением систем репликации (handle collisions и тому подобных).
Так же чтобы значительно уменьшить возможность задержки commit при synchronous_commit = on и потери данных в случае сбоев компьютерных систем, рекомендуется иметь две синхронных реплики и настройки вида: synchronous_standby_names = 'ANY 1 ( standby_name1, standby_name1 )' (информация о фиксации транзакции передается клиенту, если WAL-записи реплицированы хотя бы на один из резервных синхронных серверов).