Как стать автором
Обновить

Комментарии 17

НЛО прилетело и опубликовало эту надпись здесь

Дык это уже давно реализовано (например, Максимом Богуком). Но вот именно в ядре такого нет.

НЛО прилетело и опубликовало эту надпись здесь

Это работает HOT, пытаясь удержать обновления в пределах той же страницы.
Думаю, что инструмент использует не SQL UPDATE, а что-то более низкоуровневое. Я не смотрел, но пожалуй надо будет разобраться.

НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Ну, придумать-то много чего можно. Самая проблема — убедить сообщество в том, что это действительно так необходимо и что у решения нет неприятных побочных эффектов.
Сейчас все очарованы магией подключаемых движков хранения. Вот у zheap нет проблем с разрастанием (правда, наверняка есть много других, но это другое дело).

Егор, большое спасибо за очередную отличную статью! Вопросы :)

Поэтому в PostgreSQL плохо сочетаются OLTP- и OLAP-нагрузка в одной базе: отчеты, выполняющиеся часами, не дадут часто обновляемым таблицам вовремя очищаться. Возможным решением может быть создание отдельной «отчетной» реплики.


Но при этом физически они выглядят одинаково. Пусть на мастере совершилась очистка а на реплике идет отчетная транзакция, которая завершится через пару часов условно.

WAL sender отправляет сегмент, где страницы уже очищены. Реплика не будет его накатывать, пока транзакция не завершится? И все остальные сегменты тоже выстроятся в очередь.

Если так то отчетная реплика может существенно отставать от мастера

Владимир, спасибо.
Да, идея именно такая. Реплика будет отставать. Но для отчетов, которые выполняются часами, пара часов отставания обычно не страшна.
Ведь даже если запустить такой отчет на мастере, за пару часов его работы многое может измениться, но эти изменения в отчет не попадут, потому что — согласованность.

Будет ли мастер хранить сегмент WAL в этом случае до тех пор, пока реплика его себе не накатит?

Получается затятная ситуация:
* Очень длинные отчеты нагружают мастер. Только ли тем, что нужно хранить сегменты WAL? Не страдает ли от этого VACUUM, table bloat? Так ли критично то, что сегменты хранятся полдня? Но задержки такие идут скажем на постоянной основе.
* Очень длинные отчеты конкурируют между собой. Если один аналитик запустил отчет на полдня, то другие должны учитывать, что не могут получить актуальные данные в этот период.

Тогда получается, что нужно делать даже 2 реплики — одну для очень долгих отчетов, другую — для отчетов но покороче.
Будет ли мастер хранить сегмент WAL в этом случае до тех пор, пока реплика его себе не накатит?

Нет, хранить будет реплика.


Очень длинные отчеты нагружают мастер. Только ли тем, что нужно хранить сегменты WAL? Не страдает ли от этого VACUUM, table bloat? Так ли критично то, что сегменты хранятся полдня? Но задержки такие идут скажем на постоянной основе.

Если отчёты работают на мастере, то WAL избыточно хранить не надо. Проблема будет только в откладывании очистки и распухании таблиц.


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

Это мы уже про реплику говорим, правильно?
Сами по себе отчёты (=запросы) конкурировать не должны, они выполняются одновременно. При этом реплика может откладывать применение журнальных записей (обычно связанных с очисткой), которые несовместимы с запросами. Ну да, будет отставание. Его можно мониторить.


Тогда получается, что нужно делать даже 2 реплики — одну для очень долгих отчетов, другую — для отчетов но покороче.

Это, мне кажется, перебор, слишком сложно. Короткие отчёты и на мастере никому сильно не помешают.


Я вообще про репликацию думаю отдельную серию написать. Там очень много разных вариантов, можно по-разному настраивать в зависимости от задачи.

Я немного расплывчато сформулировал кейс. Он такой:
* Пусть решили сделать «отчетную» реплику по просьбе аналитиков (и чтобы они нам не грузили мастер).
* Создали отдельного читающего юзера для всех аналитиков, поставили уровень изоляции Repeatable Read для согласованности, раздали логин-пароль (один на всех)
* Аналитики начали экспериментировать, строить свои отчеты.
* И вот аналитик Вася запускает отчет на таблице orders, длительность которого 3 часа.
* Реплика начала отставать все больше и больше с каждым часом, потому что запрос Васи затронул очень много данных в таблице orders.
* Вася не подозревал что получится такой долгий запрос и терпеливо решил подождать.
* Аналитик Петя решил посмотреть данные за последний час, он предполагает что данные актуальны и не знает о запросе Васи.
* Аналитик Петя строит аггрегаты, получает результат, не подозревая, что он пользуется устаревшими данными.
* И не дай бог это некий отчет, который будет использоваться при финансовых расчетах.

Если я все правильно понял, такая ситуация вполне имеет место быть.

Получается, что придется делать вот такое:
* Мониторим отставание (само собой)
* Учим аналитиков как смотреть свежесть данных, выводим им где-то например текущее оставание реплики в админке
* Учим аналитиков смотреть текущие транзакции, помогаем отследить «ждунов» — запускающих слишком длинные транзакции без согласования с остальными.
* Бедным аналитикам приходится кооперироваться между собой в чатиках, составлять расписания «длинных выгрузок» и т.п.

Очень неудобно. Как вариант можно сделать «отчетную реплику для коротких запросов» и «отчетную тормозящую реплику» для длинных. И даже может «финансовую реплику» куда ходить будут строго по расписанию.

Как Вам такая идея? Может есть идея получше? Кейс очень актуальный.

Сорри, что немного не в тему статьи
Реплика начала отставать все больше и больше с каждым часом, потому что запрос Васи затронул очень много данных в таблице orders.

Тут логическая ошибка. Реплика будет отставать не из-за того, что кто-то затронул какие-то данные. У запросов на реплике есть обычные снимки, вот они и используются, чтобы понять, конфликтует журнальная запись или нет. Так же, как на мастере.


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

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


Ну а так в целом да, всё так. Но ещё раз скажу, что схема с двумя репликами для разных отчетов кажется мне слишком сложной. Не очень длинное и требующее актуальных данных — на мастер, остальное — на реплику.


Да, ещё можно настроить max_standby_streaming_delay так, чтобы конфликтующие записи применялись, но с задержкой. Тогда реплика будет отставать не больше, чем на это значение, а у более долгих запросов будет шанс доработать, если они не «наступят» на отсутствующие данные.

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


О команде CLUSTER очень часто упоминают и постоянно критикуют ее за то, что ее эффект «выдыхается» (в силу MVCC) и за то, что она блокирует все.

Когда все-таки ее целесообразно использовать?

Скажу честно — не знаю, есть ли реальные примеры успешного применения. Мне не попадались.

(Единственно исключение составляют полностью очищенные страницы, находящиеся в конце файла — такие страницы «откусываются» от файла и возвращаются операционной системе.)

Для тех кому интересно как это работает есть статья
postgreshelp.com/postgresql-vacuum-conflicts
Зарегистрируйтесь на Хабре , чтобы оставить комментарий