Ошибка PostgreSQL: отмена инструкции из-за конфликта с восстановлением



Я получаю следующую ошибку при выполнении запроса на БД PostgreSQL в режиме ожидания. Запрос, который вызывает ошибку, отлично работает в течение 1 месяца, но при запросе более 1 месяца возникает ошибка.



ERROR: canceling statement due to conflict with recovery
Detail: User query might have needed to see row versions that must be removed


любые предложения о том, как решить? Спасибо

3266   5  

5 ответов:

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

более длинные запросы будут отменены чаще.

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

более подробно на эту тему и другие обходные пути объясняются в Hot Standby - Обработка Конфликтов Запросов раздел в документации.

нет необходимости запускать неработающие транзакции на главном устройстве. В postgresql-9.1 самый прямой способ решить эту проблему-установить

hot_standby_feedback = on

Это позволит мастеру знать о длительных запросах. Из docs:

первый вариант-установить параметр hot_standby_feedback, который предотвращает Вакуум от удаления недавно мертвых строк и поэтому конфликтов очистки не происходит.

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

как заявил здесь о hot_standby_feedback = on:

Ну, недостатком его является то, что в режиме ожидания можно наворотить мастер, что может быть удивительно для некоторых людей, слишком

и здесь:

С какой настройкой max_standby_streaming_delay? Я бы предпочел по умолчанию это -1, чем по умолчанию hot_standby_feedback on. Таким образом, что вы делаете в режиме ожидания влияет только на в режиме ожидания


поэтому я добавил

max_standby_streaming_delay = -1

и не более pg_dump ошибка для нас, ни мастер раздувать :)

для экземпляра AWS RDS проверьте http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.html

не нужно трогать hot_standby_feedback. Как уже упоминали другие, установив его в on можно наворотить мастер. Представьте, что вы открываете транзакцию на ведомом устройстве, а не закрываете ее.

вместо этого установите max_standby_archive_delay и max_standby_streaming_delay к некоторому вменяемому значению:

# /etc/postgresql/10/main/postgresql.conf on a slave
max_standby_archive_delay = 900s
max_standby_streaming_delay = 900s

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

табличные данные на ведомом сервере горячего резервирования изменяются во время выполнения длительного запроса. Решение (PostgreSQL 9.1+), чтобы убедиться, что данные таблицы не изменяются, заключается в приостановке репликации и возобновлении после запроса:

select pg_xlog_replay_pause(); -- suspend
select * from foo; -- your query
select pg_xlog_replay_resume(); --resume

Comments

    Ничего не найдено.