Рассмотрим способы посмотреть текущие активности, другими словами процессы и их деятельность на сервере PostgreSQL.

Что в этой статье будет рассмотрено:

  • Вы можете посмотреть на текущие активности сервера PostgreSQL с помощью представления pg_stat_activity.
  • Чтобы завершить один из обслуживающих процессов нужно использовать функцию pg_terminate_backend(<pid>).
  • Вы можете, с помощью функции pg_blocking_pids(<pid>), посмотреть кого ожидает процесс с этим pid.

Все эти действия можно выполнить с помощью инструментов командной строки операционной системы:

  • посмотреть процессы с помощью команды ps;
  • завершить процесс с помощью команды kill -9 <pid>.

Но операционная система не сможет определить чем занят процесс postgress, поэтому ps не будет столь-же информативен, как представление pg_stat_activity.

Как вы помните при работе сервера PostgreSQL работает 1 главный процесс, который запускает остальные и следит за ними. При падении одного из процессов postgres, например когда мы его завершили командой kill -9 <pid> , главный процесс postgres может решить что в базе данных случилась ошибка и перезапустит весь кластер. Поэтому завершать процессы лучше средствами PostgreSQL, с помощью функции pg_terminate_backend(<pid>).

Практика

Создадим таблицу и вставим в неё одно значение, равное 42:

postgres@s-pg13:~$ psql -d admin_monitoring
Timing is on.
psql (13.3)
Type "help" for help.

postgres@admin_monitoring=# CREATE TABLE t(n integer);
CREATE TABLE
Time: 2,281 ms

postgres@admin_monitoring=# INSERT INTO t VALUES(42);
INSERT 0 1
Time: 0,713 ms

Затем заблокируем эту таблицу выполняя в ней транзакцию:

postgres@admin_monitoring=# BEGIN;
BEGIN
Time: 0,076 ms

postgres@admin_monitoring=# UPDATE t SET n = n + 1;
UPDATE 1
Time: 0,422 ms

Запустим второй сеанс и подключимся к той-же самой базе данных. Затем попробуем поменять значение в заблокированной таблице:

postgres@s-pg13:~$ psql -d admin_monitoring
Timing is on.
psql (13.3)
Type "help" for help.

postgres@admin_monitoring=# UPDATE t SET n = n + 2;

Второй сеанс при этом завис!

Запускаем третий сеанс, в котором будем разбираться кто кого заблокировал. Подключаемся к базе postgres и выполняем:

postgres@s-pg13:~$ psql
Timing is on.
psql (13.3)
Type "help" for help.

postgres@postgres=# SELECT pid, query, state, wait_event, wait_event_type, pg_blocking_pids(pid) FROM pg_stat_activity WHERE backend_type = 'client backend' \gx
-[ RECORD 1 ]----+------------------------------------------------------------------------------------------------------------------------------------------
pid              | 15360
query            | UPDATE t SET n = n + 1;
state            | idle in transaction
wait_event       | ClientRead
wait_event_type  | Client
pg_blocking_pids | {}
-[ RECORD 2 ]----+------------------------------------------------------------------------------------------------------------------------------------------
pid              | 15396
query            | UPDATE t SET n = n + 2;
state            | active
wait_event       | transactionid
wait_event_type  | Lock
pg_blocking_pids | {15360}
-[ RECORD 3 ]----+------------------------------------------------------------------------------------------------------------------------------------------
pid              | 15412
query            | SELECT pid, query, state, wait_event, wait_event_type, pg_blocking_pids(pid) FROM pg_stat_activity WHERE backend_type = 'client backend'
state            | active
wait_event       |
wait_event_type  |
pg_blocking_pids | {}

Time: 5,000 ms

В запросе мы получали следующую информацию:

  • pid — идентификаторе процесса;
  • query — текст запроса;
  • state — состояние процесса;
  • wait_event — чего этот процесс ожидает;
  • wait_event_type — тип ожидания;
  • pg_blocking_pids(pid) — с помощью этой функции, посмотрим pid процесса которого ожидает этот процесс.

Состояние idle in transaction означает, что сеанс начал транзакцию, но в настоящее время ничего не делает, а транзакция осталась незавершенной. Это может стать проблемой, если ситуация возникает систематически, например, из-за некорректной реализации приложения или из-за ошибок в драйвере — поскольку открытый сеанс расходует оперативную память.

В конфигурации сервера есть параметр:

  • idle_in_transaction_session_timeout — принудительно завершает сеансы, в которых транзакция простаивает больше указанного времени.

Теперь завершим зависший процесс вручную:

postgres@postgres=# SELECT pg_terminate_backend(15360);
 pg_terminate_backend
----------------------
 t
(1 row)

Time: 0,300 ms

После этого второй терминал должен отвиснуть и запрос выполится:

postgres@admin_monitoring=# UPDATE t SET n = n + 2;
UPDATE 1
Time: 204915,650 ms (03:24,916)

Дальше посмотрим некоторую информацию по всем процессам (фоновым и обслуживающим) которые есть в этом представлении:

postgres@postgres=# SELECT pid, backend_type, backend_start, state FROM pg_stat_activity;
  pid  |         backend_type         |         backend_start         | state
-------+------------------------------+-------------------------------+--------
 29397 | logical replication launcher | 2021-06-25 15:32:38.013169+03 |
 29395 | autovacuum launcher          | 2021-06-25 15:32:38.014063+03 |
 15396 | client backend               | 2021-06-28 16:46:15.1184+03   | idle
 15412 | client backend               | 2021-06-28 16:47:10.278381+03 | active
 29393 | background writer            | 2021-06-25 15:32:38.014382+03 |
 29392 | checkpointer                 | 2021-06-25 15:32:38.014499+03 |
 29394 | walwriter                    | 2021-06-25 15:32:38.014213+03 |
(7 rows)

Time: 0,651 ms

Сравним с выводом команды операционной системы ps:

postgres@postgres=# \q

postgres@s-pg13:~$ ps -o pid,command --ppid `head -n 1 $PGDATA/postmaster.pid`
  PID COMMAND
15396 postgres: postgres admin_monitoring [local] idle
29392 postgres: checkpointer
29393 postgres: background writer
29394 postgres: walwriter
29395 postgres: autovacuum launcher
29396 postgres: stats collector
29397 postgres: logical replication launcher

Можно заметить, что в представлении pg_stat_activity нет процесса stats collector.


Сводка
Текущие активности в PostgreSQL
Имя статьи
Текущие активности в PostgreSQL
Описание
В этой статье рассмотрим способы посмотреть текущие активности, другими словами процессы и их деятельность на сервере PostgreSQL

2 Replies to “Текущие активности в PostgreSQL”

    1. Команда SELECT это команда SQL, а не postgresql, поэтому она есть в любых версиях Postgresql. Возможно в версии postgresql 9.6 нет каких-то представлений или в представлениях нет каких-то столбцов (которые я использовал), и поэтому у вас что-то не получается.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *