В конце августа вышел релиз распределённой СУБД Apache Cloudberry 2.0.0 — опенсорс‑проекта, который в режиме инкубации находится в Apache Soft Foundation (ASF). В новой версии состоялся переход на кодовую базу PostgreSQL 14, а также было добавлено множество улучшений.
При этом на Хабре до сих пор незаслуженно мало статей, посвящённых этой СУБД. Мы решили исправить это совместно с Максом Янгом, техническим лидером и участником PPMC Apache Cloudberry (Incubating). Эти статьи созданы по материалам совместного митапа Yandex Cloud Data Platform — про Greenplum® и не только. В этот раз пройдёмся по базовым особенностям и функциям этой СУБД, а в следующий — доберёмся до advanced‑возможностей.
Из истории Apache Cloudberry
Apache Cloudberry — это MPP‑СУБД с открытым исходным кодом, созданная первоначальной командой разработчиков базы данных Greenplum.
Основной подход заключается в повторном использовании всей распределённой платформы MPP от Greenplum, но с заменой встроенного ядра на более новое ядро PostgreSQL. С тех пор как исходный код Greenplum стал открытым, многие команды и компании используют систему в производственных средах как основную аналитическую СУБД или просто как PostgreSQL большей ёмкости.
Greenplum закрывается, да здравствует Cloudberry
Cloudberry была создана разработчиками в начале июня 2022 года, а в 2024 году сервис добавлен в опенсорс. Одновременно проект Greenplum на GitHub сразу после этого был заархивирован и стал closed‑source — продуктом с закрытым кодом.
Уже через два месяца у проекта на Cloudberry появился первый контрибьютор в GitHub и произошёл первый пул‑реквест. В октябре 2024 года разработчики присоединились к Apache Incubator, а проектные репо были перенесены в Apache в ноябре. Там на GitHub сейчас более 1000 звёзд.
Подробнее о ключевых этапах таймлайна

#1 2022: Выпуск продукта
Cloudberry создана в 2022 году как ответвление Greenplum 7 Beta 3. Продукт — не просто замена Greenplum, он включает множество продвинутых функций и особенностей, обеспечивая управление данными в различных форматах и мультимодальные аналитические вычисления.
#2 2023: Открытый исходный код
В 2023 году Cloudberry открыла свой исходный код под лицензией Apache License V2.0. Исходный код размещён на GitHub. Cloudberry совместима с Greenplum, что позволяет пользователям работать с Cloudberry так же, как с Greenplum.
#3 2024: Вступление в инкубатор ASF
В октябре 2024 года Cloudberry была принята в инкубатор Apache. Это обеспечит развитие Cloudberry в соответствии с принципами открытого управления и ориентации на сообщество, что позволит избежать контроля со стороны одного вендора, как в случае с Greenplum.
При этом ответственность за разработку Greenplum переходила из рук в руки так часто, что это вызывало озабоченность партнёров по экосистеме, а также участников опенсорс‑сообщества. СУБД Greenplum теряла свой темп развития: она отставала от актуальных требований к производительности и не давала возможности для работы в облаке, не поддерживала озёра данных и т. д.
Ещё более важно: проект Greenplum всегда контролировался одним вендором — и не существовало модели открытого управления, которая бы позволяла сообществу участвовать в принятии решений и голосовании.
Архитектура Cloudberry

Чуть подробнее о деталях архитектуры
В сервисе есть «Координатор» (Coordinator Node) и несколько сегментов.
Также есть парсер, оптимизатор, каталог, диспетчер запросов и распределённая система. Данные переходят через Interconnect и записываются в клиент. Это типовая архитектура Cloudberry.
Для высокой доступности ввели зеркальные нагрузки с помощью архитектуры Shared-Nothing без общих ресурсов. Её полностью интегрировали с PostgreSQL 14.4.
В такой архитектуре нет мастер-узла, потому что используется автоматический перехват управления в случае сбоев. Это реализуется с помощью etcd и FTS.
На программном уровне Cloudberry обеспечивает полную архитектуру высокой доступности как для узлов данных, так и для вычислительных узлов:
etcd используется для хранения информации о топологии кластера и метаданных о его состоянии.
Узлы «Координатор» и «Резервный» (Standby) постоянно синхронизируют журналы. При отказе узла «Координатор» происходит автоматическое переключение без участия человека.
Узлы данных используют технологию зеркалирования для обеспечения высокой доступности: синхронизация происходит через WAL-журнал.
Обновлённое ядро СУБД и функции платформы
Поскольку ядро СУБД было обновлено (по сравнению с используемым в Greenplum), оно поддерживает новые типы и функции:
Multi‑range, JSON, JSONB, XML и т. д.
UPSERT: INSERT … ON CONFLICT syntax
Hash Partitioned Table
REINDEX concurrently
Инкрементальная сортировка для поддержки данных, которые уже отсортированы (это даёт выигрыш в производительности)
Сортировка использует abbreviated keys
Аутентификация сильными паролями на основе SCRAM‑SHA-256
-
И другие функции, которые поддерживаются в PostgreSQL 14.4:
System views:
pg_stat_*
Bloom filter для brin index
В зависимости от способа зеркалирования узлов можно выделить две схемы резервирования:
Взаимное резервирование — более высокая надёжность
Перекрёстное резервирование — меньшие потери производительности
Векторный движок выполнения запросов
Реализован векторный движок выполнения запросов. По умолчанию он включён, но может быть отключён с помощью параметра vector.enable_vectorization
. Он поддерживает:
Типы int2, int4, int8, float4, bool, char, tid, date, time, timestamp, timestamptz, varchar, text и т. д.
Специальные операторы векторизации: Scan, Agg, Foreign Scan, Result, Append, Subquery, Sequence, Nested Loop Join, Hash Join, Sort, Foreign Scan, Expression и т. д.
В этом движке данные передаются в пакетном режиме, который может обрабатывать их последовательно.
В проекте используются алгоритмы для Hash Join и агрегации. Сервис не просто следует режиму PostgreSQL, а использует свои высокоэффективные алгоритмы.
Используются потоки вместо процессов для ускорения.
Векторный движок выполнения улучшает утилизацию CPU.
Новое колоночное хранение PAX даёт векторному движку выполнения больше возможностей для использования современных аппаратных оптимизаций, таких как SIMD, и компиляции.
Для колоночного хранения коэффициент сжатия может быть выше, чем традиционные алгоритмы zstd.
Также есть поддержка запросов через множественные кластеры
С помощью FDW можно выполнять запросы между несколькими кластерами Cloudberry. В отличие от
postgres_fdw
, данные при этом не собираются узлом Query Dispatcher.С помощью подсказки
gp_foreign_server
можно заставить оптимизатор выполнять операции соединения на локальном кластере.Оптимизатор передаёт операторы Join и Agg на целевой кластер Cloudberry, что снижает объём передачи промежуточных данных.
Aggregation Pushdown
Это важно для OLAP‑сценариев. С помощью преобразования запросов Aggregation Pushdown мы увеличиваем пространство поиска. Оптимизатор переписывает запрос и добавляет новый план, дальше оценивает его стоимость: если детально, то он выполняет агрегацию (Agg) до соединения (Join), тем самым сокращая объём данных для соединения и улучшая время выполнения.
Решение об использовании Aggregate Pushdown в конечном итоге принимается в результате сравнения затрат разных планов и выбора наилучшего плана.
Производительность при выполнении запросов OLAP удалось значительно повысить.
Параллельное исполнение
Это фича PostgreSQL, когда один инстанс использует несколько процессов для повышения производительности. У нас в Cloudberry это тоже поддержано.
Цель — задействовать несколько ядер CPU для обработки одного запроса, что повышает производительность и позволяет сократить количество развёртываемых инстансов.
Если у нас большой объём данных, то планировщик использует мультипроцессную поддержку для исполнения.
Число параллельных потоков определяется объёмом данных.
Поддерживаемые операции:
Последовательное сканирование (Sequence Scan)
Индексное сканирование (Index Scan)
Сканирование только по индексу (Index Only Scan)
Битмап‑сканирование кучи (Bitmap Heap Scan)
Append (конкатенация подзапросов)
Хеш‑соединение (Hash Join)
Соединение вложенными петлями (Nested Loop Join)
Слияние‑соединение (Merge Join)
В такой архитектуре есть процесс‑лидер, который несёт ответственность за запуск других процессов‑работников. Они сканируют таблицу ввода‑вывода и проводят локальную агрегацию.
Материализованное представление инкрементов и переписывание запросов
Что тут интересного:
Возможность получать инкрементную часть обновлений данных. В триггерах выделяются новые и изменённые строки данных. Это позволяет упростить операцию.
Переписывание запросов с использованием материализованного представления может быть синхронным или асинхронным.
Для обеспечения семантической согласованности используются разные правила переписывания (организации запросов) для различных операторов запросов: Filter, Join, Agg.
В пути выполнения запроса, сгенерированном оптимизатором, «поддерево», соответствующее материализованному представлению, может быть заменено на поддерево, использующее материализованное представление. Оптимизатор выбирает план с наименьшей стоимостью на основе оценки затрат.
Если материализованное представление обновляется асинхронно, при переписывании запроса нужно учитывать только инкрементную часть обновлений.
Алгоритм не слишком сложный. Для операции Join есть разные варианты алгоритмов.
PAX: гибридный строково-колоночный формат хранения данных
Ещё одна важная новинка: обнаружилось, что для движка векторизации необходимо реализовать РАХ — хранение на основе блоков. Данные всей таблицы разбиваются на блоки и хранятся в нескольких файлах. В Greenplum уже есть Append optimized column oriented (AOCO), но если у нас в таблице 1000 столбцов, то будет создано такое же количество файлов. Поэтому для AOCO возникает необходимость в большом количестве дорогих операций открытия‑закрытия файлов.
Чтобы этого избежать, мы используем РАХ. Нам не нужно разбивать таблицы на разные файлы. Мы работаем в блоковом стиле, в котором всё организовано по группам.
Таблицы разбиваются на группы. В каждой группе используются столбцы, и мы можем использовать push‑down‑проекцию столбцов. Если я хочу опросить столбец таблицы, мне не нужно подкачивать другие столбцы: достаточно обратиться к нужному столбцу.
Если есть какие‑то фильтры, то мы можем их использовать, чтобы пропускать определённые блоки, которые не нужны. Также можем использовать комбинированные запросы на ввод‑вывод для непрерывных столбцов.
Возможности:
Pushdown‑фильтрация, проекция столбцов с поддержкой фильтров во время выполнения.
Объединённые I/O‑запросы по идущим подряд столбцам.
Поддержка всех типов данных — фиксированной и переменной длины.
Сжатие данных и кодирование.
Пропуск блоков.
Родная поддержка векторизации.
TOAST для хранения крупных данных.
Кластеризация и упорядочение по столбцам.
Результаты тестирования РАХ. Технология PAX даёт значительное повышение производительности.

Всего в таблице было 1600 столбцов. Технология для обработки таблицы АОСО в данном случае проигрывает по производительности РАХ.
Поддержка UnionStore
UnionStore — это автономный heap‑сервис, состоящий, в свою очередь, из двух сервисов: WAL и Page.
WAL‑сервис включает несколько подсервисов: Safekeeper leader и несколько Safekeeper followers. Данные транслируются через WAL‑сервис. Через Safekeeper они попадают в Page‑сервис, который создаёт страницу в разных версиях. Вычислительный узел берёт данные с Page‑сервера определённой версии.
Встроенная защита данных
В Cloudberry есть встроенное средство защиты данных на разных уровнях.
Уровень 1. Унифицированная аутентификация
Поддерживается аутентификация шифрованного текста и множество алгоритмов шифрования. Также используется пароль для защиты. Можно вводить политики по составу и количеству попыток ввода некорректных паролей.
Поддержка аутентификации по шифротексту, разных алгоритмов шифрования и хеширования (MD5, SHA-256 и др.)
Аутентификация Kerberos
Проверка сложности пароля (длина, наличие буквенно‑цифровых и специальных символов и т. д.)
Политики паролей (максимальное число неудачных попыток, блокировка после ошибок, ограничение повторных входов)
Дополнительные режимы аутентификации, например LDAP
Уровень 2. Аутентификация по требованию
Разные уровни разрешений и привилегий для разных групп пользователей
Определение типов привилегий (SELECT, UPDATE, EXECUTE, OWNERSHIP и т. д.) на разных уровнях объектов (схемы, таблицы, представления и т. д.) для разных пользователей
Поддержка Row‑Level Security
Белые списки пользователей для разных вычислительных кластеров
Также поддерживается безопасность на низких уровнях.
Что касается хранения, поддерживаются разные алгоритмы шифрования.
Безопасное хранение:
-
Компонент pgcrypto для шифрования данных:
Асимметричное: SM2, RSA
Симметричное: SM4, AES
Хеширование: SM3
Прозрачное шифрование базы данных (TDE) — алгоритмы: AES, SM4
Поддерживается динамическое маскирование:
Обеспечение безопасного обмена данными при защите конфиденциальной информации в сценариях разработки, тестирования и песочниц
Поддержка алгоритмов маскирования Random, Flaking, SHA, пользовательских функций и других подходов для динамического маскирования данных
Всё это делается в Sandbox, для того чтобы протестировать защиту.
Управление неструктурированными данными: таблица каталогов
Как вы знаете, база данных поддерживает и неструктурированные данные. Для управления такими данными используется следующая технология:
Пользователь загружает неструктурированные данные.
Создаются индекс и каталог, чтобы сгенерировать метаданные. После этого БД знает, откуда и из каких файлов брать эти данные.
БД переносит файл с данными в пространство с таблицами. Табличное пространство может быть локальным или облачным (DFS).
Пользователь может с помощью простых запросов получать метаданные файлов. Например, путь или размер, дату и время последнего обновления.
Когда пользователь получит эти метаданные, он может ввести их в движок и использовать для различных задач.
Функции Cloudberry
Функции, обеспечивающие высокую производительность
REINDEX CONCURRENTLY
Aggregation Pushdown
CREATE STATISTICS — статистика OK и BN/ANY
Инкрементальная сортировка
Инкрементальная сортировка для оконных функций
Конвейерная обработка запросов (Query Pipelining)
BRIN‑индексы (multi‑minmax, Bloom)
Параллелизм запросов
Сокращённые (abbreviated) ключи для сортировки
Поддержка WAL для хеш‑индексов
Продвижение агрегации в
postgres_fdw
Добавление столбца без перезаписи всей таблицы
Фильтрация на этапе выполнения для соединений (Runtime Filter for Join)
Индексное сканирование для append‑only‑таблицы
Функции безопасности
Прозрачное шифрование данных (TDE)
Доверенные расширения (Trusted Extensions)
Аутентификация SCRAM‑SHA-256
Шифрованное TCP/IP‑соединение при использовании GSSAPI
Политика безопасности на уровне строк (Row‑Level Security)
Общие функции
Поддержка EXPLAIN (ANALYZE)
Multi‑range
Удаление B‑tree‑индекса «снизу вверх» (bottom‑up index deletion)
Покрывающий индекс для GIST (INCLUDE)
Функция топ‑агрегации
crude_max_range
CREATE ACCESS METHOD
Сжатие LZ4 для TOAST‑таблиц
Атомарная подписка (Atomic Subscription)
Настройка максимального срока хранения WAL для слотов репликации
Проверка целостности бэкапа (
pg_verifybackup
)Возможность требовать SCRAM‑привязку канала (channel binding)
VACUUM в interleaving mode
Аутентификация по сертификатам через
pg_hba.conf
IPv6
COPY FROM/WHERE
VACUUM/ANALYZE для Lookup‑таблицы
Таблицы с хеш‑партиционированием (HASH partitioned tables)
CTE‑рекурсия (SEARCH и CYCLE)
Параметры процедур OUT
Ограничения CHECK для внешних таблиц
Расширение timeline для
pg_terminate_backend
Автофейловер координатора
Поддержка развёртывания в Kubernetes