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

Интроспекция кеша буферов, совместимая с pg_buffercache

Расширение PostgreSQL pg_buffercache осматривает разделяемые буферы, используемые таблицами кучи. OrioleDB хранит страницы таблиц и индексов в собственных пулах страниц в памяти и сохраняет записи отката в отдельных кольцевых буферах и файлах отката на диске. Ни один из них не виден через pg_buffercache.

Расширение OrioleDB версии 1.8 добавляет встроенные SQL-представления и функции с аналогичным интерфейсом:

  • pg_buffercache_oriole — пулы буферов страниц OrioleDB (основные, дерева свободного пространства и каталога);
  • pg_undo_cache_oriole — декодированные записи журнала отката из буферов в памяти и файлов отката на диске.

Оба устанавливаются вместе с CREATE EXTENSION orioledb, отдельное расширение не требуется.

Кеш буферов страниц​

Представление pg_buffercache_oriole​

Представление оборачивает pg_buffercache_pages_oriole() и возвращает по строке на каждый слот буфера OrioleDB. Валидные строки описывают кешированную страницу, невалидные строки представляют свободные слоты в пуле.

СтолбецТипОписание
bufferidint8Идентификатор буфера OrioleDB (номер блока в памяти).
pool_nametextПул страниц: main, free_tree или catalog.
reldatabaseoidOID базы данных кешированной страницы, если назначен.
reloidoidOID отношения (pg_class.oid), если назначен.
relfilenodeoidУзел файла отношения, если назначен.
orioledb_tree_typetextРоль дерева индекса: primary, regular, unique, toast, bridge, exclusion и т. д.
isdirtyboolИмеет ли страница незаписанные изменения.
usagecountint2Счетчик использования при циклическом сканировании (0–7). Свободные слоты используют предельное значение и отображаются как невалидные строки.
isvalidboolfalse для свободных слотов буфера; столбцы отношения имеют значение NULL в этих строках.
-- Страницы, кешированные для конкретной таблицы
SELECT bufferid, pool_name, orioledb_tree_type, isdirty, usagecount
FROM pg_buffercache_oriole
WHERE reloid = 'my_table'::regclass
AND isvalid;

-- Измененные страницы во всех пулах
SELECT pool_name, count(*) AS dirty_pages
FROM pg_buffercache_oriole
WHERE isvalid AND isdirty
GROUP BY pool_name;

Общее количество строк в pg_buffercache_oriole совпадает с общим количеством страниц, возвращаемым функцией orioledb_page_stats().

pg_buffercache_summary_oriole()​

Возвращает однострочное резюме всех пулов страниц OrioleDB:

СтолбецТипОписание
buffers_usedint8Буферы, содержащие кешированную страницу.
buffers_unusedint8Свободные слоты буфера.
buffers_dirtyint8Используемые буферы, отмеченные как измененные.
usagecount_avgfloat8Средний счетчик использования по всем используемым буферам (NULL, если ни один не используется).
SELECT * FROM pg_buffercache_summary_oriole();

pg_buffercache_usage_counts_oriole()​

Возвращает по строке на каждый уровень счета использования (от 0 до 7), соответствуя стилю гистограммы вспомогательных функций счета использования pg_buffercache PostgreSQL:

СтолбецТипОписание
usage_countint4Уровень счета использования.
buffersint8Общее количество буферов на данном уровне (включая свободные слоты на предельном уровне).
usedint8Буферы на данном уровне, содержащие кешированную страницу.
dirtyint8Используемые буферы на данном уровне, отмеченные как измененные.
SELECT usage_count, used, dirty
FROM pg_buffercache_usage_counts_oriole()
WHERE used > 0
ORDER BY usage_count;

pg_buffercache_evict_oriole(bufferid int8)​

Вытесняет одну страницу из кеша буферов OrioleDB по bufferid. Возвращает true при успешном вытеснении страницы и false, если слот уже был свободен. Требует прав суперпользователя.

SELECT pg_buffercache_evict_oriole(42);

Права доступа к кешу буферов страниц​

ОбъектДоступ
pg_buffercache_oriole, pg_buffercache_pages_oriole()Только суперпользователь
pg_buffercache_summary_oriole()pg_monitor
pg_buffercache_usage_counts_oriole()pg_monitor
pg_buffercache_evict_oriole()Только суперпользователь

Кеш журнала отката​

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

Интерфейс кеша отката декодирует отдельные записи отката и сообщает, хранится ли каждая запись в данный момент в ОЗУ, на диске или охватывает оба хранилища (значения столбца storage: ram, disk или mixed).

Представление pg_undo_cache_oriole​

Представление оборачивает pg_undo_cache_records_oriole() с аргументами по умолчанию (все типы отката, без фильтрации по позиции, до 10 000 записей).

