Pull to refresh

Comments 10

Егор, спасибо за отличный цикл статей. Очень ждем следующего цикла :)

Вопрос скорее не про блокировки а в целом про экосистему PostgreSQL

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


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

Я к тому, что для OLTP эта ситуация типична. Как так получилось, что в PostgreSQL до сих пор нет встроенных средств семплирования, которые позволят хоть как-то отловить подобные запросы? Либо все-таки подобные запросы не настолько сильно вредят Postgres, и поэтому семплирование неприоритетно. То есть блокировки, которые Вы предложили отловить семплированием — тоже редкий случай, не стоящий того, чтобы инструменты семплирования размещать в ядро.

Либо принципиально такие инструменты как семплирование — это не задача PostgreSQL и их некорректно встраивать. Было бы интересно услышать Ваше мнение по этому вопросу.

Владимир, спасибо. Продолжение будет, но, наверное, немного погодя.


По вопросу. Блокировки и запросы — разные штуки. Соответственно и инструменты разные. Есть два пути:


  1. Использовать стандартное расширение pg_stat_statements. Если запросы частые, они будут видны в табличке. Тут никакое семплирование не нужно.
  2. Установить log_min_duration_statement = 0 и в журнале сообщений будет полная картина происходящего, которую можно потом проанализировать pgBadger-ом, например.


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



А если говорить о блокировках, то мое мнение такое: семплирование — костыль. Встраивать его в ядро СУБД не нужно. Вместо этого ядро должно давать точную информацию о том, какие ожидания были у сеанса, сколько их было и сколько времени они заняли. Разработчики PostgreSQL этого почему-то не понимают, но мой опыт работы с Ораклом однозначно говорит о том, что это ценнейшая информация.

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


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

Кажется, что это достаточно большой и сложный модуль и возможно на его написание нет ресурсов.
Про семплирование.
В песочнице ожидает модерации статья о личном опыте решения.
Кратко — ведется история pg_stat_activity, pg_locks, pg_stat_user_tables.
История храниться не в целевой базе, а в отдельной базе мониторинга.
В результате получаемые отчеты очень помогает получать картину происходящего. Особенно по деградации отдельных запросов.

Что-то не появляется ваша статья в песочнице. Заботливые лучи НЛО не пускают или я как-то неправильно ищу?

Непонятно, как работает песочница.
С одной стороны — ожидает модерации
— Песочница
Мои публикации
rinace 10 сентября 2019 в 16:51
ASH для PostgreSQL
— С другой стороны, в песочнице, в разделе «Ожидают приглашения», я тоже статью не вижу.
Видимо сначала модерация, потом приглашение.

В двух словах идея довольно простая(ну если сильно упрощенно)
1)Создаются таблицы хранения снимков представлений pg_stat_avtivity, pg_locks (просто добавляется поле timepoint) — history_pg_stat_avtivity, history_pg_locks
2)systemd service каждую секунду сохраняет снимок представлений в таблицы history_*
2)каждый час создается новая секция archive_pg_stat_avtivity, archive_pg_locks для хранения истории
3)Для таблицы archive_pg_stat_avtivity добавлется дополнительный столбец queryid, который хранить queryid выполняемого запроса из представления pg_stat_statements

В результате можно получить информацию:
-Общее время CPU
-Общее время Waitings
-Время CPU для отдельного запроса по queryid
-Время Waitings для отдельного запроса по queryid
-Какие конкретно события ждал запрос
-Освобождения каких блокировок ждал запрос
-Какой процесс(запрос) удерживал блокировки

Смысл именно в том, что бы связать pg_stat_statement + pg_locks + pg_stat_activity

В результате получается некое подобие отделено напоминающее AWR в Oracle.

Первая статья в основном по ожиданиям, вторая будет по блокировкам, используя ваши статьи. Кстати пользуясь случаем спасибо.

Хм, так и не появилась статья. Пригласил вас так. Публикуйте, интересно почитать.
Кстати, видели https://pgconf.ru/2018/99643?

Спасибо за приглашение.
Опубликовано — habr.com/ru/post/467181
Чуть попозже подготовлю более подробные описания по шагам и скриптам. Сейчас как раз идет тестирование. Материала очень много. Может быть будет интересно кому.

Спасибо за ссылку, посмотрел, взял в коллекцию, очень интересно. Но не совсем, то, что хотелось.

А хеш-таблица, для доступа к которой нужна блокировка - это обычная хеш-таблица? Или что-то хитрое, вроде ConcurrentHashMap или чего-то такого?

Я не очень в курсе, как в Java реализованы хеш-таблицы (для буферного кеша используется динамически расширяемая таблица с разрешением коллизий с помощью цепочек), но по части конкурентного доступа - да, судя по всему, что-то похожее на ConcurrentHashMap.

Sign up to leave a comment.