- •Предисловие
- •Об этой книге
- •Глава 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
Статистика активности
Вэтой главе мы рассмотрим:
•клиентскую активность;
•транзакционную активность;
•представления pg_stat_activity,pg_locks и pg_stat_database;
•основные состояния клиентских сеансов;
•ожидание и блокировки;
•бездействующие (idle) транзакции;
•как определять длительность запросов и транзакций;
•как определять время ожидания блокировок;
•дерево блокировок.
Статистика активности является ключевым элементом, необходимым для понимания происходящего в СУБД. С точки зрения операционной системы СУБД выглядит как черный ящик. Операционная система ничего не знает о таких внутренних сущностях СУБД, как пользователи, базы, сеансы, транзакции и т. п. Статистика активности позволяет заглянуть внутрь этого ящика и лучше понять происходящее внутри. Активность подразумевает любые процессы в СУБД,вызванные как внутренним взаимодействием подсистем,так и обслуживанием внешних клиентов. В этой главе мы подробно рассмотрим клиентские сеансы и все, что с ними связано: взаимодействие клиента и сервера, установка сеанса, выполнение запросов и транзакций,основныесостояниясеансаинегативныесценарии,которыемогутвозникатьвовремя сеанса, такие как бездействующие транзакции и блокировки. Умение отслеживать процессы, протекающие в СУБД, — это важный навык, необходимый для успешной эксплуатации приложений и СУБД. Для этого мы рассмотрим основные источники статистики и примеры ее использования.
2.1. Ключ к пониманию происходящего в СУБД
Я люблю говорить, что СУБД — это сервис. СУБД часто воспринимается как нечто большое и сложно устроенное внутри, но можно представить СУБД как небольшой и легко развертываемый микросервис (столь привычный веб-разработчикам). С этой точки зрения главная задача СУБД — принять и обработать запрос от клиента. Внутреннее взаимодействие сложных
28Глава 2. Статистика активности
компонентов можно считать второстепенным,так как оно не предполагает прямых действий состороныклиента.Втакомупрощенномслучаеестьлишьклиентисервер.Вкачествеклиента выступает программа: это может быть приложение на Go,Python или Ruby,задание от Airflow или Celery или любимая IDE разработчика. В общем, что угодно, что может подключаться к СУБД и общаться с ней по ее протоколу. Сервером выступает СУБД, выполняющая команды клиента.Активность,создаваемая клиентом,формируетрабочую нагрузку.Объем рабочей нагрузки, с которой может справиться СУБД,определяет пропускную способность и, как следствие, общую производительность. Активность в СУБД можно измерить и проанализировать и в результате выявить аномалии, устранив которые можно увеличить производительность СУБД и приложений.
При анализе активности с точки зрения администрирования важно иметь количественную
икачественную информацию о подключенных клиентах,например:
•сколько установлено сеансов и откуда они установлены;
•от имени каких пользователей и к каким базам установлены сеансы;
•в каких состояниях находятся сеансы;
•как долго сеансы находятся в этих состояниях;
•сколько выполняется запросов,от каких пользователей и в каких базах;
•как долго выполняются запросы;
•какие конкретно запросы выполняются в сеансах.
Вопросы ктому,что происходитв СУБД,могутбыть самыми разными,в зависимости отзадач администратора, его осведомленности и гипотез, выдвинутых в процессе поиска и устранения проблем.Вопросы могут затрагивать не только обработку запросов клиентов,но и работу фоновыхслужб.Ответы,полученныеспомощьюстатистикиактивности,позволяютустранить проблемы или оптимизировать работу приложений для достижения более надежной работы и большей производительности.
2.2. Взаимодействие клиента и сервера
Для более полного понимания того, что представляет собой активность, давайте рассмотрим, как взаимодействуют между собой клиенты и СУБД. Взаимодействие строится по классической схеме «клиент — сервер». Сервер работает постоянно в фоновом режиме и ожидает подключенийотклиентов.Клиент,будьтоприложениеилипользователь,подключаетсяксерверу и после успешного подключения, следуя внутренней логике или желанию пользователя, формирует и отправляет команды серверу,ожидает их выполнения,получает ответ и обрабатывает его.
Со стороны PostgreSQL сервером выступает специальный процесс, который исторически принято называть postmaster.В задачи процесса входит прослушивание интерфейсов на предмет клиентских подключений, создание сеансов и запуск фоновых процессов для обслуживания
2.2. Взаимодействие клиента и сервера |
29 |
баз данных. При подключении клиента postmaster создает новый, дочерний процесс, внутри которого выполняются необходимая настройка и подготовка к сеансу. Когда сеанс готов, клиент может начинать отправку запросов.
Режимы работы
Взависимостиотреализацииклиентасеансможетподразумеватьсинхронныйиасинхронный режимы работы. Большинство реализаций используют синхронный режим: клиент отправляет команду, ждет результат его выполнения и в это время не может отправлять другие команды. Возможен и асинхронный режим работы, но его реализация зависит от драйвера.Например,такая функциональность имеется в штатном драйвере libpq1.
Ниже показаны процессы сервера СУБД, выведенные утилитой ps, с точки зрения операционной системы.
$ ps f -u postgres -o pid,cmd
PID CMD
4150200 /usr/lib/postgresql/15/bin/postgres -c config_file=/etc/postgresql/15/main/postgresql.conf
4150206 \_ postgres: 15/main: logger
3979107 \_ postgres: 15/main: checkpointer
3979108 \_ postgres: 15/main: background writer
3979109 \_ postgres: 15/main: walwriter
3979110 \_ postgres: 15/main: autovacuum launcher
3979111 \_ postgres: 15/main: archiver last was 000000010000000400000096
3979112 \_ postgres: 15/main: logical replication launcher
1389347 \_ postgres: 15/main: walsender postgres 127.0.0.1(39540) streaming 4/97BB49B0 1865559 \_ postgres: 15/main: postgres pgbench [local] idle
1865560 \_ postgres: 15/main: postgres pgbench [local] SELECT
1865561 \_ postgres: 15/main: postgres pgbench [local] idle
1865562 \_ postgres: 15/main: postgres pgbench [local] SELECT
1865563 \_ postgres: 15/main: postgres pgbench [local] idle
1865564 \_ postgres: 15/main: postgres pgbench [local] SELECT
1865565 \_ postgres: 15/main: postgres pgbench [local] SELECT
1865566 \_ postgres: 15/main: postgres pgbench [local] SELECT
1865567 \_ postgres: 15/main: postgres pgbench [local] SELECT
1865568 \_ postgres: 15/main: postgres pgbench [local] idle
1865571 \_ postgres: 15/main: postgres pgbench [local] UPDATE
1865572 \_ postgres: 15/main: postgres pgbench [local] COMMIT
Процессывыведеныввидедерева«родитель—потомок».Главнымизнихявляетсяpostmaster, который приходится родителем всем остальным процессам. Среди процессов-потомков есть процессы фоновых служб и процессы клиентских соединений, так называемые бэкенды (backend). Для наблюдения за работой СУБД со стороны операционной системы хорошо подходят такие утилиты, как top, htop и atop. С их помощью можно наблюдать за тем, как процессы операционной системы используют системные и операционные ресурсы,такие как
1 postgrespro.ru/docs/postgresql/current/libpq-async
30Глава 2. Статистика активности
CPU, память, дисковый и сетевой ввод-вывод, пространство на диске. Стоит обратить внима-
ние и на утилиты vmstat, dstat, nicstat и pidstat, iostat, входящие в состав пакета sysstat, — эти утилиты также могут быть полезны в оценке использования системных ресурсов.
Во время сеанса клиент общается с сервером посредством команд. SQL-запросы являются частным случаем таких команд и часто могут организовываться в транзакции. Транзакция представляет собой последовательность из нескольких запросов,которая в целом должна восприниматься как одна логическая операция. Начало транзакции объявляется командой BEGIN, для завершения могут использоваться команды COMMIT (END) или ROLLBACK. Транзакции являются важным механизмом СУБД, обеспечивающим возможность конкурентной работы множестваклиентов.Транзакцииобладаютсвойствамиатомарности,изоляцииисогласованности. Атомарность определяет, что в результате транзакции все ее операции выполняются вместе либоневыполняютсясовсем.Вслучаеошибкиилиоткататранзакциирезультатвсехопераций отменяется до состояния, которое предшествовало началу транзакции. Здесь же проявляется и свойство согласованности, которое устанавливает, что атомарно выполненная (или отмененная) транзакция сохраняет базу данных в непротиворечивом, согласованном состоянии. Отдельные запросы (выполняемые без объявления блока BEGIN и END) на самом деле также являются транзакциями, но состоящими из одной команды. Свойство изоляции заключается втом,что результатытранзакции не видныдругим,соседнимтранзакциям,дотех пор пока эта транзакция не будет зафиксирована, и то в зависимости от используемого уровня изоляции.ДляболееполногопониманияэтоговопросаследуетознакомитьсяспрезентациейБрюса Момджяна MVCC Unmasked1.
Несмотря на свойство изоляции, нельзя думать, что транзакции полностью независимы друг от друга. Возможность конкурентной работы подразумевает вероятность одновременного доступа к одним итем же данным (строкам втаблице) со стороны несколькихтранзакций.В случае операций чтения все просто, поскольку конкурентное чтение не вызывает конфликтов, почти2. С записью все становится чуть сложнее: конкурентная запись может вызывать конфликты, и такие операции должны быть сериализованы, то есть выстроены в строгую последовательность.Для сериализации доступа к объектам БД используются блокировки.Механизм блокировок позволяет ограничивать или запрещать одновременный доступ к ресурсу. Работа блокировок прозрачна для пользователя и в большинстве случаев не требует от него явных действий. Однако возможны ситуации, когда одновременно несколько клиентов пытаются установить несовместимую блокировку на один и тот же ресурс. В таком случае только один клиент сможет установить блокировку, а остальные образуют очередь и будут вынуждены ждать,когда блокировка будет снята.
Вкачестве промежуточного итога можно сделать вывод, что природа конкурентного доступа, свойства транзакций, механизм блокировок и некоторое стечение обстоятельств в совокупности могут приводить к ситуациям с негативными последствиями для СУБД и приложений.
Взависимости отважности эксплуатируемой БДтакие ситуации могутрасцениваться как аварийные, так как могут привести к снижению производительности или к остановке запросов.
1 momjian.us/main/writings/pgsql/mvcc.pdf
2 postgrespro.ru/docs/postgresql/current/sql-select#SQL-FOR-UPDATE-SHARE
