Q:

Внезапная ошибка при обращении к реплике базы данных

У меня есть python-сервис, который обращается к реплике базы данных. При этом время от времени сервер с репликой возвращает такую ошибку:
psycopg2.extensions.TransactionRollbackError: ВАЖНО:  закрытие подключения из-за конфликта с процессом восстановления                         
DETAIL:  Запросу пользователя нужно было видеть версии строк, которые должны быть удалены.                                                    
HINT:  Вы сможете переподключиться к базе данных и повторить вашу команду сию минуту.                                                         
SSL connection has been closed unexpectedly

Интересно, что после презагрузки всех connection'ов к базе данных, проблема на некоторое время пропадает. Так же, если обращаться не к реплике, а к боевой, то проблем нет. 
Еще проблема усугубляется тем, что я использую orator-orm, который по умолчанию в таких случаях не перезагружает соединение. Таким образом, процесс остается висеть с оторванным connection.
В чем может быть причина такого поведения ?

A:

Это всё сущность MVCC в комбинации с потоковой физической репликацией изменений. Мастер знает, какие у него версии строк используются. Раз это знает мастер - это знает автовакуум, который работает тоже на мастере. Зато мастер не знает, какие версии строк требуются для обработки запросов на слейве.
В итоге мастер спокойно говорит: да, эти строки мне не нужны, их можно вычищать. Строчки вычищаются, изменения страниц попадают в WAL, уезжают на реплику, применяются. А реплика внезапно понимает, что у неё есть запрос, который хочет эти данные, а их уже поудаляли. Нельзя применить wal и продолжить выполнять запрос, только что-то одно. И всё, привет. Что ещё сделать? Подождать некоторое время, может запрос выполнится (если это разрешено настройками реплики). А если запрос не уложился в отведённое время? Остаётся только ответить клиенту, что простите, попробуйте ещё раз.
В оригинале про эту проблему написано в разделе описания репликации, подраздел Handling Query Conflicts.
Вам нужно крутить ручки:

max_standby_archive_delay и max_standby_streaming_delay на слейве - насколько выполняющийся сейчас запрос может задержать репликацию. Минус - репликация на слейве при таких запросах будет отставать от мастера. Для аналитики это ок, для OLTP может быть неприемлемо.
использовать hot_standby_feedback - слейв будет сообщать мастеру, какие версии строк ему ещё нужны и мастер не даст вакууму эти строки вычищать. Соответственно, объём базы под интенсивной записью будет распухать.
vacuum_defer_cleanup_age предписывающая мастеру задержать вакуум на столько транзакций.

