paint-brush
Postgres TOAST: понимание механизма сжатия данных и его ограниченийк@timescale
7,544 чтения
7,544 чтения

Postgres TOAST: понимание механизма сжатия данных и его ограничений

к Timescale11m2023/11/03
Read on Terminal Reader

Слишком долго; Читать

В этой статье обсуждаются ограничения механизма сжатия данных PostgreSQL TOAST, который изначально был разработан для управления большими значениями на странице PostgreSQL. Хотя TOAST имеет свои преимущества, он не обеспечивает оптимизации эффективности хранения данных для современных приложений с большими наборами данных. В статье представлена функция столбчатого сжатия TimescaleDB как решение, позволяющее значительно уменьшить размер базы данных и одновременно повысить производительность запросов. Такой подход обеспечивает более эффективное хранение, что делает PostgreSQL более перспективным выбором для управления данными в современных приложениях.
featured image - Postgres TOAST: понимание механизма сжатия данных и его ограничений
Timescale HackerNoon profile picture


Если вы работаете с большими базами данных в Postgres , эта история покажется вам знакомой. По мере того как ваша база данных Postgres продолжает расти, ваша производительность начинает снижаться, и вы начинаете беспокоиться о месте хранения — или, точнее, о том, сколько вы за него заплатите. Вы любите PostgreSQL, но есть кое-что, что вам хотелось бы: высокоэффективный механизм сжатия данных.


PostgreSQL имеет своего рода механизм сжатия: ТОСТ 🍞. В этом посте мы познакомим вас с тем, как работает Postgres TOAST, и с различными стратегиями TOAST. Как бы нам ни нравился хороший TOAST, мы обсудим, почему это не та функция сжатия, которая вам нужна для уменьшения объема хранилища современных больших баз данных, и как, как энтузиасты PostgreSQL, которые мы здесь, в Timescale, решили создать более подходящий механизм сжатия для PostgreSQL, вдохновленный столбчатой структурой баз данных NoSQL.


Что такое Postgres TOAST?

Даже если TOAST (метод хранения негабаритных атрибутов) может уменьшить размер наборов данных, он не является традиционным механизмом сжатия данных. Чтобы понять, что такое TOAST, нам нужно начать с разговора о как данные хранятся в PostgreSQL .


Единицы хранения Postgres называются страницами и имеют фиксированный размер (по умолчанию 8 КБ). Наличие фиксированного размера страницы дает Postgres множество преимуществ, а именно простоту, эффективность и согласованность управления данными, но у него есть и обратная сторона: некоторые значения данных могут не поместиться на этой странице.


Именно здесь на помощь приходит TOAST. TOAST — это автоматический механизм, который PostgreSQL использует для эффективного хранения и управления значениями в Postgres, которые не умещаются на странице. Для обработки таких значений Postgres TOAST по умолчанию сжимает их, используя внутренний алгоритм. Если после сжатия значения по-прежнему слишком велики, Postgres переместит их в отдельную таблицу (называемую таблицей TOAST), оставив указатели в исходной таблице.


Как мы увидим далее в этой статье, вы можете изменить эту стратегию как пользователь, например, указав Postgres избегать сжатия данных в определенном столбце.


Типы данных, поддерживающие TOAST

Типы данных, которые могут подвергаться TOAST, в основном имеют переменную длину и могут превысить ограничения размера стандартной страницы PostgreSQL. С другой стороны, типы данных фиксированной длины, такие как integer , float или timestamp , не подвергаются TOAST, поскольку они удобно помещаются на странице.


Некоторые примеры типов данных, которые могут подвергаться TOAST:


  • json и jsonb

  • Большие text строки

  • varchar и varchar(n) (если длина, указанная в varchar(n) достаточно мала, значения этого столбца могут всегда оставаться ниже порога TOAST.)

  • bytea хранит двоичные данные

  • Геометрические данные, такие как path и polygon , и типы PostGIS, такие как geometry или geography


Как работает Postgres TOAST?

