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

Определение интерфейса для табличных методов доступа

примечание

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

В этой главе описан интерфейс между ядром PostgreSQL и методами доступа к таблицам, управляющими их хранением. Ядро знает о них только то, что указано здесь, что позволяет создавать совершенно новые типы методов доступа с помощью дополнительного кода.

Каждый метод доступа описывается строкой в системном каталоге pg_am. Запись содержит имя и функцию-обработчик метода. Управление записями осуществляется командами SQL CREATE ACCESS METHOD и DROP ACCESS METHOD.

Функция-обработчик должна принимать один аргумент типа internal и возвращать псевдотип table_am_handler. Аргумент является фиктивным и служит только для защиты от прямого вызова обработчика из SQL.

Пример создания обработчика в SQL-скрипте расширения:

CREATE OR REPLACE FUNCTION my_tableam_handler(internal)
RETURNS table_am_handler AS 'my_extension', 'my_tableam_handler'
LANGUAGE C STRICT;

CREATE ACCESS METHOD myam TYPE TABLE HANDLER my_tableam_handler;

Результат функции — указатель на структуру TableAmRoutine, содержащую все необходимые ядру сведения о методе доступа. Возвращаемое значение должно существовать на протяжении жизни серверного процесса, что обычно достигается объявлением static const в глобальной области видимости.

Пример исходного файла с обработчиком:

#include "postgres.h"

#include "access/tableam.h"
#include "fmgr.h"

PG_MODULE_MAGIC;

static const TableAmRoutine my_tableam_methods = {
.type = T_TableAmRoutine,

/* Methods of TableAmRoutine omitted from example, add them here. */
};

PG_FUNCTION_INFO_V1(my_tableam_handler);

Datum
my_tableam_handler(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(&my_tableam_methods);
}

Структура TableAmRoutine (API метода доступа) определяет его поведение через обратные вызовы. Это указатели на обычные функции C, недоступные на уровне SQL. Все вызовы и их поведение описаны в самой структуре (в комментариях указаны требования). Большинство вызовов имеют функции-обертки, документированные с точки зрения пользователя метода. Подробности смотрите в файле src/include/access/tableam.h.

Для реализации метода обычно требуется создать специфичный для него тип слота таблицы кортежей (смотрите src/include/executor/tuptable.h). Это позволяет внешнему коду хранить ссылки на кортежи метода и обращаться к их столбцам.

Способ фактического хранения данных методом слабо регламентирован. Например, можно (но не обязательно) использовать разделяемый кэш буферов PostgreSQL. При его использовании логично применять стандартный макет страницы.

Существенное ограничение API: для поддержки изменений и/или индексов каждый кортеж должен иметь идентификатор (TID), состоящий из номера блока и номера элемента. Смысл частей TID может отличаться от heap, но для поддержки битового сканирования (опционально) номер блока должен обеспечивать локальность данных.

Для безопасности при сбоях можно использовать WAL PostgreSQL или собственную реализацию. При выборе WAL допустимы общие записи WAL или собственный менеджер ресурсов WAL.

Для реализации транзакционной поддержки, позволяющей использовать разные методы доступа в одной транзакции, потребуется тесная интеграция с механизмами из src/backend/access/transam/xlog.c.

Разработчикам новых методов доступа рекомендуется изучать существующую реализацию для heap в файле src/backend/access/heap/heapam_handler.c.