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

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

Теперь взглянем на то,к каким базам данных выполнены подключения (рис. 2.4).

Рис. 2.4.Количество подключений к базам данных

Изприведенногографикастановитсяочевидным,чтопочтивсесоединенияустановленыкБД pgbench и это основная БД, на которой сосредоточена рабочая нагрузка. Совсем небольшая часть соединений установлена к БД postgres; скорее всего, эти соединения также устанавливаются экспортером метрик.

В зависимости от информативности метрик и используемых меток можно строить и другие проекции. Например, при широком использовании application_name со стороны прикладных приложений эту информацию можно также экспортировать в метках метрик и вывести соответствующий график.

Транзакционная активность

Запросы—это базовая единица рабочей нагрузки.Их можно объединятьвтранзакции,итранзакция выполняется как единое целое: ошибка даже в одном запросе воспринимается как ошибка всей транзакции целиком. Механизм транзакций устроен так, что даже один запрос, не обернутый явно в команды управления транзакциями (BEGIN и END), также является транзакцией (состоящей из одной команды).

По количеству выполняемых транзакций можно сделать выводы о том, насколько активно используется база данных. Найти необходимую информацию можно в pg_stat_database. Она включает в себя поля xact_commit и xact_rollback, которые показывают количество зафиксированных и оборванных транзакций. Сумма этих полей и показываеттранзакционную активность в базе данных:

2.4. Подключенные клиенты

45

#SELECT datname, xact_commit + xact_rollback AS xacts FROM pg_stat_database

ORDER BY xact_commit + xact_rollback DESC; datname | xacts

-----------

+

---------

pgbench

| 5786340

postgres

|

357301

template1 |

6116

 

|

13

template0 |

0

Втестовом окружении всегодве активно используемые БД: pgbench и postgres.Также естьособая строка с отсутствующим именем базы данных,которая содержит статистику общих объектов системного каталога. Следующим запросом мы можем получить данные из мониторинга:

#rate(postgres_database_xact_commits_total{service_id="primary"} + postgres_database_xact_rollbacks_total{service_id="primary"}[1m])

Запроссчитаетколичествовыполненныхтранзакцийвсекунду,наегоосновеможнополучить график (рис. 2.5), который показывает эту картину в динамике. На нем наглядно видно, что объем выполняемых транзакций в БД pgbench в несколько раз больше,чем в БД postgres.

Рис. 2.5.Транзакционная активность: количество транзакций в секунду

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

46

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

Подсчет транзакций с помощью pg_stat_statements

Информацию о транзакциях можно получить с помощью pg_stat_statements.query, отслеживая команды начала и завершения транзакций (BEGIN, COMMIT и пр.). Однако у этого способа есть несколько недостатков.Во-первых,должно быть включено отслеживание служебных команд (track_utility =on).Во-вторых,расширение регистрируеттолько прямые вызовы команды ROLLBACK, следовательно, невозможно отслеживать откаты транзакций, произошедшие из-за ошибок. В-третьих, не всегда возможно отследить начало транзакции. Например,если клиент использует \set AUTOCOMMIT off,транзакция будет открываться неявно сразу после первой выполненной команды. Поэтому учет с помощью pg_stat_statements хоть и возможен,но менее удобен.

Статусы завершения сеансов

Нормальная работа сеанса предполагает, что клиент устанавливает соединение с СУБД, отправляет запросы и, когда необходимость в подключении исчезает, закрывает соединение

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

сброс соединения клиентом,СУБД или промежуточным сетевым устройством;

возникновение ошибки в сеансе,после которой продолжение сеанса невозможно;

принудительное завершение сеанса по инициативе администратора или СУБД.

