Postgres Pro Enterprise 13
CFS — сжатая файловая система
13
Авторские права
© Postgres Professional, 2023 год.
Авторы: Алексей Береснев, Илья Баштанов, Павел Толмачев
Использование материалов курса
Некоммерческое использование материалов курса (презентации,
демонстрации) разрешается без ограничений. Коммерческое
использование возможно только с письменного разрешения компании
Postgres Professional. Запрещается внесение изменений в материалы
курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу:
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за
любые повреждения и убытки, включая потерю дохода, нанесенные
прямым или непрямым, специальным или случайным использованием
материалов курса. Компания Postgres Professional не предоставляет
каких-либо гарантий на материалы курса. Материалы курса
предоставляются на основе принципа «как есть» и компания Postgres
Professional не обязана предоставлять сопровождение, поддержку,
обновления, расширения и изменения.
2
Темы
Возможность и польза сжатия
Реализация сжатия в Postgres Pro Enterprise
Использование CFS
Объем данных и степень сжатия
Фрагментация и сбор мусора
3
Возможности и польза
Данные БД обычно хорошо сжимаются
текстовые данные
дублирование
Преимущества сжатия
уменьшение объема хранения
экономия ресурсов ввода-вывода
последовательное чтение и запись
Сжатие при записи грязного буфера
в буферном кеше нужны несжатые данные
В базах данных обычно хранятся большие объемы текста и
повторяющейся информации. Поэтому для большинства баз сжатие
может быть довольно эффективным и позволяет сократить объем
хранимых данных в несколько раз. PostgreSQL сжимает данные
в TOAST-таблицах, но небольшие текстовые поля, умещающиеся
в странице, не сжимаются. Сжатие может быть полезно не только для
таблиц, но и для индексов по текстовым ключам или для индексов
с большим количеством повторяющихся значений.
Помимо очевидного плюса — экономии места, сжатие может также
увеличить быстродействие системы по двум причинам. Во-первых,
сокращается объем дискового ввода-вывода. Во-вторых, улучшается
кучность хранения, что увеличивает вероятность последовательного
чтения.
Работать со сжатыми данными в общей памяти сервера (в буферном
кеше) непроизводительно, поэтому логично выполнять сжатие
страницы при сохранении грязного буфера и разжимать ее при чтении
в буферный кеш.
4
Реализация сжатия
буферный кеш
файл отображения
.cfm 1 Мбайт
сегмент слоя данных
Буферный кеш для эффективности использует страницы
фиксированного размера (обычно 8 Кбайт), а сжатые страницы
имеют разный размер. При сохранении страница может не уместиться
на прежнее место, поэтому вводится дополнительный уровень
адресации — отображение страниц.
Как и в несжатых табличных пространствах, данные хранятся
в файлах-сегментах, и для каждого из них имеется своя карта
отображения страниц. Карта имеет размер 1 Мбайт (32 байта на
заголовок + по 8 байт на каждый из 131072 указателей) и поэтому
обычно умещается в оперативной памяти.
5
Реализация сжатия
мусорная страница
буферный кеш
сегмент слоя данных
файл отображения
.cfm 1 Мбайт
При записи (в частности, при выполнении контрольной точки) страница,
содержащаяся в грязном буфере, сжимается в соответствии
с настройками сжатия и добавляется в конец сегмента, а в указатель
в файле отображения заносится новая позиция страницы. После этого
область файла данных, в которой раньше находилась страница,
становится ненужной. Такие мусорные страницы будут накапливаться,
что приведет к увеличению фрагментации хранимых данных.
Заметим, что если изменилось значительное число страниц отношения,
перед определением степени фрагментации имеет смысл выполнить
контрольную точку, чтобы все грязные буферы сбросились на диск.
6
Использование CFS
CREATE TABLESPACE ...
WITH (compression=on)
WITH (compression=zstd|pglz|zlib|lz4)
Системные отношения не сжимаются
Проверка контрольной суммы — при чтении в буфер
pg_checksums и pg_basebackup не проверяют
Сжатие можно включить только на уровне табличного пространства и
только в момент его создания, при этом нужно задать алгоритм сжатия.
Изменить факт и алгоритм сжатия в дальнейшем нельзя.
Поддерживаются библиотеки zstd, pglz, zlib, lz4. По умолчанию
используется алгоритм zstd.
Системные отношения никогда не сжимаются — для соответствующих
сегментов не создаются файлы отображения и механизм сжатия не
используется.
Проверка контрольных сумм для сжатых страниц невозможна, она
происходит только при чтении страницы в буферный кеш, а утилиты
pg_checksums и pg_basebackup контрольные суммы страниц не
проверяют.
8
Объем данных
Стандартные функции
pg_relation_size
pg_table_size
pg_indexes_size
pg_total_relation_size
pg_database_size + файлы отображения
pg_tablespace_size + файлы отображения + pg_compression
работают корректно
Стандартные функции pg_*_size, возвращающие занимаемый на диске
объем, корректно работают со сжатыми табличными пространствами.
В объеме базы данных учитываются файлы отображения, а в объеме
табличного пространства — файлы отображения и служебный файл
pg_compression.
9
Степень сжатия
Параметры
cfs_level = 1 0 — без сжатия, 1–100 – степень сжатия
cfs_compress_temp_relations = off
Функции
cfs_estimate прогноз степени сжатия
(среднее по 10 первым страницам)
cfs_compression_ratio фактическое сжатие по всем сегментам
Уровень сжатия настраивается параметром cfs_level. Значение 0
отключает сжатие, значение 1 (по умолчанию) соответствует
максимальной скорости, значения от 2 до 100 определяют уровень
сжатия. Максимальное значение зависит от используемого алгоритма.
Временные таблицы по умолчанию не сжимаются. Параметр
cfs_compress_temp_relations позволяет включить их сжатие, это может
быть полезно при большом объеме временных таблиц.
Функция cfs_estimate оценивает степень сжатия, анализируя десять
первых страниц таблицы. Функция cfs_compression_ratio возвращает
фактическую степень сжатия таблицы. Степень сжатия – это отношение
объема несжатых данных к объему сжатых, в данном случае объем
страниц в буферном кеше делится на объем сжатых страниц,
сохраненных в файле.
11
Фрагментация
мусорные страницы
процент мусора > cfs_gc_threshold
или файл > 2 Гбайт
Чтобы бороться с фрагментацией, в Postgres Pro Enterprise реализован
механизм сбора мусора.
Файл данных подлежит обработке, если суммарный размер мусорных
страниц превышает cfs_gc_threshold процентов от размера файла или
размер файла больше 2 Гбайт. Одновременно с файлом данных
обрабатывается соответствующий файл отображения.
12
Сбор мусора
cfs file lock
< 3 Гбайт не ждет
На время обработки файл данных полностью блокируется — ставится
легкая блокировка cfs file lock в исключительном режиме, она
запрещает обслуживающим процессам обращаться к файлу. Если не
удается получить блокировку немедленно, а размер файла менее 3
Гбайт, процедура сбора мусора его пропустит, а если файл имеет
больший размер — будет ждать получения блокировки.
Затем нужные страницы копируются в новый файл данных и строится
новый файл отображения. По окончании обработки старые файлы
удаляются, а новые переименовываются; это происходит атомарно.
Обслуживающие процессы устанавливают на файл ту же блокировку,
но в разделяемом режиме, чтобы процесс сбора мусора дождался
окончания работы с файлом, прежде чем начинать дефрагментацию.
13
Сбор мусора
Настройки
cfs_gc = on
cfs_gc_workers = 1
cfs_gc_threshold = 50
cfs_gc_delay = 0
cfs_gc_period = 5000ms
Запуск
cfs_start_gc( число-процессов ), 0 синхронно
cfs_gc_relation( отношение )
Сбор мусора выполняется одним или несколькими процессами
в ручном или фоновом режиме.
По умолчанию фоновый сбор мусора включен (cfs_gc = on) и
использует один рабочий процесс (cfs_gc_workers = 1).
Если выключить фоновый сбор (cfs_gc = off) и задать параметр
cfs_gc_workers = 0, можно вызовом функции cfs_start_gc(0) запустить
сбор мусора синхронно, а вызовом cfs_start_gc(N) — асинхронно N
процессами. Функция cfs_gc_relation собирает мусор в файлах
определенного отношения, возвращая число обработанных файлов.
Параметр cfs_gc_threshold задает минимальный процент мусора, при
котором файл размером до 2 Гбайт подлежит обработке (файлы
больше 2 Гбайт обрабатываются всегда). Эти условия действуют
независимо от способа запуска.
После обработки каждого файла процесс приостанавливается на
cfs_gc_delay миллисекунд. По окончании обработки всех файлов
процесс бездействует cfs_gc_period миллисекунд.
При ручном запуске можно задать все упомянутые параметры на
уровне сеанса, чтобы, например, обработать файлы с меньшим
уровнем фрагментации или сделать обработку более интенсивной.
14
Сбор мусора
Мониторинг
cfs_fragmentation (отношение)
cfs_gc_activity_scanned_files
cfs_gc_activity_processed_files
cfs_gc_activity_processed_pages
cfs_gc_activity_processed_bytes
Для мониторинга процессов сбора мусора имеется несколько функций.
Статистика накапливается с момента запуска сервера.
Важно, чтобы сбор мусора выполнялся регулярно, иначе файлы
отношений будут неограниченно расти, что приведет к падению
производительности, а в дальнейшем к недостатку свободного места
на диске. Поэтому рекомендуется не отключать фоновый сбор и при
необходимости настроить его частоту и производительность.
16
Итоги
Сжатие настраивается на уровне табличных пространств
Можно выбирать алгоритм и управлять степенью сжатия
Встроенный механизм сбора мусора сокращает объем
хранимых данных
17
Практика
1. Создайте сжатое табличное пространство, использующее
алгоритм zstd с максимальной степенью сжатия 14.
2. Поместите копии таблиц демобазы в сжатое табличное
пространство. Насколько уменьшился их размер?
3. Удалите сжатое пространство.