Документация по PostgreSQL 9.4.1 | |||
---|---|---|---|
Пред. | Уровень выше | Приложение E. Дополнительно поставляемые модули | След. |
E.29. pg_stat_statements
Модуль pg_stat_statements предоставляет возможность отслеживать статистику выполнения сервером всех операторов SQL.
Этот модуль нужно загружать, добавив pg_stat_statements в shared_preload_libraries в файле postgresql.conf, так как ему требуется дополнительная разделяемая память. Это значит, что для загрузки или выгрузки модуля необходимо перезапустить сервер.
E.29.1. Представление pg_stat_statements
Статистика, собираемая модулем, выдаётся через системное представление с именем pg_stat_statements. Это представление содержит отдельные строки для каждой комбинации идентификатора базы данных, идентификатора пользователя и идентификатора запроса (но в количестве, не превышающем максимальное число различных операторов, которые может отслеживать модуль). Колонки представления показаны в Таблице E-20.
Таблица E-20. Колонки pg_stat_statements
Имя | Тип | Ссылки | Описание |
---|---|---|---|
userid | oid | pg_authid.oid | OID пользователя, выполнявшего оператор |
dbid | oid | pg_database.oid | OID базы данных, в которой выполнялся оператор |
queryid | bigint | Внутренний хеш-код, вычисленный по дереву разбора оператора | |
query | text | Текст, представляющий оператор | |
calls | bigint | Число выполнений | |
total_time | double precision | Общее время, потраченное на оператор, в миллисекундах | |
rows | bigint | Общее число строк, полученных или затронутых оператором | |
shared_blks_hit | bigint | Общее число попаданий в разделяемый кеш блоков для данного оператора | |
shared_blks_read | bigint | Общее число чтений разделяемых блоков для данного оператора | |
shared_blks_dirtied | bigint | Общее число разделяемых блоков, «загрязнённых» данным оператором | |
shared_blks_written | bigint | Общее число разделяемых блоков, записанных данным оператором | |
local_blks_hit | bigint | Общее число попаданий в локальный кеш блоков для данного оператора | |
local_blks_read | bigint | Общее число чтений локальных блоков для данного оператора | |
local_blks_dirtied | bigint | Общее число локальных блоков, «загрязнённых» данным оператором | |
local_blks_written | bigint | Общее число локальных блоков, записанных данным оператором | |
temp_blks_read | bigint | Общее число чтений временных блоков для данного оператора | |
temp_blks_written | bigint | Общее число записей временных блоков для данного оператора | |
blk_read_time | double precision | Общее время, потраченное оператором на чтение блоков, в миллисекундах (если включён track_io_timing, или ноль в противном случае) | |
blk_write_time | double precision | Общее время, потраченное оператором на запись блоков, в миллисекундах (если включён track_io_timing, или ноль в противном случае) |
Это представление и функции pg_stat_statements_reset
и pg_stat_statements
доступны только в тех базах, где они были специально установлены при установке расширения pg_stat_statements. Однако когда модуль pg_stat_statements загружен в сервер, статистика отслеживается по всем базам данным, вне зависимости от присутствия представления.
По соображениям безопасности обычные пользователи не видят текст SQL и queryid для запросов, выполненных другими пользователями. Однако они могут видеть статистику, если в их базу данных установлено представление.
Планируемые запросы (то есть, SELECT, INSERT, UPDATE и DELETE) объединяются в одну запись в pg_stat_statements, когда они имеют идентичные структуры запросов согласно внутреннему вычисленному хешу. Обычно два запроса будут считаться равными при таком сравнении, если они семантически равнозначны, не считая значений констант, фигурирующих в запросе. Однако служебные команды (то есть все другие команды) сравниваются строго по текстовым строкам запросов.
Когда значение константы игнорируется в целях сравнения запроса с другими запросами, эта константа заменяется в выводе pg_stat_statements знаком ?. В остальном этот вывод содержит текст первого запроса, имеющего определённое значение хеша queryid, связанное с записью в pg_stat_statements.
В некоторых случаях запросы с визуально различными текстами могут быть объединены в одну запись pg_stat_statements. Обычно это происходит только для семантически равнозначных запросов, но есть небольшая вероятность, что из-за наложений хеша несвязанные запросы могут оказаться объединёнными в одной записи. (Однако это невозможно для запросов, принадлежащих разным пользователям баз данных.)
Так как значение хеша queryid вычисляется по представлениям запроса на стадии после разбора, возможна и обратная ситуация: запросы с одинаковым текстом могут оказаться в разных записях, если они получили различные представления по разным причинам, например, из-за изменения search_path.
Потребители статистики pg_stat_statements могут пожелать использовать в качестве более стабильного и надёжного идентификатора для каждой записи не текст запроса, а queryid (возможно, в сочетании с dbid и userid). Однако важно понимать, что стабильность значения хеша queryid гарантируется с ограничениями. Так как этот идентификатор получается из дерева запроса после анализа, его значение будет, помимо прочего, зависеть от внутренних идентификаторов объектов, фигурирующих в этом представлении. С этим связано несколько неинтуитивных следствий. Например, pg_stat_statements будет считать два одинаково выглядящих запроса разными, если они обращаются к таблице, которая была удалена, а затем воссоздана между этими запросами. Результат хеширования также чувствителен к различиям в машинной архитектуре и другим особенностям платформы. Более того, не стоит рассчитывать на то, что queryid будет оставаться неизменным при обновлении основных версий PostgreSQL.
Как правило, значения queryid можно считать надёжными и сравнимыми, только с условием, что версия сервера и детали метаданных каталога неизменны. Следовательно, можно ожидать, что два сервера, участвующие в репликации на основе воспроизведения физического WAL, будут иметь одинаковые queryid для одного запроса. Однако схемы с логической репликацией не гарантируют сохранения идентичности реплик во всех имеющих значение деталях, так что queryid не будет полезным идентификатором для накопления показателей стоимости по набору логических реплик. В случае сомнений в том или ином подходе, рекомендуется непосредственно протестировать его.
E.29.2. Функции
pg_stat_statements_reset() returns void
Функция
pg_stat_statements_reset
очищает всю статистику, собранную к этому времени модулем pg_stat_statements. По умолчанию эту функцию могут выполнять только суперпользователи.pg_stat_statements(showtext boolean) returns setof record
Представление pg_stat_statements реализовано на базе функции, которая тоже называется
pg_stat_statements
. Клиенты могут вызывать функциюpg_stat_statements
непосредственно, и могут указать showtext := false и получить результат без текста запроса (то есть, выходной аргумент (OUT), соответствующий колонке представления query, будет содержать NULL). Эта возможность предназначена для поддержки внешних инструментов, для которых желательно избежать издержек, связанных с получением текстов запросов неопределённой длины. Такие инструменты могут кешировать текст первого запроса, который они получат самостоятельно, как это и делает pg_stat_statements, а затем запрашивать тексты запросов только при необходимости. Так как сервер сохраняет тексты запросов в файле, этот подход сокращает объём физического ввода/вывода, порождаемого при постоянном обращении к данным pg_stat_statements.
E.29.3. Параметры конфигурации
- pg_stat_statements.max (integer)
Параметр pg_stat_statements.max задаёт максимальное число операторов, отслеживаемых модулем (то есть, максимальное число строк в представлении pg_stat_statements). Когда на обработку поступает больше, чем заданное число различных операторов, информация о редко выполняемых операторах отбрасывается. Значение по умолчанию — 5000. Этот параметр можно задать только при запуске сервера.
- pg_stat_statements.track (enum)
Параметр pg_stat_statements.track определяет, какие операторы будут отслеживаться модулем. Со значением top отслеживаются операторы верхнего уровня (те, что непосредственно выполняются клиентами), со значением all также отслеживаются вложенные операторы (например, операторы, вызываемые внутри функций), а значение none полностью отключает сбор статистики по операторам. Значение по умолчанию — top. Изменять этот параметр могут только суперпользователи.
- pg_stat_statements.track_utility (boolean)
Параметр pg_stat_statements.track_utility определяет, будет ли этот модуль отслеживать служебные команды. Служебными командами считаются команды, отличные от SELECT, INSERT, UPDATE и DELETE. Значение по умолчанию — on (вкл.). Изменить этот параметр могут только суперпользователи.
- pg_stat_statements.save (boolean)
Параметр pg_stat_statements.save определяет, должна ли статистика операторов сохраняться после перезагрузки сервера. Если он отключён (имеет значение off), статистика не сохраняется при остановке сервера и не перезагружается при запуске. Значение по умолчанию — on (вкл.). Этот параметр можно задать только в postgresql.conf или в командной строке сервера.
Этому модулю требуется дополнительная разделяемая память в объёме, пропорциональном pg_stat_statements.max. Заметьте, что эта память будет занята при загрузке модуля, даже если pg_stat_statements.track имеет значение none.
Эти параметры должны задаваться в postgresql.conf. Обычное использование выглядит так:
# postgresql.conf shared_preload_libraries = 'pg_stat_statements' pg_stat_statements.max = 10000 pg_stat_statements.track = all
E.29.4. Пример вывода
bench=# SELECT pg_stat_statements_reset(); $ pgbench -i bench $ pgbench -c10 -t300 bench bench=# \x bench=# SELECT query, calls, total_time, rows, 100.0 * shared_blks_hit / nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5; -[ RECORD 1 ]--------------------------------------------------------------------- query | UPDATE pgbench_branches SET bbalance = bbalance + ? WHERE bid = ?; calls | 3000 total_time | 9609.00100000002 rows | 2836 hit_percent | 99.9778970000200936 -[ RECORD 2 ]--------------------------------------------------------------------- query | UPDATE pgbench_tellers SET tbalance = tbalance + ? WHERE tid = ?; calls | 3000 total_time | 8015.156 rows | 2990 hit_percent | 99.9731126579631345 -[ RECORD 3 ]--------------------------------------------------------------------- query | copy pgbench_accounts from stdin calls | 1 total_time | 310.624 rows | 100000 hit_percent | 0.30395136778115501520 -[ RECORD 4 ]--------------------------------------------------------------------- query | UPDATE pgbench_accounts SET abalance = abalance + ? WHERE aid = ?; calls | 3000 total_time | 271.741999999997 rows | 3000 hit_percent | 93.7968855088209426 -[ RECORD 5 ]--------------------------------------------------------------------- query | alter table pgbench_accounts add primary key (aid) calls | 1 total_time | 81.42 rows | 0 hit_percent | 34.4947735191637631
E.29.5. Авторы
Такахиро Итагаки <itagaki.takahiro@oss.ntt.co.jp>
. Нормализацию запросов добавил Питер Геохеган <peter@2ndquadrant.com>
.
Пред. | Начало | След. |
pgrowlocks | Уровень выше | pgstattuple |