Понимание TOAST связано не только с концепцией размера страницы, но и с другой концепцией хранения данных Postgres: кортежами. Кортежи — это строки в таблице PostgreSQL. Обычно механизм TOAST срабатывает, если общий размер всех полей в кортеже превышает 2 КБ.


Если вы обратили внимание, вы, возможно, задаетесь вопросом: «Подождите, но размер страницы составляет около 8 КБ — почему такие накладные расходы?» Это связано с тем, что PostgreSQL предпочитает хранить несколько кортежей на одной странице: если кортежи слишком велики, на каждой странице помещается меньше кортежей, что приводит к увеличению количества операций ввода-вывода и снижению производительности.


Postgres также необходимо сохранять свободное пространство для размещения дополнительных операционных данных: на каждой странице хранятся не только данные кортежа, но и дополнительная информация для управления данными, такая как идентификаторы элементов, заголовки и информация о транзакциях.


Итак, когда совокупный размер всех полей в кортеже превышает примерно 2 КБ (или пороговый параметр TOAST, как мы увидим позже), PostgreSQL предпринимает действия, чтобы гарантировать эффективное хранение данных. TOAST решает эту проблему двумя основными способами:


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


  2. Внеочередное хранение. Если одно только сжатие недостаточно эффективно для уменьшения размера больших значений полей, Postgres перемещает их в отдельную таблицу TOAST. Этот процесс известен как «внеочередное» хранение, поскольку исходный кортеж в основной таблице больше не содержит больших значений полей. Вместо этого он содержит «указатель» или ссылку на расположение больших данных в таблице TOAST.



Алгоритм сжатия Postgres: pglz

Мы упоминали, что TOAST может сжимать большие значения в PostgreSQL. Но какой алгоритм сжатия использует PostgreSQL и насколько он эффективен?


pglz (PostgreSQL Lempel-Ziv) — это внутренний алгоритм сжатия по умолчанию, используемый PostgreSQL, специально разработанный для TOAST.


Вот как это работает очень простыми словами:


  • pglz пытается избежать повторения данных. Когда он видит повторяющиеся данные, вместо того, чтобы писать одно и то же снова, он просто указывает туда, где он писал это раньше. Такое «избегание повторений» помогает сэкономить место.


  • Когда pglz считывает данные, он запоминает часть недавно просмотренных данных. Это недавнее воспоминание называется «скользящим окном».


  • По мере поступления новых данных pglz проверяет, видел ли он эти данные в последнее время (в пределах своего скользящего окна). Если да, он записывает короткую ссылку вместо повторения данных.


  • Если данные новые или повторяются недостаточное количество раз, чтобы сделать ссылку короче фактических данных, pglz просто записывает их как есть.


  • Когда приходит время прочитать сжатые данные, pglz использует свои ссылки для получения исходных данных. Этот процесс довольно прямой, поскольку он ищет указанные данные и помещает их туда, где им место.


  • pglz не требует отдельного хранилища для своей памяти (скользящее окно); он создает его на ходу во время сжатия и делает то же самое при распаковке.


Эта реализация предназначена для обеспечения баланса между эффективностью сжатия и скоростью в рамках механизма TOAST. Что касается степени сжатия, эффективность pglz во многом будет зависеть от характера данных.


Например, часто повторяющиеся данные будут сжиматься гораздо лучше, чем данные с высокой энтропией (например, случайные данные). Вы можете увидеть степень сжатия в диапазоне от 25 до 50 процентов, но это очень общая оценка — результаты будут сильно различаться в зависимости от точного характера данных.


Настройка TOAST

Тост-стратегии

По умолчанию PostgreSQL использует механизм TOAST в соответствии с процедурой, описанной ранее (сначала сжатие, затем внешнее сохранение, если сжатия недостаточно). Тем не менее, могут быть сценарии, в которых вам может потребоваться более тонкая настройка этого поведения для каждого столбца. PostgreSQL позволяет вам сделать это, используя стратегии TOAST PLAIN , EXTERNAL , EXTENDED и MAIN .


  • EXTENDED : это стратегия по умолчанию. Это означает, что данные будут храниться вне очереди в отдельной таблице TOAST, если они слишком велики для обычной страницы таблицы. Перед перемещением данных в таблицу TOAST они будут сжаты для экономии места.


  • EXTERNAL : эта стратегия сообщает PostgreSQL хранить данные для этого столбца вне строки, если данные слишком велики, чтобы поместиться на обычной странице таблицы, и мы просим PostgreSQL не сжимать данные — значение будет просто перемещено в Стол TOAST как есть.


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


  • PLAIN : использование PLAIN в столбце указывает PostgreSQL всегда хранить данные столбца в строке в основной таблице, гарантируя, что они не будут перемещены в внестрочную таблицу TOAST. Учтите, что если данные превысят размер страницы, INSERT завершится неудачей, поскольку данные не поместятся.


Если вы хотите проверить текущие стратегии конкретной таблицы, вы можете запустить следующее:


 \d+ your_table_name


Вы получите такой вывод:

 => \d+ example_table                     Table "public.example_table" Column |    Data Type  | Modifiers | Storage | Stats target | Description ---------+------------------+-----------+----------+--------------+-------------  bar  | varchar(100000) |      | extended |       |


Если вы хотите изменить настройки хранилища, вы можете сделать это с помощью следующей команды:

 -- Sets EXTENDED as the TOAST strategy for bar_column ALTER TABLE example_blob ALTER COLUMN bar_column SET STORAGE EXTENDED;

Ключевые параметры

Помимо описанных выше стратегий, эти два параметра также важны для управления поведением TOAST:


TOAST_TUPLE_THRESHOLD


Это параметр, который устанавливает порог размера, когда операции TOAST (сжатие и внешнее хранение) рассматриваются для кортежей слишком большого размера.


Как мы упоминали ранее, по умолчанию TOAST_TUPLE_THRESHOLD имеет значение примерно 2 КБ.


TOAST_COMPRESSION_THRESHOLD


Это параметр, который определяет минимальный размер значения, прежде чем Postgres рассмотрит возможность его сжатия во время процесса TOAST.


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


Собираем все это вместе

TOAST_TUPLE_THRESHOLD — это точка срабатывания. Когда совокупный размер полей данных кортежа превышает этот порог, PostgreSQL оценит, как им управлять, на основе установленной стратегии TOAST для его столбцов, учитывая сжатие и внешнее хранение. Точные предпринятые действия также будут зависеть от того, превосходят ли данные столбца TOAST_COMPRESSION_THRESHOLD :


  • EXTENDED (стратегия по умолчанию): если размер кортежа превышает TOAST_TUPLE_THRESHOLD , PostgreSQL сначала попытается сжать слишком большие столбцы, если они также превышают TOAST_COMPRESSION_THRESHOLD . Если при сжатии размер кортежа станет ниже порогового значения, он останется в основной таблице. В противном случае данные будут перемещены во внешнюю таблицу TOAST, а основная таблица будет содержать указатели на эти внешние данные.


  • MAIN : если размер кортежа превышает TOAST_TUPLE_THRESHOLD , PostgreSQL попытается сжать столбцы слишком большого размера (при условии, что они превышают TOAST_COMPRESSION_THRESHOLD ). Если сжатие позволяет кортежу поместиться в кортеж основной таблицы, он остается там. Если нет, данные перемещаются в таблицу TOAST в несжатом виде.


  • EXTERNAL : PostgreSQL пропускает сжатие независимо от TOAST_COMPRESSION_THRESHOLD . Если размер кортежа превышает TOAST_TUPLE_THRESHOLD , столбцы слишком большого размера будут храниться вне строки в таблице TOAST.


  • PLAIN : данные всегда хранятся в основной таблице. Если размер кортежа превышает размер страницы (из-за очень больших столбцов), возникает ошибка.


Стратегия

Сжать кортеж if > TOAST_COMPRESSION_THRESHOLD

Сохранять вне очереди, если кортеж > TOAST_TUPLE_THRESHOLD

Описание

РАСШИРЕННЫЙ

Да

Да

Стратегия по умолчанию. Сначала сжимает, затем проверяет, требуется ли внешнее хранилище.

ОСНОВНОЙ

Да

