- •Предисловие
- •Об этой книге
- •Глава 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
- •Предметный указатель
144Глава 5. Область общей памяти и ввод-вывод
•shared_blks_read—количество блоков,прочитанных с диска или из страничного кеша ОС
вобщий буферный кеш;
•shared_blks_dirtied — количество блоков в общем буферном кеше, ставших грязными
врезультате внесения изменений;
•shared_blks_written — количество блоков в общем буферном кеше, содержимое которых было записано на диск.
Статистику дополняют аналогичные поля с данными по локальным кешам: local_blks_hit, local_blks_read, local_blks_dirtied и local_blks_written. В главе 3, посвященной запросам,
рассмотрены поля blk_read_time и blk_write_time, которые показывают время, затраченное на ввод-вывод.
Статистику можно использовать в следующих сценариях:
•определение объемов ввода-вывода конкретными запросами;
•выявлениезапросовквременнымтаблицамиобъемввода-вывода,связанныйсними(для работы с временнымитаблицами используютсялокальные кеши,их размер определяется параметром temp_buffers);
•оценка эффекта от внесенных оптимизаций (как изменился объем ввода-вывода при выполнении конкретных запросов);
•оценка ввода-вывода запросов при определении приоритета для оптимизации (оптимизация запроса с бóльшим объемом ввода-вывода будет заметнее и эффективнее с точки зрения утилизации ресурсов).
Также возможны и другие сценарии использования в каких-то особых случаях поиска и устранения проблем производительности.
5.6. Временные файлы
Исполнение запросов, особенно сложных, состоит из нескольких шагов, соответствующих узламплана.Наэтихшагахобычнопроисходитопределеннаяработасданными(выборка,фильтрация, сортировка, сравнение и т. д.). Для некоторых типов работ,таких как сортировка данных, построение хеш-таблицы для соединений и агрегаций или материализация CTE, может потребоваться временный буфер. Для него выделяется рабочая память размером work_mem, обычно небольшая — по умолчанию 4 МБ. При этом запросы могут оперировать значительно бóльшими объемами данных. В случае нехватки рабочей памяти создается временный файл на диске и часть данных переносится в него.После того как запрос выполнен,все потребовавшиесядля его выполнения временные файлы удаляются.Ожидаемая особенностьиспользования временных файлов—замедление производительности запросов,поскольку необходимые
5.6. Временные файлы |
145 |
данные приходится записывать на диск и считывать с диска. С точки зрения производительности следует отслеживать все запросы,которые используют временные файлы и предпринимать шаги по их оптимизации с целью исключения необходимости ввода-вывода.
Статистика СУБД предлагает несколько источников для отслеживания временных файлов,которые могут пригодиться в разных сценариях:
•pg_stat_database содержит статистику по созданным временным файлам в контексте отдельных баз данных;
•pg_stat_statements содержит статистику по вводу-выводу во временные файлы в контексте выполнения запросов;
•в журналах сообщений СУБД также могут фиксироваться случаи использования временных файлов (см. log_temp_files),включая и тексты запросов.
Всем трем источникам присуща общая особенность: статистика использования фиксируется только в моментзавершения запроса.Это неудобно,когда запрос выполняетсядолго и уже используетвременные файлы,—обновление статистики произойдеттолько после его успешного завершения, а в случае аварийного завершения из-за тайм-аута (statement_timeout и т. п.) или принудительного завершения администратором (функцией pg_terminate_backend) фиксации не произойдет.
Далее мы рассмотрим все способы получения статистики по временным файлам.
Уровень баз данных
Представление pg_stat_database содержит поля temp_files и temp_bytes, которые указывают на суммарное количество временных файлов и их размер. Как известно, каждая строка pg_stat_database содержит накопленную статистику по конкретной БД, соответственно, указанныеполябудутсодержатькумулятивнуюстатистикузавсевремянакопления(времясброса статистики указано в stats_reset).
#SELECT datname, temp_files, pg_size_pretty(temp_bytes) AS temp_size FROM pg_stat_database WHERE temp_files > 0
ORDER BY temp_bytes DESC;
datname |
| temp_files |
| temp_size |
||
--------- |
+ |
------------ |
+ |
----------- |
pgbench |
| |
4 |
| |
38 MB |
|1 | 178 kB
Запросы, выполняемые в тестовом окружении, практически не используют временных файлов, однако какую-то статистику все же можно увидеть. Далее для экспериментов будет использоваться следующий запрос, для выполнения которого гарантированно потребуется временный файл (при значении work_mem по умолчанию):
# SELECT a.*, b.* FROM pg_class a, pg_class b ORDER BY random();
146Глава 5. Область общей памяти и ввод-вывод
Запрос выполняется несколько секунд и создает временный файл размером около 60 МБ. Повторив запрос к pg_stat_database, можно обнаружить, что в БД postgres зафиксировано использование временного файла:
#SELECT datname, temp_files, pg_size_pretty(temp_bytes) AS temp_size FROM pg_stat_database
WHERE temp_files > 0 |
|
|
||
ORDER BY temp_bytes DESC; |
|
|||
datname |
| temp_files |
| temp_size |
||
---------- |
+ |
------------ |
+----------- |
|
postgres |
| |
1 |
| 58 |
MB |
pgbench |
| |
4 |
| 38 |
MB |
|1 | 178 kB
C помощью метрики postgres_database_temp_bytes_total можно получить график (рис. 5.6):
Рис. 5.6.Временный файл в БД postgres
Обычно такой график нужен для поверхностного отслеживания временных файлов: как только замечены критические уровни использования временных файлов, можно перейти к более детальному анализу с помощью pg_stat_statements или журналов сообщений.
Важной особенностью счетчика temp_bytes является фиксация итогового размера временного файла. Этот размер не следует путать с объемом ввода-вывода, связанного с файлом: чтение и запись в файл можно осуществлять многократно, и объем выполненного ввода-вывода может многократно превышать конечный размер файла.
Ввод-вывод при выполнении запросов
Расширение pg_stat_statements — это второй источник отслеживания временных файлов. Следующие столбцы одноименного представления показываютобъем ввода-вывода запросов и время,затраченное на работу с временными файлами:
5.6. Временные файлы |
147 |
•temp_blks_read—количество блоков,прочитанных из временных файлов;
•temp_blks_written—количество блоков,записанных во временные файлы;
•temp_blk_read_time—время,затраченное на чтение временных файлов,в миллисекундах;
•temp_blk_write_time — время, затраченное на запись во временные файлы, в миллисекундах.
Отсутствие счетчиков _hits и _dirtied является нормальным, поскольку весь ввод-вывод осуществляется напрямую с файлом без кеширования. Более того,для работы с временным файлом используется техника,отличная от страничной,которая применяется при работе с буферными кешами (общим или локальными): ввод-вывод в этом случае работает с плотно упакованными строками без заголовков и только с нужными полями. В представлении также есть поле dbid, группировка по которому позволяет получить статистику по отдельным базам. Это может навести на мысли о сходстве с pg_stat_database, однако в нем ведется учет количества и размеров временных файлов, а в pg_stat_statements — объема ввода-вывода. Прямое сравнение значений из pg_stat_database и pg_stat_statements довольно бессмысленно.
# SELECT calls, total_exec_time, pg_size_pretty(temp_blks_read * 8192) AS temp_read_bytes,
pg_size_pretty(temp_blks_written * 8192) AS temp_written_bytes, temp_blk_read_time, temp_blk_write_time,
left(query, 32) |
as query |
FROM pg_stat_statements WHERE query ~ 'SELECT a.*, b.*'; |
|
-[ RECORD 1 ]------- |
+-------------------------------------------------------------- |
calls |
| 1 |
total_exec_time |
| 3262.312213999999 |
temp_blks_read |
| 115 MB |
temp_blks_written |
| 115 MB |
temp_blk_read_time |
| 96.354933 |
temp_blk_write_time |
| 257.18505 |
query |
| SELECT a.*, b.* FROM pg_class a, pg_class b ORDER BY random() |
Сточкизрениямониторингазапросовполезнытакжеграфикиtop-K,позволяющиебыстровы- явить запросы, которые больше остальных используют временные файлы. Однако в тестовом окружении нет подходящих запросов и такой график не покажет ничего интересного.
Отслеживание в журнале сообщений
Следующий способ отслеживания временных файлов предполагает использование журнала сообщений СУБД. По умолчанию запись сообщений о временных файлах выключена, для ее включения следует установить пороговое значение с помощью параметра log_temp_files. Если размер временного файла превысит это значение, информация о нем, включая и текст запроса,будетсохраненавжурналесообщений.Записиобиспользованиивременныхфайловимеют узнаваемуюсигнатурустекстомtemporaryfileиуказаниемпутидофайлаиегоразмеравбайтах,в следующей строке будет указан текст запроса:
