Перейти к основному содержимому

pg_buffercache — просмотр состояния буферного кеша PostgreSQL

примечание

Эта страница переведена при помощи нейросети GigaChat.

Модуль pg_buffercache предоставляет возможность исследовать происходящее в общем буферном кеше в реальном времени. Он также предлагает низкоуровневый способ вытеснения данных из него для тестовых целей.

Этот модуль предоставляет функции pg_buffercache_pages() (обернутые в представление pg_buffercache), pg_buffercache_numa_pages() (обернутые в представление pg_buffercache_numa), pg_buffercache_summary(), pg_buffercache_usage_counts(), pg_buffercache_evict(), pg_buffercache_evict_relation() и pg_buffercache_evict_all().

Функция pg_buffercache_pages() возвращает набор записей, каждая строка описывает состояние одной записи общего буфера. Для удобства использования функция инкапсулируется представлением pg_buffercache.

Функция pg_buffercache_numa_pages() предоставляет сопоставления узлов NUMA для записей общего буфера. Эта информация не является частью самой функции pg_buffercache_pages(), поскольку ее получение занимает гораздо больше времени. Для удобства использования функция инкапсулируется представлением pg_buffercache_numa.

Функция pg_buffercache_summary() возвращает одну строку, суммирующую состояние кэша общего буфера.

Функция pg_buffercache_usage_counts() возвращает набор записей, каждая строка описывает количество буферов с заданным количеством использований.

По умолчанию использование указанных выше функций ограничено суперпользователями и ролями с привилегиями роли pg_monitor. Доступ может быть предоставлен другим пользователям с помощью команды GRANT.

Функция pg_buffercache_evict() позволяет удалить блок из буферного пула, указав идентификатор буфера. Использование этой функции разрешено только суперпользователям.

Функция pg_buffercache_evict_relation() позволяет удалить все незакрепленные разделяемые буферы в отношении из буферного пула, указав идентификатор отношения. Использование этой функции разрешено только суперпользователям.

Функция pg_buffercache_evict_all() позволяет удалить все незакрепленные разделяемые буферы из буферного пула. Использование этой функции разрешено только суперпользователям.

Представление pg_buffercache

Определения столбцов, отображаемых представлением, показаны в таблице ниже.

Столбцы pg_buffercache:

Тип столбцаОписание
bufferid integerID, в диапазоне 1..shared_buffers
relfilenode oid (ссылается на pg_class.relfilenode)Номер файлового узла для отношения
reltablespace oid (ссылается на pg_tablespace.oid)OID табличного пространства, содержащего отношение
reldatabase oid (ссылается на pg_database.oid)OID базы данных, содержащей отношение
relforknumber smallintНомер слоя внутри отношения, подробнее смотрите common/relpath.h
relblocknumber bigintНомер страницы в отношении
isdirty booleanСтраница загрязнена?
usagecount smallintСчетчик обращений по часовой стрелке
pinning_backends integerКоличество обслуживающих процессов, закрепивших этот буфер

Для каждого буфера в общем кеше выдается одна строка. Для неиспользуемых буферов все поля равны NULL, за исключением bufferid. Общие системные каталоги отображаются как принадлежащие базе данных с номером ноль.

Поскольку кеш используется всеми базами данных, обычно в нем будут и страницы из отношений, не принадлежащих текущей базе данных. Это означает, что для некоторых строк может не быть соответствующих строк соединения в pg_class или даже могут быть неправильные соединения. Если требуется присоединиться к pg_class, то хорошей идеей будет ограничить соединение строками, у которых reldatabase равно идентификатору текущей базы данных или нулю.

Поскольку блокировки диспетчера буфера не берутся для копирования состояния буфера, которое будет отображать представление, доступ к представлению pg_buffercache оказывает меньшее влияние на обычную активность буфера, но он не предоставляет согласованный набор результатов во всех буферах. Однако гарантируется, что информация каждого буфера является самосогласованной.

Представление pg_buffercache_numa

Определения столбцов, отображаемых представлением, показаны в таблице ниже:

Столбцы pg_buffercache_numa

Тип столбцаОписание
bufferid integerID, в диапазоне 1..shared_buffers
os_page_num bigintКоличество страниц памяти ОС для этого буфера
numa_node intID узла NUMA

Поскольку запрос ID узла NUMA для каждой страницы требует подкачки страниц памяти, первое выполнение этой функции может занять заметное количество времени. Во всех случаях (при первом выполнении или нет) получение этой информации является затратным, и частое обращение к представлению не рекомендуется.

warning

При определении узла NUMA представление обращается ко всем страницам памяти для сегмента разделяемой памяти. Это приведет к принудительному выделению общей памяти, если она еще не была выделена, и память может быть выделена в одном узле NUMA (в зависимости от конфигурации системы).

Функция pg_buffercache_summary()

Определения столбцов, раскрываемых функцией, приведены в таблице ниже.

Столбцы вывода pg_buffercache_summary():

Тип столбцаОписание
buffers_used int4Количество используемых общих буферов
buffers_unused int4Количество неиспользуемых общих буферов
buffers_dirty int4Количество «грязных» общих буферов
buffers_pinned int4Количество закрепленных общих буферов
usagecount_avg float8Средняя частота использования используемых общих буферов

Функция pg_buffercache_summary() возвращает одну строку, обобщающую состояние всех общих буферов. Похожая и более подробная информация предоставляется представлением pg_buffercache, однако pg_buffercache_summary() значительно дешевле.

Как и представление pg_buffercache, функция pg_buffercache_summary() не захватывает блокировку менеджера буферов. Поэтому параллельная активность может привести к незначительным неточностям в результате.

Функция pg_buffercache_usage_counts()

Определения столбцов, раскрываемых функцией, приведены в таблице ниже.

Столбцы вывода pg_buffercache_usage_counts():

Тип столбцаОписание
usage_count int4Возможный счетчик использования буфера
buffers int4Количество буферов с таким значением счетчика использования
dirty int4Количество «грязных» буферов с этим значением счетчика использования
pinned int4Количество закрепленных буферов с учетом частоты использования

Функция pg_buffercache_usage_counts() возвращает набор строк, обобщающих состояния всех общих буферов, агрегированных по возможным значениям частоты использования. Похожая и более подробная информация предоставляется представлением pg_buffercache, но pg_buffercache_usage_counts() значительно дешевле.

Как и представление pg_buffercache, pg_buffercache_usage_counts() не захватывает блокировки менеджера буферов. Поэтому параллельная активность может привести к незначительным неточностям в результате.

Функция pg_buffercache_evict()

Функция pg_buffercache_evict() принимает идентификатор буфера, как показано в столбце bufferid представления pg_buffercache. Она возвращает информацию о том, был ли буфер вытеснен и очищен. Столбец buffer_evicted принимает значение true в случае успеха и false, если буфер был недействителен, если его не удалось вытеснить, потому что он был закреплен, или если он снова стал «грязным» после попытки записи. Столбец buffer_flushed принимает значение true, если буфер был очищен. Это не обязательно означает, что буфер был очищен нами, он мог быть очищен кем-то другим. Результат сразу же устаревает после возврата, поскольку буфер может снова стать действительным в любой момент из-за одновременной активности. Функция предназначена только для тестирования разработчиками.

Функция pg_buffercache_evict_relation()

Функция pg_buffercache_evict_relation() очень похожа на функцию pg_buffercache_evict(). Разница заключается в том, что функция pg_buffercache_evict_relation() принимает идентификатор отношения вместо идентификатора буфера. Она пытается удалить все буферы для всех ответвлений в этом отношении. Она возвращает количество удаленных буферов, очищенных буферов и количество буферов, которые не удалось удалить. Очищенные буферы не обязательно были очищены нами, они могли быть очищены кем-то другим. Результат сразу же устаревает после возврата, поскольку буферы могут быть немедленно считаны обратно из-за параллельной активности. Функция предназначена только для тестирования разработчиками.

Функция pg_buffercache_evict_all()

Функция pg_buffercache_evict_all() очень похожа на функцию pg_buffercache_evict(). Разница в том, что функция pg_buffercache_evict_all() не принимает аргумент, вместо этого она пытается удалить все буферы в пуле буферов. Функция возвращает количество вытесненных буферов, сброшенных буферов и количество буферов, которые не удалось вытеснить. Сброшенные буферы не обязательно были сброшены нами, они могли быть сброшены кем-то другим. Результат сразу же устаревает после возврата, поскольку буферы могут быть немедленно считаны обратно из-за параллельной активности. Функция предназначена только для тестирования разработчиками.

Пример вывода

regression=# SELECT n.nspname, c.relname, count(*) AS buffers
FROM pg_buffercache b JOIN pg_class c
ON b.relfilenode = pg_relation_filenode(c.oid) AND
b.reldatabase IN (0, (SELECT oid FROM pg_database
WHERE datname = current_database()))
JOIN pg_namespace n ON n.oid = c.relnamespace
GROUP BY n.nspname, c.relname
ORDER BY 3 DESC
LIMIT 10;

nspname | relname | buffers
------------+------------------------+---------
public | delete_test_table | 593
public | delete_test_table_pkey | 494
pg_catalog | pg_attribute | 472
public | quad_poly_tbl | 353
public | tenk2 | 349
public | tenk1 | 349
public | gin_test_idx | 306
pg_catalog | pg_largeobject | 206
public | gin_test_tbl | 188
public | spgist_text_tbl | 182
(10 rows)

regression=# SELECT * FROM pg_buffercache_summary();
buffers_used | buffers_unused | buffers_dirty | buffers_pinned | usagecount_avg
--------------+----------------+---------------+----------------+----------------
248 | 2096904 | 39 | 0 | 3.141129
(1 row)

regression=# SELECT * FROM pg_buffercache_usage_counts();
usage_count | buffers | dirty | pinned
-------------+---------+-------+--------
0 | 14650 | 0 | 0
1 | 1436 | 671 | 0
2 | 102 | 88 | 0
3 | 23 | 21 | 0
4 | 9 | 7 | 0
5 | 164 | 106 | 0
(6 rows)