Инструкция по настройке и работе с расширением pg_stat_kcache#
Установка pg_stat_kcache#
Установить
pg_stat_kcachesudo apt install postgresql-16-pg-stat-kcache postgresql-contrib
Зарегистрировать расширение в postgresql
su postgres psqlПроверьте какие библиотеки у вас уже занесены в
shared_preload_librariesshow shared_preload_libraries;
Пример вывода:
postgres=# show shared_preload_libraries; shared_preload_libraries ----------------------------------- <ваши расширения> (1 строка)
Дополнить
shared_preload_librariesновыми расширениями, сохранив старыеalter system set shared_preload_libraries = '<ваши расширения>,pg_stat_statements,pg_stat_kcache';
Что-бы применить новые расширения, необходимо перезапустить
postgresqlsudo systemctl restart postgresql
Создать расширение в нужной БД
Подключитесь к нужной вам БД
\c <ваша бд>
Создайте расширения
CREATE EXTENSION pg_stat_statements; CREATE EXTENSION pg_stat_kcache;
Примечание
Чтобы распространялось на новые БД — выполнить команды в БД template1.
Проверка
Чтоб проверить успешность, выполните команду
\dx
Пример вывода:
pg16=# \dx Список установленных расширений Имя | Версия | Схема | Описание --------------------+--------+------------+------------------------------------------------------------------------ ... pg_stat_kcache | 2.3.0 | public | Kernel statistics gathering pg_stat_statements | 1.10 | public | track planning and execution statistics of all SQL statements executed ... (N строк)
Пример запросов#
Топ-20 по IO (exec_reads + exec_writes) с текстом запроса
WITH k AS (
SELECT *
FROM pg_stat_kcache_detail
WHERE top IS TRUE
),
s AS (
SELECT dbid, userid, toplevel, query,
calls
FROM pg_stat_statements
)
SELECT
s.calls,
(k.exec_reads + k.exec_writes) AS io_ops,
k.exec_reads, k.exec_writes,
round(k.exec_user_time::numeric, 3) AS user_sec,
round(k.exec_system_time::numeric, 3) AS sys_sec,
left(k.query, 200) AS query_sample
FROM k
JOIN pg_database d ON d.datname = k.datname
JOIN pg_roles u ON u.rolname = k.rolname
JOIN s ON s.dbid = d.oid
AND s.userid = u.oid
AND s.toplevel = k.top
-- нормализуем пробелы в тексте запроса на обоих сторонах
AND md5(regexp_replace(s.query, '\s+', ' ', 'g'))
= md5(regexp_replace(k.query, '\s+', ' ', 'g'))
ORDER BY (k.exec_reads + k.exec_writes) DESC
LIMIT 20;
Топ-20 по CPU (exec_user_time + exec_system_time)
WITH k AS (
SELECT *
FROM pg_stat_kcache_detail
WHERE top IS TRUE
),
s AS (
SELECT dbid, userid, toplevel, query,
calls
FROM pg_stat_statements
)
SELECT
s.calls,
round((k.exec_user_time + k.exec_system_time)::numeric, 3) AS cpu_sec,
round(k.exec_user_time::numeric, 3) AS user_sec,
round(k.exec_system_time::numeric, 3) AS sys_sec,
left(k.query, 200) AS query_sample
FROM k
JOIN pg_database d ON d.datname = k.datname
JOIN pg_roles u ON u.rolname = k.rolname
JOIN s ON s.dbid = d.oid
AND s.userid = u.oid
AND s.toplevel = k.top
AND md5(regexp_replace(s.query, '\s+', ' ', 'g'))
= md5(regexp_replace(k.query, '\s+', ' ', 'g'))
ORDER BY (k.exec_user_time + k.exec_system_time) DESC
LIMIT 20;
Быстрая сводка по БД (без джойнов)#
SELECT
datname,
(exec_reads + exec_writes) AS io_ops,
exec_reads, exec_writes,
round(exec_user_time::numeric, 3) AS user_sec,
round(exec_system_time::numeric, 3) AS sys_sec,
stats_since
FROM pg_stat_kcache
ORDER BY io_ops DESC;