Добавил:
ИВТ (советую зайти в "Несортированное")rnПИН МАГА Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Database 2024 / Books / Мониторинг PostgreSQL.pdf
Скачиваний:
13
Добавлен:
20.11.2024
Размер:
6.87 Mб
Скачать

58

Глава 2. Статистика активности

пытаться открыть новые соединения, что может привести к росту очереди ожидающих и достижению ограничения на одновременно разрешенные подключения. При достижении этого ограничения приложение не сможет подключиться к БД, что приведет к невозможности работы и приложения,и СУБД,и других приложений,которые также хотели бы установить соединение с СУБД.

Таким образом, состояние idle in transaction является потенциально опасным, и долгое пребывание процессов в этом состоянии может привести к негативным последствиям. Такие транзакции нужно отслеживать и устранять. В тактическом плане такие транзакции можно завершать автоматически через включение тайм-аута idle_in_transaction_session_timeout в настройках СУБД. Эту настройку можно сделать как глобально, на уровне общей конфигурации СУБД,такииндивидуально,науровнеотдельныхпользователейилибазданных.Другимвариантом может быть периодический запуск скриптов на основе функции pg_terminate_backend средствами утилиты cron. Такое решение может быть предпочтительным в случае, когда возможностейidle_in_transaction_session_timeout недостаточноитребуетсяболеетонкаянастройка тайм-аутов.Пример использования связки pg_terminate_backend и pg_stat_activity:

#SELECT pg_terminate_backend(pid) FROM pg_stat_activity

WHERE usename = 'pgbench' AND application_name = 'pgbench'

AND clock_timestamp() - coalesce(xact_start, query_start) > '00:01:00'::interval AND state ~ 'idle in transaction';

Такой запрос достаточно вызвать из psql.При необходимости список полей в SELECT или условия можно переопределить,а вывод результата сохранять,например,для анализа.

clock_timestamp vs now

Для определения длительности обычно принято вычитать отметку времени из текущего времени.В любой СУБД есть функция,которая выводиттекущее время.В PostgreSQLтакой функцией является хорошо известная now,однако ее особенностью является то,что она показывает время начала транзакции. Попробуйте вызвать now в транзакции несколько раз. Для целей же мониторинга рекомендуется использовать clock_timestamp, которая всегда показываеттекущую отметку времени.

2.6. Время выполнения запросов и транзакций

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

2.6. Время выполнения запросов и транзакций

59

можно сфокусироваться на отдельных единицах выполнения —транзакциях и запросах, и отслеживать появление продолжительных запросов и транзакций, нехарактерных для этой рабочей нагрузки. Оптимизация времени выполнения положительно сказывается на производительности независимо от типа рабочей нагрузки. Неважно, OLTP, OLAP или HTAP, оптимизация всегда направлена на сокращение времени выполнения запросов и уменьшение объема ресурсов,необходимыхдля их выполнения.Время выполнения запросов зависитоттаких факторов, как количество требуемых ресурсов, доступные СУБД ресурсы, сложность запроса, его параметры и план выполнения и т. п. Долгое выполнение команд может указывать на самые разные проблемы. Например, выбор планировщиком неэффективного плана может выражаться в долгом выполнении и избыточном использовании ресурсов. Долгие транзакции могут быть следствием плохого дизайна и проблем в управлении транзакциями на стороне приложения. С точки зрения приложений долгое выполнение операций в СУБД может приводить к тайм-аутам обработки запросов в самом приложении или эффекту зависания (если тайм-ауты не настроены), исчерпанию соединений к СУБД и аварийной остановке приложения.Врегулярныезадачиадминистраторавходитотслеживаниевременивыполнениякоманд, расследование и устранение причин долгой работы.Зачастую устранением причин DBA занимается совместно с командами разработки приложений.

Для отслеживания продолжительности выполнения команд и транзакций в pg_stat_activity есть несколько полей:

