Ошибка 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
любые предложения о том, как решить? Спасибо
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