- •Предисловие
- •Об этой книге
- •Глава 1. Обзор статистики
- •Внутреннее устройство PostgreSQL
- •Установка соединений и работа сеансов
- •Запросы как базовая единица рабочей нагрузки
- •Планирование и выполнение запросов
- •Ввод-вывод при выполнении запросов
- •Журнал сообщений СУБД
- •Репликация изменений
- •Архивирование журнала предзаписи
- •Фоновая синхронизация данных
- •Автоочистка
- •Интерфейс статистики
- •Статистика как отправная точка инструментов мониторинга
- •Особенности статистики
- •Тестовое окружение
- •Глава 2. Статистика активности
- •Ключ к пониманию происходящего в СУБД
- •Взаимодействие клиента и сервера
- •Источники информации об активности
- •Представление pg_stat_activity
- •Представление pg_locks
- •Особенности pg_stat_activity и pg_locks
- •Представление pg_stat_database
- •Подключенные клиенты
- •Отслеживание клиентских сеансов
- •Транзакционная активность
- •Статусы завершения сеансов
- •Состояния сеансов
- •Отслеживание состояний
- •Ожидания и блокировки
- •Отслеживание состояний с учетом ожиданий
- •Взаимоблокировки
- •Бездействующие транзакции
- •Время выполнения запросов и транзакций
- •Отслеживание времени ожидания блокировок
- •Использование pg_locks.waitstart
- •Использование pg_stat_activity.state_change
- •Дерево блокировок
- •Глава 3. Выполнение запросов и функций
- •Зачем нужен мониторинг запросов
- •Расширение pg_stat_statements
- •Метаданные запроса
- •Планирование запроса
- •Исполнение запроса
- •Сквозная идентификация с queryid
- •Построение отчетов на основе pg_stat_statements
- •Представление pg_stat_statements_info
- •Выполнение процедур и функций
- •Глава 4. Базы данных
- •Иерархия объектов СУБД
- •Кластер баз данных
- •Табличные пространства
- •Базы данных
- •Схемы
- •Таблицы и индексы
- •TOAST
- •События в кластере баз данных
- •Рабочая нагрузка в отношении таблиц и индексов
- •Ошибки и нежелательные события
- •Функции для работы с объектами СУБД
- •Определение размеров объектов СУБД
- •Размещение объектов в файловой системе
- •Глава 5. Область общей памяти и ввод-вывод
- •Анализ общей памяти
- •Представление pg_buffercache
- •Представление pg_shmem_allocations
- •Анализ памяти клиентских процессов
- •Оценка использования SLRU-кешей
- •Ввод-вывод в контексте объектов СУБД
- •Базы данных
- •Ввод-вывод в контексте выполнения запросов
- •Временные файлы
- •Уровень баз данных
- •Ввод-вывод при выполнении запросов
- •Отслеживание в журнале сообщений
- •Отслеживание активных временных файлов
- •Ввод-вывод фоновых процессов
- •Глава 6. Журнал упреждающей записи
- •Отслеживание активности в журнале
- •Представление pg_stat_wal
- •Представление pg_stat_statements
- •Архивирование журнала
- •Представление pg_stat_archiver
- •Очередь архивирования
- •Глава 7. Репликация
- •Обзор репликации
- •Инструменты отслеживания репликации
- •Представление pg_stat_replication
- •Представление pg_stat_wal_receiver
- •Cлоты репликации и pg_replication_slots
- •Публикации и подписки
- •Конфликты восстановления
- •Глава 8. Очистка
- •Введение в очистку
- •Особенности очистки на практике
- •Когда выполняется автоочистка?
- •Статистика выполнения очистки
- •Счетчик транзакций и предотвращение ошибок, связанных с его зацикливанием
- •Раздувание таблиц и индексов
- •Отслеживание активных процессов очистки
- •Представление pg_stat_activity
- •Представление pg_stat_progress_vacuum
- •Глава 9. Ход выполнения операций
- •Представление pg_stat_progress_analyze
- •Представление pg_stat_progress_basebackup
- •Представление pg_stat_progress_cluster
- •Представление pg_stat_progress_create_index
- •Представление pg_stat_progress_copy
- •Предметный указатель
2.8. Дерево блокировок |
65 |
pid |
| state |
| granted |
| |
wait |
| state_age | wait_age |
|
--------- |
+-------- |
+--------- |
+ |
-------------------- |
+----------- |
+---------- |
2291758 |
| active |
| t |
| transactionid.Lock |
| 00:00:14 |
| |
|
2291758 |
| active |
| t |
| transactionid.Lock |
| 00:00:14 |
| |
|
2291758 |
| active |
| t |
| transactionid.Lock |
| 00:00:14 |
| |
|
2291758 |
| active |
| f |
| transactionid.Lock |
| 00:00:14 |
| 00:00:05 |
|
2291758 |
| active |
| t |
| transactionid.Lock |
| 00:00:14 |
| |
|
2291758 |
| active |
| t |
| transactionid.Lock |
| 00:00:14 |
| |
|
Появилась строка для блокировки, которую не удалось взять, с состоянием granted = false и отсчетом, начавшимся в wait_age. При этом значение state осталось прежним, state_age не сбросился и продолжает отсчитываться. В этом примере получается, что запрос выполнял полезную работу примерно девять секунд до начала ожидания блокировки. Фактически ожидание началось после девяти секунд работы запроса.Это поведение и демонстрируетотличие способов учета с помощью waitstart и state_change. Если вы решите повторить эксперимент, незабудьтевконцеотменитьилизакрытьтранзакцию,этопозволитзапросувовторомсеансе завершиться.
Используя учет времени на основе state_change, следует помнить о таком поведении. Например, в OLTP-нагрузке, преимущественно состоящей из коротких и быстрых запросов, оно не сильно исказит статистику, и этот способ подсчета может показаться приемлемым. А вот в случае более долгих OLAP-запросов (как в эксперименте выше) статистика может оказаться неточной,время ожидания будетнесправедливо включатьв себя время выполнения полезной работы,и способ подсчета может оказаться сомнительным.
2.8. Дерево блокировок
На практике часто бывает так, что в определенные моменты довольно много процессов находятся в ожидании блокировок,причем часть процессов оказываются заблокированы другими процессами. Если в такой ситуации найти источник блокировки и устранить его, то с высокойвероятностьюостальныепроцессысмогутнормальнопродолжитьработу.Однако,неимея подготовленных средств, в такой ситуации довольно сложно точно идентифицировать процесс,который стал причиной всех блокировок.Можно анализировать непосредственно вывод pg_stat_activity и pg_locks, но это неудобно и может занять много времени. Для определения источников блокировок нужно выявить зависимости между процессами и построить дерево зависимостей между заблокированными и блокирующими процессами. Такая визуализация позволит быстро определить источник блокировки и устранить его. Подход к решению таких проблем не является новым, и на просторах интернета можно найти разные реализации, которые позволяют выводить дерево блокировок. Такие запросы основываются на pg_stat_activity и pg_locks и, как правило, занимают несколько страниц, поэтому я не буду приводить их здесь. Такие запросы для удобства использования лучше всего оборачивать в представления.
66Глава 2. Статистика активности
В качестве отправной точки я взял этот запрос1 и немного модифицировал его. Итоговый запрос можно найти в репозитории книги, в файле playground/scripts/locktree.sql2. Ключевой особенностью запроса является использование функции pg_blocking_pids. Функция принимает идентификатор процесса и возвращает список процессов, которые его блокируют. Это довольно удобно и позволяет избежать использования pg_locks, однако, согласно документации,частый вызов этой функции может негативно сказываться на производительности СУБД, таккак функция получаеткратковременныйисключительныйдоступк общемусостояниюменеджера блокировок. Так или иначе, функция удобная, и использование ее в редких случаях поиска не должно быть проблемой. Не следует применять ее регулярно для нужд мониторинга, например для снятия метрик. В определенных условиях эксплуатации (высокая нагрузка, требования к задержкам), когда эта особенность даже для целей отладки оказывается неприемлемой,вместо pg_blocking_pids можно использовать pg_locks3.
Давайте рассмотрим пару примеров получения дерева блокировок в тестовом окружении.
pid |
| |
blocked_by |
| state |
| |
wait |
| wait_age | tx_age |
| usename | datname | blkd |
| |
query |
|
||||
--------- |
+ |
------------------- |
+---------- |
+ |
--------------------- |
+---------- |
+----------- |
+--------- |
+--------- |
+ |
------ |
+--------------------------------------------------------------------------------------- |
|
|
2072376 |
| |
{} |
| active |
| LWLock.WALWrite |
| |
| 00:00:00 |
| classic |
| pgbench | |
1 |
| [2072376] END; |
|
|||
2072427 |
| |
{2072376} |
| waiting |
| Lock.transactionid |
| 00:00:00 | 00:00:00 |
| maru |
| pgbench | |
0 |
| [2072427] . UPDATE pgbench_branches SET bbalance = bbalance + |
3135 WHERE bid = 17; |
||||
2072386 |
| |
{} |
| active |
| LWLock.WALWrite |
| |
| 00:00:01 |
| classic | pgbench | |
1 |
| [2072386] END; |
|
||||
2072382 |
| |
{2072386} |
| waiting |
| Lock.transactionid |
| 00:00:01 | 00:00:01 |
| classic | pgbench | |
0 |
| [2072382] . UPDATE pgbench_branches SET bbalance = bbalance + |
232 WHERE bid = 15; |
|||||
2072387 |
| |
{} |
| active |
| LWLock.WALWrite |
| |
| 00:00:01 |
| classic | pgbench | |
1 |
| [2072387] END; |
|
||||
2072388 |
| |
{2072387} |
| waiting |
| Lock.transactionid |
| 00:00:00 | 00:00:00 |
| classic | pgbench | |
0 |
| [2072388] . UPDATE pgbench_branches SET bbalance = bbalance + |
3169 WHERE bid = 13; |
|||||
2072394 |
| |
{} |
| active |
| LWLock.WALWrite |
| |
| 00:00:01 |
| classic | pgbench | |
1 |
| [2072394] END; |
|
||||
2072391 |
| |
{2072394} |
| waiting |
| Lock.transactionid |
| 00:00:00 | 00:00:00 |
| classic | pgbench | |
0 |
| [2072391] . UPDATE pgbench_branches SET bbalance = bbalance + |
-2825 WHERE bid = 6; |
|||||
2072399 |
| |
{} |
| active |
| LWLock.WALWrite |
| |
| 00:00:01 |
| classic | pgbench | |
1 |
| [2072399] END; |
|
||||
2072390 |
| |
{2072399} |
| waiting |
| Lock.transactionid |
| 00:00:01 | 00:00:01 |
| classic |
| pgbench | |
0 |
| [2072390] . UPDATE pgbench_branches SET bbalance = bbalance + |
-122 WHERE bid = 7; |
||||
2072415 |
| |
{} |
| active |
| LWLock.WALWrite |
| |
| 00:00:01 |
| maru |
| pgbench | |
1 |
| [2072415] END; |
|
|||
2072418 |
| |
{2072415} |
| waiting |
| Lock.transactionid |
| 00:00:00 | 00:00:00 |
| maru |
| pgbench | |
0 |
| [2072418] . UPDATE pgbench_branches SET bbalance = bbalance + |
-3319 WHERE bid = 12; |
||||
2072423 |
| |
{} |
| active |
| IO.WALSync |
| |
| 00:00:01 |
| maru |
| pgbench | |
2 |
| [2072423] END; |
|
|||
2072410 |
| |
{2072423} |
| waiting |
| Lock.transactionid |
| 00:00:01 | 00:00:01 |
| serral |
| pgbench | |
0 |
| [2072410] . UPDATE pgbench_tellers SET tbalance = tbalance + 1404 WHERE tid = 18; |
|||||
2072416 |
| |
{2072423} |
| waiting |
| Lock.transactionid |
| 00:00:00 | 00:00:00 |
| maru |
| pgbench | |
0 |
| [2072416] . UPDATE pgbench_branches SET bbalance = bbalance + |
1468 WHERE bid = 11; |
||||
2072424 |
| |
{} |
| active |
| LWLock.WALWrite |
| |
| 00:00:01 |
| maru |
| pgbench | |
4 |
| [2072424] END; |
|
|||
2072408 |
| |
{2072424} |
| waiting |
| Lock.transactionid |
| 00:00:01 | 00:00:01 |
| serral |
| pgbench | |
3 |
| [2072408] . UPDATE pgbench_branches SET bbalance = bbalance + |
-1605 WHERE bid = 8; |
||||
2072392 |
| |
{2072408} |
| waiting |
| Lock.tuple |
| 00:00:00 | 00:00:00 |
| classic |
| pgbench | |
2 |
| [2072392] .. |
UPDATE pgbench_branches SET bbalance = bbalance + -3889 WHERE bid = 8; |
||||
2072409 |
| |
{2072408,2072392} |
| waiting |
| Lock.tuple |
| 00:00:00 | 00:00:00 |
| serral |
| pgbench | |
1 |
| [2072409] ... |
UPDATE pgbench_branches SET bbalance = bbalance |
+ 4620 WHERE bid = 8; |
|||
2072419 |
| |
{2072409} |
| waiting |
| Lock.transactionid |
| 00:00:00 | 00:00:00 |
| maru |
| pgbench | |
0 |
| [2072419] .... |
UPDATE pgbench_tellers SET tbalance = tbalance |
+ 2315 WHERE tid = 180; |
|||
Блокировки, представленные в первом примере, часто возникают при конкурентном обновлении данных. Каждая строка вывода описывает отдельный процесс и детализацию сеанса на основе pg_stat_activity.Давайте рассмотрим поля этого запроса:
•pid—идентификатор процесса;
•blocked_by — список процессов, которые блокируют текущий процесс. Рассчитывается на основе функции pg_blocking_pids;
•state— состояние процесса с дополненным псевдосостоянием waiting на основе условия wait_event_type = 'Lock';
•wait—маркер ожидания,составленный из wait_event_type и wait_event;
•wait_age—длительность ожидания процесса на основе pg_locks.waitstart;
•tx_age—длительностьтранзакции;
1 postgres.ai/blog/20211018-postgresql-lock-trees
2 github.com/lesovsky/postgresql-monitoring-book/blob/main/playground/scripts/locktree.sql 3 dev.to/bolajiwahab/2022-01-13-postgresql-lock-trees-56e0
2.8. Дерево блокировок |
67 |
•usename—имя пользователя;
•datname—имя базы данных;
•blkd—количество других процессов,заблокированных данным;
•query—текст запроса. Содержит идентификатор процесса и его уровень в своей ветви дерева блокировок.
Все процессы можно условно разделить на группы, в которых есть основной источник блокировки, который никем не блокируется, и есть заблокированные процессы, которые могут также блокировать других участников группы. Давайте более внимательно рассмотрим последнюю группу, где главным процессом, который заблокировал остальных участников, является процесс с идентификатором 2072424.Потексту запроса видно,что это фиксациятранзакции (END, или COMMIT), сам процесс находится в активном состоянии и его маркер ожидания — LWLock.WALWrite. Это указывает на то, что происходит запись в WAL-журнал, и пока она не завершится, клиент не получит возможность отправлять другие команды или открывать транзакции.Такоеповедениехарактерноврежимесинхроннойфиксации(см.synchronous_commit), который используется по умолчанию.По полю blkd можно увидеть,что фиксациятранзакции блокирует еще четыре процесса, которые описаны в строках ниже. По полям pid и blocked_by можно проследить взаимосвязи процессов и кто кого блокирует. Также глубину блокировки удобноотслеживатьпосимволуточкивполеquery.Потекстузапросавэтомжеполевидно,что трипроцессапытаютсяобновитьоднуитужестрокупоусловиюWHEREbid=8.Вероятнейвсего, эта строка была обновлена втранзакции,которая фиксируется вданный момент,чем и вызвана очередь ожидания. Поля state и wait указывают на то, что все четыре процесса находятся в ожидании блокировок. Судя по полю wait_age, время ожидания составляет меньше одной секунды — это вполне приемлемо для тестовой рабочей нагрузки, а вот в производственной нагрузкедажетакие короткие ожидания могутстатьпричиной задержек в приложениях.Поля usename и datname указывают, от имени каких пользователей и в какой базе данных возникли блокировки.
Рассмотримещеодинпримердереваблокировок,которыйможетвозникнутьвтестовомокружении.
pid | blocked_by | state | wait | wait_age | tx_age | usename | datname | blkd | query
------+------------+---------+--------------------+----------+----------+----------+---------+------+-----------------------------------------------------------------------------------------------...
161 |
| {} |
| active | |
IO.WALSync |
| |
| 00:00:00 | postgres | pgbench | |
20 |
| |
[161] |
TRUNCATE |
pgbench_history ; |
|
|
|
|
|
1923 |
| {161} |
| waiting | |
Lock. relation |
| 00:00:00 | 00:00:00 | serral |
| pgbench | |
0 |
| |
[1923] |
. INSERT |
INTO pgbench_history (tid, bid, |
aid, delta, |
mtime) |
VALUES (15, |
13, 1518573,... |
|
1924 |
| {161} |
| waiting | |
Lock. relation |
| 00:00:00 | 00:00:00 | serral |
| pgbench | |
2 |
| |
[1924] |
. INSERT |
INTO pgbench_history (tid, bid, |
aid, delta, |
mtime) |
VALUES (46, |
6, 589135, -... |
|
1925 |
| {161} |
| waiting | |
Lock. relation |
| 00:00:00 | 00:00:01 | serral |
| pgbench | |
1 |
| |
[1925] |
. INSERT |
INTO pgbench_history (tid, bid, |
aid, delta, |
mtime) |
VALUES (106, 12, 100334,... |
||
1929 |
| {161} |
| waiting | |
Lock. relation |
| 00:00:00 | 00:00:00 | serral |
| pgbench | |
0 |
| |
[1929] |
. INSERT |
INTO pgbench_history (tid, bid, |
aid, delta, |
mtime) |
VALUES (93, |
18, 1330287,... |
|
1936 |
| {161} |
| waiting | |
Lock. relation |
| 00:00:00 | 00:00:00 | maru |
| pgbench | |
0 |
| |
[1936] |
. INSERT |
INTO pgbench_history (tid, bid, |
aid, delta, |
mtime) |
VALUES (99, |
7, 914556, 1... |
|
1942 |
| {161} |
| waiting | |
Lock. relation |
| 00:00:00 | 00:00:00 | maru |
| pgbench | |
3 |
| |
[1942] |
. INSERT |
INTO pgbench_history (tid, bid, |
aid, delta, |
mtime) |
VALUES (61, |
20, 669763, ... |
|
1957 |
| {161} |
| waiting | |
Lock. relation |
| 00:00:00 | 00:00:00 | classic |
| pgbench | |
0 |
| |
[1957] |
. INSERT |
INTO pgbench_history (tid, bid, |
aid, delta, |
mtime) |
VALUES (104, 4, 880250, ... |
||
1963 |
| {161} |
| waiting | |
Lock. relation |
| 00:00:00 | 00:00:00 | classic |
| pgbench | |
0 |
| |
[1963] |
. INSERT |
INTO pgbench_history (tid, bid, |
aid, delta, |
mtime) |
VALUES (162, 8, 1371725,... |
||
1964 |
| {161} |
| waiting | |
Lock. relation |
| 00:00:00 | 00:00:00 | classic |
| pgbench | |
0 |
| |
[1964] |
. INSERT |
INTO pgbench_history (tid, bid, |
aid, delta, |
mtime) |
VALUES (69, |
9, 71583, 18... |
|
1971 |
| {161} |
| waiting | |
Lock. relation |
| 00:00:00 | 00:00:01 | classic |
| pgbench | |
1 |
| |
[1971] |
. INSERT |
INTO pgbench_history (tid, bid, |
aid, delta, |
mtime) |
VALUES (44, |
14, 1331579,... |
|
1976 |
| {161} |
| waiting | |
Lock. relation |
| 00:00:00 | 00:00:00 | classic |
| pgbench | |
2 |
| |
[1976] |
. INSERT |
INTO pgbench_history (tid, bid, |
aid, delta, |
mtime) |
VALUES (60, |
17, 1238351,... |
|
955 |
| {1942} |
| waiting | |
Lock.transactionid | 00:00:00 | 00:00:00 | pgbench |
| pgbench | |
1 |
| |
[955] |
.. UPDATE pgbench_branches SET bbalance = bbalance + |
-2769 WHERE bid = 20; |
||||||
1926 |
| {1976} |
| waiting | |
Lock.transactionid | 00:00:00 | 00:00:00 | serral |
| pgbench | |
0 |
| |
[1926] |
.. UPDATE pgbench_branches SET bbalance = bbalance + |
-410 WHERE bid = 17; |
||||||
1927 |
| {1971} |
| waiting | |
Lock.transactionid | 00:00:00 | 00:00:00 | serral |
| pgbench | |
0 |
| |
[1927] |
.. UPDATE pgbench_branches SET bbalance = bbalance + |
-4047 WHERE bid = 14; |
||||||
1930 |
| {1924} |
| waiting | |
Lock.transactionid | 00:00:00 | 00:00:00 | serral |
| pgbench | |
1 |
| |
[1930] |
.. UPDATE pgbench_branches SET bbalance = bbalance + |
-3100 WHERE bid = 6; |
||||||
1938 |
| {1925} |
| waiting | |
Lock.transactionid | 00:00:00 | 00:00:00 | maru |
| pgbench | |
0 |
| |
[1938] |
.. UPDATE pgbench_branches SET bbalance = bbalance + |
608 WHERE bid = 12; |
|
|||||
1955 |
| {1976} |
| waiting | |
Lock.transactionid | 00:00:00 | 00:00:00 | classic |
| pgbench | |
0 |
| |
[1955] |
.. UPDATE pgbench_branches SET bbalance = bbalance + |
1745 WHERE bid = 17; |
||||||
1966 |
| {1942} |
| waiting | |
Lock.transactionid | 00:00:00 | 00:00:00 | classic |
| pgbench | |
0 |
| |
[1966] |
.. UPDATE pgbench_branches SET bbalance = bbalance + |
-4835 WHERE bid = 20; |
||||||
1931 |
| {955} |
| waiting | |
Lock.transactionid | 00:00:00 | 00:00:00 | serral |
| pgbench | |
0 |
| |
[1931] |
... UPDATE pgbench_tellers SET tbalance = tbalance + |
-4006 WHERE tid = 182; |
||||||
1972 |
| {1930} |
| waiting | |
Lock.tuple |
| 00:00:00 | 00:00:00 | classic |
| pgbench | |
0 |
| |
[1972] |
... UPDATE pgbench_branches SET bbalance |
= bbalance + -3771 |
WHERE bid = |
6; |
|||
68Глава 2. Статистика активности
Вэтомпримереисточникомблокировкивыступаетпроцессскомандойопустошениятаблицы (TRUNCATE). Это довольно быстрая операция, заключающаяся в замене файла данных на пустой, однако сначала ей нужно дождаться завершения ранее запущенных запросов к целевой таблице. В момент опустошения таблица блокируется, поэтому все процессы, обращающиеся в нее, должны дождаться завершения команды. Поле blkd показывает, что процесс TRUNCATE (pid = 161) блокирует выполнение еще двадцати процессов. Примерно половина из них пытаются вставить строки в опустошаемую таблицу — у всех этих процессов в поле blocked_by указанидентификаторпроцессаTRUNCATE.Другаячастьпроцессов—этооперацииобновления, которые, в свою очередь, ожидают выполнения вставок. Подтвердить это можно, сопоставив значения идентификаторов blocked_by с полем pid процессов, выполняющих вставку. Также можносопоставитьзначения поляbidвзапросах—онобудетсовпадатьвотдельныхцепочках ожидающих запросов: например, процесс 955 обновляет строку с bid = 20 и ожидает завершения вставки в процессе 1942, который сам ожидает завершения команды TRUNCATE. Состояние и маркеры ожидания процесса,выполняющего команду TRUNCATE,показывают,что процесс ак- тивенисинхронизируетWAL-сегментсфайломнадиске(вызовомfsyncилидругимспособом, который указан в параметре wal_sync_method).Еще одним способом определения причин ожиданийявляетсяисследованиезаписейоблокировкахвжурналесообщенийСУБД(приусловии, что включен параметр log_lock_waits и ожидание составило больше, чем значение параметра deadlock_timeout,по умолчанию равное одной секунде).
Оба рассмотренных случая относятся к рабочей нагрузке в тестовом окружении, которое характеризуется короткими транзакциями и такими же короткими блокировками. На практике все может быть намного сложнее, особенно если источником блокировок выступают бездействующие транзакции,которые могут удерживать блокировки непредсказуемо долго и потенциально приводить к аварийным ситуациям.Порядок действия в таких ситуациях,как правило,сводится к принудительному завершению процессов.В критической ситуации важно быстросориентироватьсяинайтитоткорневойпроцесс,завершениекоторогоразрешитситуацию. При недостатке информации часто приходится без разбора завершать множество процессов. В случае же использования запросов,подобных рассмотренному,можно с большейточностью определить и устранить источник блокировки, позволив остальным процессам продолжить работу.
Резюме
•Статистика клиентской активности позволяет понять,что происходит в СУБД.
•СУБД предоставляет три важных источника данных о клиентской активности: представ-
ления pg_stat_activity,pg_locks и pg_stat_database.
•И администраторы БД, и инструменты мониторинга получают данные из представлений с помощью SQL-запросов.
•Клиентский сеанс в процессе существования может пребывать в разных состояниях.
Резюме 69
•Транзакционная активность помогает быстро оценить нагрузку в кластере баз данных.
•Важно вовремя отслеживать и устранять опасные ожидания и блокировки.
•Следует устранять или минимизировать нахождение транзакций в бездействующем состоянии.
•Продолжительность клиентской активности прямо влияет на производительность.
•Ожидание блокировок снижает производительность СУБД и приложений.
•Дерево блокировок позволяет быстро выявить источник блокировок.