xact_start — время начала транзакции. Значение может отсутствовать (NULL), если в данный момент нет активной транзакции или в транзакции произошла ошибка и при этом транзакция не была закрыта,—состояние idle in transaction (aborted);

query_start — время начала текущего запроса (состояние active) или последнего выполненного запроса в сеансе (все прочие состояния).

Для получения информации о длительности выполнения запросов и транзакций можно использоватьтакой вариант запроса:

#SELECT pid,

CASE WHEN wait_event_type = 'Lock' THEN 'waiting' ELSE state END AS state, (clock_timestamp() - xact_start) AS xact_age,

(clock_timestamp() - query_start) AS query_age

 

 

FROM pg_stat_activity

 

 

 

 

WHERE (clock_timestamp() - xact_start > '00:00:00'::interval)

 

OR (clock_timestamp() - query_start > '00:00:00'::interval

 

AND state = 'idle in transaction (aborted)')

 

 

ORDER BY coalesce(xact_start, query_start);

 

 

 

pid

|

state

|

xact_age

|

query_age

--------

+

-------------------------------

+-----------------

 

+-----------------

 

3878

|

idle in transaction (aborted) |

 

| 00:00:04.264773

242533

|

active

| 00:00:00.176216 | 00:00:00.174478

241520

|

active

| 00:00:00.150633 | 00:00:00.149281

242541

|

waiting

| 00:00:00.141747 | 00:00:00.139989

241506

|

waiting

| 00:00:00.123768 | 00:00:00.122107

241523

|

active

| 00:00:00.102864 | 00:00:00.101012

60Глава 2. Статистика активности

Вэтом запросе есть несколько особенностей,на которые стоит обратить внимание:

Дляопределениясостоянияприменяетсярасширеннаялогикасиспользованиемсобытий ожидания.Процессыстипомсобытияwait_event_type='Lock'расцениваютсякакпроцессы,ожидающие завершения конкурентных транзакций.

Условие запроса отбирает именно транзакции, а не отдельные запросы: левая часть условия OR ищет активные транзакций, правая часть — отмененные (aborted), но не закрытые транзакции. И вот почему: запросы, даже если они выполняются отдельно, вне транзакций, на самом деле также используют транзакционный механизм и, по сути, являются транзакциями,состоящимиизоднойкоманды.Втакомслучаедажедляобычныхзапросов заполняется поле xact_start (которое в этом случае равно значению query_start). Поэтому нет смысла концентрироваться на поиске запросов, они попадут в результат в любом случае.

В правом от OR условии для поиска отмененных транзакций используется поле state. Смысл его использования заключается в том, что в случае возникновения ошибки внутри транзакции значение xact_start устанавливается в NULL, но сама транзакция при этом остается открытой. Чтобы не потерять такие транзакции, следует ориентироваться на query_start—время запроса,который завершился ошибкой.

Изменяя значение в интервале, можно исключать из результата совсем короткие транзакции.

Спомощью метрики postgres_activity_max_seconds можно получить максимальную длительностьтранзакции.Метрика содержит в себе несколько меток:

user—пользователь,вызвавший активность;

database—база данных,к которой подключен клиент;

type—тип активности: пользовательский запрос или фоновое обслуживание (в случае автоочистки или сбора статистики для планировщика);

state—состояние сеанса,согласно полю state с учетом состояния waiting.

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

# max by (user) (postgres_activity_max_seconds{service_id="primary"})

На рис. 2.9 изображен пример графика на основе этого запроса. Из графика видно, что бóльшаячастьзапросовукладываетсявинтервалдо500миллисекунд.Отдельноотметилсяпроцесс автоочистки, который выполнялся на тот момент около четырех секунд. Важно отметить, что эта метрика и график на ее основе показывают не абсолютно всю активность, происходящую в СУБД,а лишьту,что была в момент опроса pg_stat_activity.

Соседние файлы в папке Books