F.40. pg_csm — оценка сжимаемости таблиц и индексов с помощью CSM#
F.40. pg_csm — оценка сжимаемости таблиц и индексов с помощью CSM #
F.40.1. Обзор #
pg_csm — расширение PostgreSQL для диагностики Compression Storage Manager (CSM).
Расширение предоставляет SQL-интерфейс к четырём направлениям диагностики CSM:
Информация о storage manager. Функция
smgr_infoпоказывает, какой storage manager используется для конкретной relation, и возвращает его параметры — алгоритм сжатия и размер страницы.Анализ сжатия. Функция
csm_compress_analysisчитает страницы relation, сжимает их во временном буфере и возвращает статистику по каждому алгоритму. Это позволяет подобрать алгоритм и размер страницы до того, как данные будут физически перезаписаны.Статистика overflow fork. Функция
csm_overflow_fork_statпоказывает, как заполнен overflow fork CSM-relation: ёмкость, использованные и свободные блоки, распределение batch по размеру. Это основной инструмент для оценки фрагментации overflow-пространства.Статистика кешей CSM. Функция
csm_cache_statвозвращает накопленные счётчики операций и промахов для внутренних кешей CSM в shared memory.
pg_csm входит в состав поставки СУБД. Compression Storage Manager реализован на уровне ядра СУБД и доступен всегда, поэтому расширение не требует отдельной сборки внешнего storage manager.
F.40.2. Подключение расширения #
Расширение подключается в нужной базе данных стандартной командой PostgreSQL:
CREATE EXTENSION pg_csm;
После подключения становятся доступны функции smgr_info, csm_compress_analysis, csm_overflow_fork_stat и csm_cache_stat.
F.40.3. Быстрый старт #
Узнать, какой storage manager используется для таблицы:
SELECT smgr_info('public.orders'::regclass);
Оценить сжимаемость таблицы всеми алгоритмами:
SELECT *
FROM csm_compress_analysis('public.orders');
Посмотреть статистику overflow fork CSM-таблицы:
CHECKPOINT;
SELECT *
FROM csm_overflow_fork_stat('public.orders'::regclass);
Посмотреть статистику внутреннего кэша CSM:
SELECT * FROM csm_cache_stat('ctl');
F.40.4. Настройка сжатого хранения #
Параметры CSM задаются через storage options relation.
Пример создания таблицы со сжатием:
CREATE TABLE orders (
id bigint,
customer_id bigint,
payload jsonb
) WITH (
compression = zstd,
compression_page = 1024
);
Пример создания индекса со сжатием:
CREATE INDEX orders_customer_id_idx
ON orders (customer_id)
WITH (
compression = zstd,
compression_page = 4096
);
Изменить параметры хранения можно с помощью ALTER TABLE или ALTER INDEX:
ALTER TABLE orders
SET (
compression = pglz,
compression_page = 2048
);
ALTER INDEX orders_customer_id_idx
SET (
compression_page = 1024
);
Отключить сжатие для relation можно с помощью compression = off:
CREATE TABLE orders_plain (
id bigint,
payload text
) WITH (
compression = off
);
В тестах расширения используются значения compression_page: 1024, 2048 и 4096.
F.40.5. smgr_info #
smgr_info(
rel regclass,
do_switch bool DEFAULT false
)
RETURNS cstring
Возвращает строку с описанием storage manager, используемого для таблицы или индекса. При do_switch = true перед выводом принудительно завершает выбор storage manager для relation, не изменяя пользовательские данные.
F.40.5.1. Аргументы #
| Аргумент | Тип | По умолчанию | Описание |
|---|---|---|---|
rel | regclass | — | Таблица или индекс. |
do_switch | bool | false | Если true, перед выводом выполняется выбор конкретного storage manager. Полезно, когда relation ещё находится в состоянии выбора (Switcher). |
F.40.5.2. Возвращаемое значение #
Возможные значения возвращаемой строки:
| Значение | Описание |
|---|---|
Switcher | Конкретный storage manager ещё не выбран. |
Storage Manager with compression (algorithm: ..., page size: ...) | Relation использует Compression Storage Manager. |
Magnatic disk | Relation использует обычный дисковый storage manager PostgreSQL. |
The storage manager defined by the extension | Используется внешний storage manager, определённый расширением. |
F.40.5.3. Примеры #
Проверить storage manager таблицы:
SELECT smgr_info('public.orders'::regclass);
smgr_info
----------------------------------------------------------------------
Storage Manager with compression (algorithm: zstd, page size: 1024)
(1 row)
Завершить выбор storage manager и сразу получить результат:
SELECT smgr_info('public.orders'::regclass, true);
smgr_info
----------------------------------------------------------------------
Storage Manager with compression (algorithm: zstd, page size: 1024)
(1 row)
F.40.5.4. Как интерпретировать результат #
Если функция возвращает Switcher, storage manager для relation ещё не определён. Повторный вызов с do_switch = true завершит выбор и вернёт итоговое значение.
Для CSM-relation в строке отображаются алгоритм и размер страницы, заданные через compression и compression_page.
F.40.6. csm_compress_analysis #
csm_compress_analysis(
rel regclass,
compress_alg text DEFAULT 'all',
sample_rate float8 DEFAULT 1.0
)
RETURNS TABLE (
reloid oid,
page_cnt int4,
alg_name text,
avg_compress float4,
avg_page_sz int8,
pages_over_1k int4,
pages_over_2k int4,
pages_over_4k int4
)
Читает страницы relation, сжимает их во временном буфере и возвращает агрегированную статистику по каждому алгоритму. Данные relation при этом не изменяются.
F.40.6.1. Аргументы #
| Аргумент | Тип | По умолчанию | Описание |
|---|---|---|---|
rel | regclass | — | Имя или OID таблицы/индекса. Рекомендуется указывать имя со схемой, например 'public.orders'. |
compress_alg | text | 'all' | Алгоритм сжатия. Допустимые значения: all, zstd, pglz, lz4, cpy. Значение all запускает анализ для всех доступных алгоритмов. |
sample_rate | float8 | 1.0 | Доля страниц для анализа. Значение должно быть больше 0.0 и меньше или равно 1.0. |
F.40.6.2. Возвращаемые колонки #
| Колонка | Тип | Описание |
|---|---|---|
reloid | oid | OID проанализированной relation. |
page_cnt | int4 | Количество страниц, использованных при анализе. |
alg_name | text | Алгоритм сжатия. |
avg_compress | float4 | Средний коэффициент сжатия: отношение среднего размера сжатой страницы к исходному. Чем меньше, тем сильнее сжатие. |
avg_page_sz | int8 | Средний размер страницы после сжатия, в байтах. |
pages_over_1k | int4 | Количество страниц, размер которых после сжатия превысил 1 KB. |
pages_over_2k | int4 | Количество страниц, размер которых после сжатия превысил 2 KB. |
pages_over_4k | int4 | Количество страниц, размер которых после сжатия превысил 4 KB. |
Если relation не содержит страниц, page_cnt равен 0, то статистические колонки возвращаются как NULL.
F.40.6.3. Примеры #
Сравнить все алгоритмы и отсортировать результат по среднему размеру страницы:
SELECT *
FROM csm_compress_analysis('public.orders', 'all', 1.0)
ORDER BY avg_page_sz;
reloid | page_cnt | alg_name | avg_compress | avg_page_sz | pages_over_1k | pages_over_2k | pages_over_4k --------+----------+----------+--------------+-------------+---------------+---------------+--------------- 16384 | 1250 | zstd | 0.38 | 3113 | 1180 | 948 | 118 16384 | 1250 | lz4 | 0.44 | 3604 | 1212 | 1047 | 309 16384 | 1250 | pglz | 0.47 | 3850 | 1224 | 1103 | 421 16384 | 1250 | cpy | 0.53 | 4341 | 1238 | 1186 | 702 (4 rows)
Быстро оценить большую таблицу по 5% страниц:
SELECT *
FROM csm_compress_analysis('public.orders', 'all', 0.05)
ORDER BY avg_compress;
reloid | page_cnt | alg_name | avg_compress | avg_page_sz | pages_over_1k | pages_over_2k | pages_over_4k --------+----------+----------+--------------+-------------+---------------+---------------+--------------- 16384 | 63 | zstd | 0.37 | 3031 | 58 | 46 | 6 16384 | 63 | lz4 | 0.43 | 3522 | 60 | 51 | 15 16384 | 63 | pglz | 0.46 | 3768 | 61 | 54 | 20 16384 | 63 | cpy | 0.52 | 4260 | 62 | 58 | 34 (4 rows)
Проверить только zstd:
SELECT *
FROM csm_compress_analysis('public.orders', 'zstd');
reloid | page_cnt | alg_name | avg_compress | avg_page_sz | pages_over_1k | pages_over_2k | pages_over_4k --------+----------+----------+--------------+-------------+---------------+---------------+--------------- 16384 | 1250 | zstd | 0.38 | 3113 | 1180 | 948 | 118 (1 row)
Проанализировать индекс:
SELECT *
FROM csm_compress_analysis('public.orders_customer_id_idx', 'all');
reloid | page_cnt | alg_name | avg_compress | avg_page_sz | pages_over_1k | pages_over_2k | pages_over_4k --------+----------+----------+--------------+-------------+---------------+---------------+--------------- 16402 | 275 | zstd | 0.21 | 1720 | 201 | 48 | 0 16402 | 275 | lz4 | 0.26 | 2130 | 231 | 89 | 0 16402 | 275 | pglz | 0.29 | 2376 | 249 | 121 | 2 16402 | 275 | cpy | 0.33 | 2703 | 261 | 158 | 8 (4 rows)
F.40.6.4. Как интерпретировать результат #
Главные поля — avg_compress, avg_page_sz и пороговые счётчики pages_over_1k, pages_over_2k, pages_over_4k.
avg_compress = 0.45 означает, что средняя сжатая страница занимает около 45% от исходного размера.
Если avg_page_sz значительно меньше выбранного compression_page, заданный размер страницы достаточен для большинства данных.
Если многие страницы попадают в pages_over_4k, возможно, нужен больший compression_page или другой алгоритм.
Если zstd даёт лучшее сжатие, но нагрузка чувствительна к CPU, следует дополнительно оценить стоимость сжатия/распаковки на реальной рабочей нагрузке.
F.40.6.5. Ограничения #
Поддерживаются только обычные таблицы и индексы. Представления, sequences и другие типы relation вернут ошибку.
Полный анализ большой relation может занять заметное время: страницы читаются и сжимаются в backend-процессе.
При
sample_rate < 1.0результат является приблизительным.avg_compressиavg_page_szописывают ожидаемую сжимаемость страниц, но не заменяют проверку производительности на реальной нагрузке.
F.40.7. csm_overflow_fork_stat #
csm_overflow_fork_stat(
rel regclass,
OUT relname text,
OUT is_csm boolean,
OUT compression_alg text,
OUT compression_page_size int4,
OUT overflow_physical_blocks int8,
OUT overflow_extent_count int8,
OUT overflow_data_capacity_blocks int8,
OUT used_blocks int8,
OUT free_blocks int8,
OUT overflow_batches int8,
OUT overflow_blocks_in_batches int8,
OUT avg_batch_len float8,
OUT batch_count_by_len int8[],
OUT block_count_by_batch_len int8[]
)
Возвращает статистику overflow fork для указанной relation. Overflow fork хранит сжатые страницы CSM, которые не помещаются в стандартный блок PostgreSQL. Relation открывается с блокировкой AccessShareLock; для non-CSM relation все поля кроме relname и is_csm возвращаются как NULL.
Для актуальной статистики рекомендуется выполнить CHECKPOINT перед вызовом — иначе несброшенные грязные буферы не попадут в результат.
F.40.7.1. Аргументы #
| Аргумент | Тип | По умолчанию | Описание |
|---|---|---|---|
rel | regclass | — | Таблица или индекс. Relation должна иметь физическое хранилище. |
F.40.7.2. Возвращаемые колонки #
| Колонка | Тип | Описание |
|---|---|---|
relname | text | Имя relation со схемой. |
is_csm | boolean | true, если relation использует CSM. |
compression_alg | text | Алгоритм сжатия (zstd, pglz, lz4, cpy) или off. NULL для non-CSM. |
compression_page_size | int4 | Настроенный размер сжатой страницы в KB. NULL для non-CSM. |
overflow_physical_blocks | int8 | Количество физических блоков в overflow fork, включая заголовки extents. |
overflow_extent_count | int8 | Количество overflow extents. |
overflow_data_capacity_blocks | int8 | Количество блоков данных: overflow_physical_blocks − overflow_extent_count. |
used_blocks | int8 | Количество блоков данных, помеченных как используемые в bitmap extent. |
free_blocks | int8 | Количество блоков данных, помеченных как свободные в bitmap extent. |
overflow_batches | int8 | Количество найденных overflow batch. |
overflow_blocks_in_batches | int8 | Суммарное количество блоков во всех найденных batch. |
avg_batch_len | float8 | Средняя длина batch в блоках, округлена до двух знаков. |
batch_count_by_len | int8[] | Гистограмма: элемент [N] — количество batch длиной N блоков (1–8). |
block_count_by_batch_len | int8[] | Гистограмма: элемент [N] — количество блоков в batch длиной N (1–8). |
F.40.7.3. Примеры #
Статистика для non-CSM таблицы:
SELECT relname, is_csm
FROM csm_overflow_fork_stat('public.orders_plain'::regclass);
relname | is_csm
---------------------+--------
public.orders_plain | f
(1 row)
Статистика для CSM-таблицы после вставки данных:
CHECKPOINT;
SELECT *
FROM csm_overflow_fork_stat('public.orders'::regclass);
relname | is_csm | compression_alg | compression_page_size | overflow_physical_blocks | overflow_extent_count | overflow_data_capacity_blocks | used_blocks | free_blocks | overflow_batches | overflow_blocks_in_batches | avg_batch_len | batch_count_by_len | block_count_by_batch_len
---------------+--------+-----------------+-----------------------+--------------------------+-----------------------+-------------------------------+-------------+-------------+------------------+----------------------------+---------------+------------------------+--------------------------
public.orders | t | zstd | 1 | 512 | 1 | 511 | 304 | 207 | 38 | 304 | 8 | {0,0,0,0,0,0,0,38} | {0,0,0,0,0,0,0,304}
(1 row)
F.40.7.4. Как интерпретировать результат #
used_blocks + free_blocks должно совпадать с overflow_data_capacity_blocks.
avg_batch_len близкая к 8 говорит о том, что большинство данных упаковано в максимальные batch — overflow fork используется эффективно.
Высокое значение free_blocks относительно overflow_data_capacity_blocks указывает на фрагментацию overflow-пространства.
F.40.7.5. Ограничения #
Функция отражает состояние overflow fork на момент последнего
CHECKPOINT. Несброшенные грязные буферы в результат не попадают.Relation без физического хранилища (представления и т.п.) вернут ошибку.
F.40.8. csm_cache_stat #
csm_cache_stat(
cache_name text
)
RETURNS TABLE (
get_total bigint,
get_miss bigint,
put_total bigint,
put_evict bigint,
blocks_used bigint
)
Возвращает накопленные счётчики операций для внутреннего кеша CSM в shared memory. Предназначена для диагностики эффективности кеширования. Статистика накапливается с момента запуска кластера и не сбрасывается.
F.40.8.1. Аргументы #
| Аргумент | Тип | По умолчанию | Описание |
|---|---|---|---|
cache_name | text | — | Имя кэша. Допустимые значения: ctl (кэш управляющих структур CSM), ovr (кэш размеров overflow страниц), extent (кэш overflow extents). |
F.40.8.2. Возвращаемые колонки #
| Колонка | Тип | Описание |
|---|---|---|
get_total | bigint | Суммарное количество операций чтения из кэша. |
get_miss | bigint | Количество промахов: данные не найдены в кэше. |
put_total | bigint | Суммарное количество операций записи в кэш. |
put_evict | bigint | Количество вытеснений из кэша. |
blocks_used | bigint | Текущее количество занятых (pinned) записей в кэше. |
F.40.8.3. Примеры #
Получить статистику кэша управляющих структур:
SELECT * FROM csm_cache_stat('ctl');
get_total | get_miss | put_total | put_evict | blocks_used
-----------+----------+-----------+-----------+-------------
1024 | 12 | 512 | 0 | 8
(1 row)
Обращение к несуществующему кешу вернёт ошибку:
SELECT * FROM csm_cache_stat('unknown');
-- ERROR: storage manager cache 'unknown' not exist
F.40.8.4. Как интерпретировать результат #
Доля промахов (get_miss / get_total) — основной показатель эффективности кеша. Высокое значение может указывать на недостаточный размер shared memory для CSM.
Рост put_evict означает, что кеш переполняется и вынужден вытеснять записи; при частых вытеснениях стоит рассмотреть увеличение параметров памяти CSM.
F.40.8.5. Ограничения #
Статистика накапливается с момента запуска кластера и не сбрасывается.
Допустимые значения
cache_name: толькоctl,ovr,extent. Любое другое значение вернёт ошибку.
F.40.9. Примечания и ограничения #
Все функции работают в режиме read-only: данные relation не изменяются, блокировка
AccessShareLock.Compression Storage Manager реализован на уровне ядра СУБД;
pg_csmпредоставляет SQL-интерфейс для диагностики и не требует отдельной сборки внешнего storage manager.