Вполне возможны и другие, более экзотические варианты развития событий, но перечисленные выше причины встречаются наиболее часто.Аварийное завершение сеанса может происходить редко и незаметно—если сеанс прервется,СУБД запишет сообщение в журнал,приложение переустановит соединение и работа продолжится. Такое бывает из-за сетевых ошибок, тайм-аутов или потерь пакетов, когда нарушается работа TCP-соединения. Но есть и другая крайность: шквал ошибок, которые невозможно не заметить или игнорировать. Обычно это результат ошибок прикладного уровня, когда завершение сеанса происходит из-за ошибки в приложении. Например, после обрыва сеанса приложение может переустанавливать соединениеивыполнятькодсошибкой,врезультатечегосеанссбрасываетсяивсеповторяетсясновабезостановки.Такоеповедениехорошоописываетсятерминомcrashloop,которыйнепонаслышкезнакомадминистраторамKubernetes.Прикоротком(миллисекунды)интервалемежду ошибками приложение может создать шторм из попыток установки соединений. В лучшем случае это приведет к увеличению нагрузки на CPU на стороне СУБД (создание клиентских процессов обходится недешево). В худшем случае при наличии нескольких экземпляров приложения,которыеведутсебяодинаково,можноисчерпатьлимитподключенийmax_connections и сделать невозможным подключение других приложений к СУБД.

Статистика по статусам сеансов находится в pg_stat_database,получить ее можно следующим образом:

2.4. Подключенные клиенты

47

#SELECT datname, sessions, sessions_abandoned, sessions_fatal, sessions_killed FROM pg_stat_database

WHERE sessions > 0;

 

 

 

 

 

 

datname

| sessions | sessions_abandoned | sessions_fatal | sessions_killed

----------

+

----------

+

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

+

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

+

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

postgres |

1154107

|

0

|

0

|

0

pgbench

|

383947

|

0

|

0

|

0

Напомню, что pg_stat_database содержит кумулятивную статистику,поэтому среди значений можно наблюдать большие числа.На что нужно обращать внимание в этой статистике,это наличие аномальных статусов: abandoned, fatal и killed. В данном примере таких сеансов не зафиксировано, и это указывает на то, что на уровне сеансов приложения работают корректно и без ошибок. В этом примере можно обратить внимание на то, что к служебной БД postgres выполненогораздобольшесоединений,чемкприкладнойБДpgbench.Спомощьюследующего PromQL-запроса можно построить график и посмотреть картину во времени:

#sum by (database) ( increase(postgres_database_sessions_total{ service_id="primary", database=~"(postgres|pgbench)" }[1m]))

В данном запросе количество сеансов, находящихся в любых статусах, суммируется по двум интересующим нас БД. Статистика является кумулятивной, и для наглядности изменений во времени стоит применить функцию increase, которая показывает изменение метрики за указанный интервал (в этом примере—одна минута).

На графике (рис. 2.6) видно, что довольно большое количество сеансов — примерно 90 в минуту — устанавливается с БД postgres. Это объясняется рабочей нагрузкой, характерной для экспортера метрик. Экспортер устанавливает несколько сеансов на время сбора статистики,

Рис. 2.6.Частота установления сеансов в минуту к базам данных

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

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

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

Запрос на получение статусов сеансов показал, что значение в sessions_abandoned составляло 13% от общего числа sessions и продолжало медленно увеличиваться. Это довольно большое значение, и я попытался выяснить причины такого количества оставленных сеансов. После отключения тестовой нагрузки счетчик продолжил расти, и подозрения упали на агента мониторинга. Эта проблема мне хорошо известна: она проявляется, если на стороне приложения не закрыть соединение должным образом.Имея доступ к исходному коду агента,я решил проверить все места,где открываются соединения.Нужно было убедиться,что соединения закрываются после использования,и я обнаружил одно из мест,где этого неделалось,что могло приводить к утечке соединений.

Для подтверждения постоянного характера проблемы я построил график (рис. 2.7) на основе следующего запроса:

#sum by (reason) (increase(postgres_database_sessions_total{ service_id="primary",database="pgbench"

}[1m]))

Рис. 2.7.Частота установления сеансов в минуту с группировкой по статусам

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