СтолбецТипОписание
undo_typetextКатегория журнала отката: row, page или system.
undo_locationint8Байтовое смещение записи в пределах журнала отката.
storagetextМесто хранения тела записи: ram, disk или mixed.
item_typetextДекодированный вид записи, например Modify, RowLock, PageImage, Relnode.
item_sizeint4Размер записи в байтах.
prev_locationint8Предыдущая запись в цепочке отката, при наличии.
index_typetextТип дерева индекса для элементов стека, содержащих данный тип.
actiontextДля записей Modify: insert, update, delete или lock.
datoidoidOID базы данных, если запись ссылается на отношение.
reloidoidOID отношения, если запись ссылается на отношение.
blknoint8Номер блока в пределах отношения, для записей Modify.
page_image_typetextПодтип изображения страницы для записей PageImage.
is_validboolСуществует ли запись по данной позиции.

pg_undo_cache_records_oriole(undo_type_filter, from_location, to_location, max_records)​

Функция, возвращающая набор строк, с необязательными фильтрами:

АргументПо умолчаниюОписание
undo_type_filterNULL (все типы)Ограничить типами row, page или system.
from_locationNULLНачать сканирование с данной позиции отката (включительно).
to_locationNULLОстановиться до данной позиции отката.
max_records10000Максимальное количество возвращаемых записей.
-- Недавний откат на уровне строк для таблицы
SELECT undo_location, storage, item_type, action, blkno
FROM pg_undo_cache_records_oriole('row')
WHERE reloid = 'my_table'::regclass
AND is_valid
ORDER BY undo_location DESC
LIMIT 20;

-- Только откат на уровне страниц, ограничен 100 записями
SELECT undo_location, item_type, page_image_type
FROM pg_undo_cache_records_oriole('page', NULL, NULL, 100);

pg_undo_cache_summary_oriole()​

Возвращает по строке на каждый тип журнала отката со сводной статистикой:

СтолбецТипОписание
undo_typetextrow, page или system.
records_countint8Количество валидных записей отката, прошедших сканирование.
records_bytesint8Общее байтовое количество прошедших сканирование записей.
records_in_ramint8Записи, тело которых полностью находится в кольцевом буфере.
records_on_diskint8Записи, тело которых полностью находится на диске.
circular_buffer_sizeint8Размер кольцевого буфера в памяти для данного журнала отката.
last_used_locationint8Текущая позиция добавления в журнал отката.
written_locationint8Граница между хранением на диске и в памяти.
SELECT * FROM pg_undo_cache_summary_oriole();

Для измерения общего размера отката на диске (а не только кешированных записей) использовать orioledb_undo_size().

Права доступа к кешу отката​

ОбъектДоступ
pg_undo_cache_oriole, pg_undo_cache_records_oriole()Только суперпользователь
pg_undo_cache_summary_oriole()pg_monitor

Сравнение с pg_buffercache​

PostgreSQL pg_buffercacheАналоги OrioleDB
Буферы страницПредставление pg_buffercacheПредставление pg_buffercache_oriole
Резюме буферов—pg_buffercache_summary_oriole()
Гистограмма счета использованияВспомогательные функции pg_buffercachepg_buffercache_usage_counts_oriole()
Вытеснение буфераpg_buffercache_evict() (PG 17+)pg_buffercache_evict_oriole()
Буферы отката / WALНе применимоПредставление pg_undo_cache_oriole

Буферы страниц OrioleDB используют bufferid и pool_name вместо bufferid PostgreSQL, привязанного к shared_buffers. Столбцы метаданных отношения (reldatabase, reloid, relfilenode) аналогичны, но OrioleDB также предоставляет orioledb_tree_type, так как таблицы и индексы используют общие пулы буферов.

Пример: диагностика давления на кеш​

CREATE TABLE o_cache_probe (id int PRIMARY KEY, payload text) USING orioledb;
INSERT INTO o_cache_probe SELECT i, repeat('x', 200) FROM generate_series(1, 5000) i;
SELECT count(*) FROM o_cache_probe;
CHECKPOINT;

-- Использование пула страниц
SELECT * FROM pg_buffercache_summary_oriole();

-- Какие отношения доминируют в кеше?
SELECT c.relname, b.orioledb_tree_type, count(*) AS pages
FROM pg_buffercache_oriole b
JOIN pg_class c ON c.oid = b.reloid
WHERE b.isvalid
GROUP BY c.relname, b.orioledb_tree_type
ORDER BY pages DESC
LIMIT 10;

-- Активность отката после модификаций
UPDATE o_cache_probe SET payload = 'updated' WHERE id <= 100;
SELECT undo_type, records_count, records_in_ram, records_on_disk
FROM pg_undo_cache_summary_oriole();