Только в несжатом виде

Сначала сжимается, а если размер по-прежнему слишком велик, перемещается в таблицу TOAST без сжатия.

ВНЕШНИЙ

Нет

Да

Всегда переходит в режим TOAST, если размер слишком велик, без сжатия.

ПРОСТОЙ

Нет

Нет

Данные всегда остаются в основной таблице. Если кортеж превышает размер страницы, возникает ошибка.


Почему TOAST недостаточно в качестве механизма сжатия данных в PostgreSQL

К настоящему моменту вы, вероятно, поймете, почему TOAST — это не тот механизм сжатия данных, который вы хотели бы иметь в PostgreSQL. Современные приложения подразумевают, что ежедневно обрабатываются большие объемы данных, а это означает, что базы данных быстро (пере)растут.


Такая проблема не была столь заметной, когда десятилетия назад был создан наш любимый Postgres, но сегодняшним разработчикам нужны решения для сжатия, позволяющие уменьшить объем хранилища их наборов данных.


Хотя TOAST включает сжатие в качестве одного из своих методов, важно понимать, что его основная роль не заключается в том, чтобы служить механизмом сжатия базы данных в традиционном смысле. TOAST — это, главным образом, решение одной проблемы: управление большими значениями в структурных рамках страницы Postgres.


Хотя этот подход может привести к некоторой экономии места для хранения за счет сжатия определенных больших значений, его основная цель не состоит в оптимизации пространства для хранения по всем направлениям.


Например, если у вас есть база данных размером 5 ТБ, состоящая из небольших кортежей, TOAST не поможет вам превратить эти 5 ТБ в 1 ТБ. Хотя в TOAST есть параметры, которые можно настраивать, это не превратит TOAST в универсальное решение для экономии места.


Существуют и другие проблемы, присущие использованию TOAST в качестве традиционного механизма сжатия в PostgreSQL, например:


  • Доступ к данным TOAST может привести к увеличению накладных расходов, особенно если данные хранятся вне очереди. Это становится более очевидным, когда часто осуществляется доступ к большому тексту или другим типам данных, поддерживающим TOAST.


  • В TOAST отсутствует удобный для пользователя механизм высокого уровня для определения политик сжатия. Он не предназначен для оптимизации затрат на хранение или облегчения управления хранилищем.


  • Сжатие TOAST не предназначено для обеспечения особенно высоких степеней сжатия. Он использует только один алгоритм ( pglz ) со степенью сжатия, обычно варьирующейся от 25 до 50 процентов.

Добавление сжатия столбцов в PostgreSQL с помощью шкалы времени

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


Добавив политику сжатия в большие таблицы, вы можете уменьшить размер базы данных PostgreSQL до 10 раз (достигнув степени сжатия +90 процентов) .


Определяя политику сжатия по времени, вы указываете, когда данные следует сжимать. Например, вы можете автоматически сжимать данные старше семи (7) дней:


 -- Compress data older than 7 days SELECT add_compression_policy('my_hypertable', INTERVAL '7 days');


С помощью этой политики сжатия Timescale преобразует таблицу. перегородки ( которые в Timescale также создаются автоматически ) в столбчатый формат, незаметно объединяя множество строк (1000) в массив. Чтобы повысить сжимаемость, Timescale будет применять разные алгоритмы сжатия в зависимости от типа данных:


  • Компрессия Gorilla для поплавков

  • Дельта-дельта + Простой-8b с кодирование длин серий сжатие временных меток и других целочисленных типов

  • Сжатие словаря всей строки для столбцов с несколькими повторяющимися значениями (+ LZ-сжатие сверху)

  • Сжатие массива на основе LZ для всех остальных типов


Эта конструкция столбчатого сжатия предлагает эффективное и масштабируемое решение проблемы больших наборов данных в PostgreSQL. Это позволяет вам использовать меньше места для хранения большего количества данных без ущерба для производительности запросов (это улучшает ее). А в последних версиях TimescaleDB вы также можете INSERT , DELETE и UPDATE непосредственно поверх сжатых данных.

Заворачивать

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


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


Автор Карлота Сото .