stat_dump
Расширение stat_dump предоставляет функции, позволяющие выгрузить и восстановить
содержимое таблицы pg_statistic. Расширение позволяет избежать выполнения
ANALYZE при восстановлении данных или разворачивании экземпляра, дублирующего
существующий, тем самым сокращая время развертывания, так как ANALYZE требует
много времени для анализа больших баз данных.
Функция dump_statistic выдает операторы INSERT, которые затем можно
применить к совместимой базе данных. Чтобы успешно восстановить статистические
данные, это расширение следует установить и на исходном, и на целевом сервере,
так как эти операторы будут задействовать функции, реализованные в расширении.
ВНИМАНИЕ!
Определение таблицы pg_statistic может поменяться в новых версиях, в результате чего старые экспорты могут оказаться несовместимыми.
Установка
CREATE EXTENSION stat_dump;
Функции
Основные
dump_statistic() returns setof text
Выгружает содержимое системного каталога pg_statistic, выдавая INSERT
для каждого кортежа в pg_statistic, кроме тех, что содержат
статистические данные о таблицах в схемах information_schema и pg_catalog.
Оператор INSERT принимает следующую форму:
WITH upsert as (
UPDATE pg_catalog.pg_statistic SET [имя_столбца1 = значение1, ...]
WHERE starelid = '{t_relname}'::regclass
AND to_attname('{t_relname}'::regclass, staattnum) = '{t_attname}'
AND to_atttype('{t_relname}'::regclass, staattnum) = '{t_atttype}'
AND stainherit = {t_stainherit}
RETURNING *),
ins as (
SELECT [значение1, ...]
WHERE NOT EXISTS (SELECT * FROM upsert)
AND to_attnum('{t_relname}', '{t_attname}') IS NOT NULL
AND to_atttype('{t_relname}'::regclass, '{t_attname}') = '{t_atttype}')
INSERT INTO pg_catalog.pg_statistic SELECT * FROM ins;
/*
где значениеN может быть представлено в одном из следующих вариантов:
- значение::имя_типа
- array_in(текст_массива, имя_типа::regtype::oid, -1)
а вместо t_relname, t_attname и t_atttype подставляются конкретные
значения
*/
Для сохранения выданных операторов, необходимо направить вывод psql в файл, используя стандартные возможности psql. Например, чтобы сохранить статистику базы данных имя_базы в файл dump_stat.sql, надо выполнить:
psql -XAtq -c "SELECT dump_statistic()" имя_базы > dump_stat.sql
Вспомогательные
to_schema_qualified_type(id_типа oid) returns text
Выдает дополненное схемой имя типа по заданному id_типа.
to_schema_qualified_relation(id_отношения oid) returns text
Выдает дополненное схемой имя отношения по заданному id_отношения.
to_attname(отношение regclass, номер_столбца int2) returns text
Для заданных отношения и номера_столбца возвращает имя столбца в виде значения text.
to_attnum(отношение regclass, столбец text) returns int2
Для заданных отношения и столбца возвращает номер столбца в виде значения int2.
to_atttype(отношение regclass, столбец text) returns text
Для заданных отношения и столбца возвращает дополненное схемой имя типа столбца в виде значения text.
to_atttype(отношение regclass, номер_столбца int2) returns text
Для заданных отношения и номера_столбца возвращает дополненное схемой имя типа столбца в виде значения text.
Ограничения
Нельзя экспортировать отдельно: схемы, схемы и таблицы, отношения.
Расширение не совместимо с параметром qss_encrypt_statistic (не работает и экспорт и импорт). Экспорт статистики считается небезопасным при включенном шифровании.
Заметки по реализации
- В
UPDATEиINSERTзначениеN — это непосредственные значения, которые вставляются в таблицу pg_statistic. ВUPDATEиINSERTони одинаковы, то есть дублируют друг друга (за исключением того что вUPDATEформа записи "имя = значение", а вINSERTпросто "значение"), в связи с тем, что решение о том, произойдет лиUPDATEилиINSERT, принимается во время импорта, а не экспорта. - Функции to_attname, to_atttype и to_attnum используются для исключения использования идентификаторов таблиц и полей, так как они могут отличаться в базе, в которую производится импорт. Таким образом, эти функции принимают человеко-читаемое имя и конвертируют его в OID'ы текущего экземпляра.
- Логика использования
UPDATEиINSERTсостоит в том, что сначала выполняется попытка сделатьUPDATE, если статистика для соответствующих строк уже существует в pg_statistic, иначе делаетсяINSERT. - Функция array_in создает значение типа anyarray, принимая на вход строку
определенного формата (например,
'{1,2,3}') и тип элементов массива. Пример:select array_in('{1,2,3}', 'int4'::regtype, -1);.