По идее пост должен быть интересен тем кому небезразлична тема мониторинга и поиска проблем в PostgreSQL системные администраторы, DBA, SRE, DBRE.
- В pg_stat_activity добавлено
новое поле query_id. Поле содержит идентификатор запроса
аналогичный тому что есть в pg_stat_statements. Таким
образом с помощью трио полей datid/userid/query_id можно
присоединить pg_stat_statements и посмотреть накопленную статистику
по конкретному типу запросов. Забавный нюанс имена полей для
объединения между pg_stat_activity и pg_stat_statements
отличаются.
Осторожно, текстselect a.*, s.* from pg_stat_activity a inner join pg_stat_statements s on (a.datid = s.dbid AND a.usesysid = s.userid AND a.query_id = s.queryid) where a.pid = 1001291;-[ RECORD 1 ]-------+-----------------------------------------------------------datid | 16413datname | pgbenchpid | 1001291leader_pid | usesysid | 10usename | postgresapplication_name | pgbenchclient_addr | client_hostname | client_port | -1backend_start | 2021-05-22 10:15:57.299468+05xact_start | 2021-05-22 10:16:25.566151+05query_start | 2021-05-22 10:16:25.566623+05state_change | 2021-05-22 10:16:25.566763+05wait_event_type | wait_event | state | idle in transactionbackend_xid | 237577backend_xmin | query_id | 2517686606037258902query | SELECT abalance FROM pgbench_accounts WHERE aid = 1715456;backend_type | client backenduserid | 10dbid | 16413toplevel | tqueryid | 2517686606037258902query | SELECT abalance FROM pgbench_accounts WHERE aid = $1plans | 0total_plan_time | 0min_plan_time | 0max_plan_time | 0mean_plan_time | 0stddev_plan_time | 0calls | 209439total_exec_time | 4251.98569499987min_exec_time | 0.005414max_exec_time | 0.435581mean_exec_time | 0.020301785698938563stddev_exec_time | 0.005889254053319066rows | 209439shared_blks_hit | 884097shared_blks_read | 0shared_blks_dirtied | 0shared_blks_written | 0local_blks_hit | 0local_blks_read | 0local_blks_dirtied | 0local_blks_written | 0temp_blks_read | 0temp_blks_written | 0blk_read_time | 0blk_write_time | 0wal_records | 149wal_fpi | 2wal_bytes | 9870
- В pg_stat_activity в списке процессов теперь также отображается
WAL archiver. Пока информации не так много, так что не особо
информативно и есть куда развиваться далее.
- В pg_stat_activity для wal sender процессов (участвуют в
репликации), в поле query отображается команда протокола
репликации. Это небольшое улучшение позволяет отслеживать команды
репликации между мастером и репликами, раньше это возможно было
только через логи с включенным параметром
log_replication_commands.
- В pg_locks добавлено поле
waitstart время с которого началось ожидание. Поле позволяет
получить время ожидания и при этом не присоединять
pg_stat_activity. С одной стороны вроде и удобно, но чтобы взять
текст запроса, все равно понадобится присоединить pg_stat_activity.
А вот для использования в качестве метрики, вполне подходит т.к. в
таком случае текст запроса может быть неинтересен.
Выглядит так# select pid,mode,now()-waitstart as wait_time from pg_locks where not granted;-[ RECORD 1 ]--------------pid | 1068094mode | ShareLockwait_time | 00:00:12.669753-[ RECORD 2 ]--------------pid | 1068093mode | ShareLockwait_time | 00:00:14.789208
- Пара групп полей в pg_stat_database. Первая
группа это session_time, active_time,
idle_in_transaction_time коротко, в этих полях посчитано
сколько времени проведено сессиями. Есть нюанс счетчики обновляются
в момент смены состояния (поле state), поэтому если сессия долгое
время находится в одном состоянии, то это время засчитается только
тогда когда оно (состояние) сменится на другое или сессия
завершится. Вторая группа полей sessions,
sessions_abandoned, sessions_fatal,
sessions_killed определяет статистику по сессиям и причинам
их завершения. Обе группы счетчиков так и просятся в графики на
мониторинг.
- Новое представление pg_stat_progress_copy. По названию
очевидно что представление показывает ход выполнения команд COPY.
Полезно за наблюдением того как 1) выполняется выгрузка и загрузка
дампов (pg_dump), 2) непосредственное выполнение команд COPY, 3)
выполнение начальной загрузки таблиц при использовании логической
репликации через публикации/подписки.
Пример копирования из файла в таблицу-[ RECORD 1 ]----+----------pid | 1068106datid | 16413datname | pgbenchrelid | 17612command | COPY FROMtype | FILEbytes_processed | 30998528bytes_total | 195764221tuples_processed | 313263tuples_excluded | 0
- Новое представление pg_stat_wal с помощью него можно
получить подробное представление об объемах генерируемого WAL. До
версии 13 ничего подобного не было. Затем в 13-й версии подобная
статистика была добавлена в pg_stat_statements и если ее
просуммировать можно получить нечто похожее. Теперь эта статистика
расширена и есть в более обобщенном виде (не привязана к
запросам).
Пример-[ RECORD 1 ]----+------------------------------wal_records | 40811237wal_fpi | 1551923wal_bytes | 13744020096wal_buffers_full | 509935wal_write | 1177449wal_sync | 666045wal_write_time | 26449.751wal_sync_time | 10956905.427stats_reset | 2021-05-21 10:33:39.009804+05
- Новое представление для наблюдения за логическими слотами
репликации pg_stat_replication_slots. Если используется
логическая репликация (PUBLICATIONS/SUBSCRIPTIONS, или например
Debezium), то это будет полезно в добавок к уже имеющейся
pg_replication_slots.
- Новое поле toplevel в pg_stat_statements. Известно что
pg_stat_statements можно настроить так, чтобы хранить статистику о
запросах вложенных в процедуры и функции. Однако если считать
агрегаты, то можно получить неверные результаты статистика по
вложенным запросам посчитается дважды. Все из-за того, что
непонятно как отличить вложенный запрос от нормального. Новое поле
позволяет отличать запросы и исключать их.
- Новое представление pg_stat_statements_info. Пока там
всего два значения время сброса статистики и количество выброшенных
значений из pg_stat_statements. Второе значение представляет
пользу, поскольку pg_stat_statements имеет лимит на количество
записей и если лимит достигнут, то старые записи будут удалены и
этого никто не узнает. Теперь же это можно отследить и при
необходимости пересмотреть значение
pg_stat_statements.max.
- Новое представление pg_backend_memory_contexts одно из
нововедений которое вызвало у меня противоречивые эмоции.
Показывает распределение используемой памяти текущим процессом.
Представление как мне кажется предназначено для разработчиков и для
отладки на предмет утечек памяти при долгой работе сессий.
- Здесь как бы продолжение предыдущего пункта, в котором будет
понятен тезис про эмоции.
Новая функция pg_log_backend_memory_contexts() это развитие предыдущего улучшения, функция принимает в качестве аргумента идентификатор процесса и сохраняет в журнал, статистику утилизации подобно той что в представлении pg_backend_memory_contexts.
И вот тут как мне кажется, разработчики перемудрили достаточно было бы сделать только одну эту функцию (без вьюхи) которая бы принимала идентификатор процесса, но при этом вместо логирования, выводила бы статистику в виде строк. В таком случае можно взять статистику и по текущей сессии и по любой соседней. При этом возможность залогировать вывод тоже никуда не девается (хоть и не в журнал, но тем не менее возможность есть). А в текущем виде есть представление и функция с логированием и еще в журнал надо сходить, чтобы достать сброшенную статистику. Короче, мне реализация показалось слегка странной. - Новые поля в pg_prepared_statements
generic_plans, custom_plans для подсчета количества
планов для каждого запроса. Честно, я практически этим
представлением никогда не пользовался и у меня нет практических
примеров его применения.
- Новая функция pg_get_wal_replay_pause_state(). Чуть
более улучшенная версия функции pg_is_wal_replay_paused().
Показывает состояние постановки репликации на паузу. Доступно три
варианта not paused, pause requested, paused.
- Новый параметр log_recovery_conflict_waits включает
журналирование случаев когда воспроизведение WAL журнала на реплике
вступает в конфликт и ждет разрешения конфликта. Штука полезная, я
бы рекомендовал включать по-умолчанию.
- Новые операторы для pg_lsn типа. Тип pg_lsn используется
для работы с позицией в WAL журнале например с помощью этого типа
удобно считать лаг репликации в байтах. С помощью двух новых
операторов арифметика стала проще и значения pg_lsn можно
складывать или вычитать с целыми числами.
Пока не придумал где использовать, но выглядит клевоpgbench=# select '1/8000000'::pg_lsn + 16777216;-[ RECORD 1 ]-------?column? | 1/9000000pgbench=# select '1/8000000'::pg_lsn - 16777216;-[ RECORD 1 ]-------?column? | 1/7000000
- Добавлена информация о таймингах ввода-вывода при
журналировании операций autovacuum и autoanalyze. Должен быть
включен log_autovacuum_min_duration.
А ну-ка попробуйте отыскать2021-05-22 10:50:48.000 +05 1005664 @ from [vxid:4/309623 txid:0] [] LOG: automatic vacuum of table "pgbench.public.pgbench_accounts": index scans: 1 pages: 0 removed, 65600 remain, 0 skipped due to pins, 0 skipped frozen tuples: 1936414 removed, 2000605 remain, 566 are dead but not yet removable, oldest xmin: 253998 buffer usage: 92201 hits, 108672 misses, 129131 dirtied index scan needed: 58623 pages from table (89.36% of total) had 1961508 dead item identifiers removed index "pgbench_accounts_pkey": pages: 10970 in total, 0 newly deleted, 0 currently deleted, 0 reusable avg read rate: 3.522 MB/s, avg write rate: 4.185 MB/s I/O Timings: read=392.361 write=1964.360 system usage: CPU: user: 2.92 s, system: 1.79 s, elapsed: 241.07 s WAL usage: 195815 records, 72916 full page images, 308792606 bytes
Вот и всё.
В завершение хочу сделать анонс мероприятия 8 и 9 июля в онлайне состоится PG Day21 Russia. Это будет двух-дневная тусовка фанатов PostgreSQL, 12 выступлений от отечественных и зарубежных докладчиков. Участие бесплатное. Прием докладов также открыт до 7 июня
На этом все, спасибо за внимание!