Интроспекция кеша буферов, совместимая с 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. Валидные строки описывают кешированную страницу, невалидные строки представляют свободные слоты в пуле.
| Столбец | Тип | Описание |
|---|---|---|
bufferid | int8 | Идентификатор буфера OrioleDB (номер блока в памяти). |
pool_name | text | Пул страниц: main, free_tree или catalog. |
reldatabase | oid | OID базы данных кешированной страницы, если назначен. |
reloid | oid | OID отношения (pg_class.oid), если назначен. |
relfilenode | oid | Узел файла отношения, если назначен. |
orioledb_tree_type | text | Роль дерева индекса: primary, regular, unique, toast, bridge, exclusion и т. д. |
isdirty | bool | Имеет ли страница незаписанные изменения. |
usagecount | int2 | Счетчик использования при циклическом сканировании (0–7). Свободные слоты используют предельное значение и отображаются как невалидные строки. |
isvalid | bool | false для свободных слотов буфера; столбцы отношения имеют значение 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_used | int8 | Буферы, содержащие кешированную страницу. |
buffers_unused | int8 | Свободные слоты буфера. |
buffers_dirty | int8 | Используемые буферы, отмеченные как измененные. |
usagecount_avg | float8 | Средний счетчик использования по всем используемым буферам (NULL, если ни один не используется). |
SELECT * FROM pg_buffercache_summary_oriole();
pg_buffercache_usage_counts_oriole()
Возвращает по строке на каждый уровень счета использования (от 0 до 7), соответствуя стилю гистограммы вспомогательных функций счета использования pg_buffercache PostgreSQL:
| Столбец | Тип | Описание |
|---|---|---|
usage_count | int4 | Уровень счета использования. |
buffers | int8 | Общее количество буферов на данном уровне (включая свободные слоты на предельном уровне). |
used | int8 | Буферы на данном уровне, содержащие кешированную страницу. |
dirty | int8 | Используемые буферы на данном уровне, отмеченные как измененные. |
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_type | text | Категория журнала отката: row, page или system. |
undo_location | int8 | Байтовое смещение записи в пределах журнала отката. |
storage | text | Место хранения тела записи: ram, disk или mixed. |
item_type | text | Декодированный вид записи, например Modify, RowLock, PageImage, Relnode. |
item_size | int4 | Размер записи в байтах. |
prev_location | int8 | Предыдущая запись в цепочке отката, при наличии. |
index_type | text | Тип дерева индекса для элементов стека, содержащих данный тип. |
action | text | Для записей Modify: insert, update, delete или lock. |
datoid | oid | OID базы данных, если запись ссылается на отношение. |
reloid | oid | OID отношения, если запись ссылается на отношение. |
blkno | int8 | Номер блока в пределах отношения, для записей Modify. |
page_image_type | text | Подтип изображения страницы для записей PageImage. |
is_valid | bool | Существует ли запись по данной позиции. |
pg_undo_cache_records_oriole(undo_type_filter, from_location, to_location, max_records)
Функция, возвращающая набор строк, с необязательными фильтрами:
| Аргумент | По умолчанию | Описание |
|---|---|---|
undo_type_filter | NULL (все типы) | Ограничить типами row, page или system. |
from_location | NULL | Начать сканирование с данной позиции отката (включительно). |
to_location | NULL | Остановиться до данной позиции отката. |
max_records | 10000 | Максимальное количество возвращаемых записей. |
-- Недавний откат на уровне строк для таблицы
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_type | text | row, page или system. |
records_count | int8 | Количество валидных записей отката, прошедших сканирование. |
records_bytes | int8 | Общее байтовое количество прошедших сканирование записей. |
records_in_ram | int8 | Записи, тело которых полностью находится в кольцевом буфере. |
records_on_disk | int8 | Записи, тело которых полностью находится на диске. |
circular_buffer_size | int8 | Размер кольцевого буфера в памяти для данного журнала отката. |
last_used_location | int8 | Текущая позиция добавления в журнал отката. |
written_location | int8 | Граница между хранением на диске и в памяти. |
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_buffercache | pg_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();