|
Professor Seleznov
|
 В мае 2024 года Broadcom заархивировал публичный репозиторий Greenplum: последний коммит остался на месте, дальнейшая разработка ушла в закрытый репозиторий, enterprise-сборка теперь доступна только по подписке. Greenplum как живой OSS-проект остановился — но сам код, выпускавшийся с октября 2015-го, остался под Apache 2.0. Именно на этой кодовой базе стартанули остальные форки. Те, кто строил аналитику на Greenplum, оказались перед развилкой. Сообщество разделилось: Apache Cloudberry (incubating), Greengage DB от Arenadata, WarehousePG от EDB. Каждый форк продолжает линию, но в собственной траектории. У компании с боевым кластером появляется конкретный вопрос: переехать/остаться в одном из этих форков или мигрировать на принципиально другую платформу и архитектурную парадигму. Эта статья (сага из трех эпизодов) будет полезна, если у вас уже есть Greenplum-кластер, вы понимаете его DDL/ETL/backup-процессы и хотите оценить, насколько болезненным будет переход на StarRocks. Также здесь я пытаюсь охватить миграцию с Greenplum на StarRocks как инженерный проект: что меняется в DDL, SQL, ETL и эксплуатации, где миграция почти механическая, а где придется перепроектировать решения. Поэтому статья ближе к техническому сборнику. В этой статье я не пытаюсь покрыть все возможные конфигурации Greenplum в разных компаниях — у каждой за эти 3–5 лет сложился свой путь и архитектура решений на Greenplum, поэтому я опираюсь на общие конструкции. Привет, Хабр! Меня зовут Александр, я DevRel команды Selena Lakehouse. Пишу про СУБД StarRocks, архитектуры Lakehouse и Streamhouse в Telegram-канале @starrocks_selena (https://t.me/starrocks_selena). Тут в целом мы стоим перед выбором:
 Остаться в семействе (Cloudberry, Greengage, WarehousePG): Плюсы: ✅ Самый низкозатратный путь по времени и бюджету: DDL и SQL переносятся почти 1:1, PL/pgSQL-логика продолжает работать, команда не учится заново, привычные инструменты (gpbackup, gp_*) остаются на месте. Минусы: ⚠ Архитектурные ограничения Greenplum переезжают вместе с продуктом: единственный master-узел, неотделимое от вычислений хранилище, операционная нагрузка от VACUUM/ANALYZE, ручное обновление materialized views (в Greenplum 6). Сменить продукт, оставив MPP-парадигму (ClickHouse, StarRocks) Плюсы: ✅ Современный движок: векторизация + pipeline-обработка; ✅ Auto-stats и auto-compaction вместо ручного VACUUM/ANALYZE; ✅ Декларативные ускорения: async MV с auto-rewrite (StarRocks) или Projections (ClickHouse) — там, где в Greenplum 6 был manual REFRESH; ✅ Нативная работа с внешними каталогами Iceberg/Delta/Hudi/Paimon/Hive. Минусы: ⚠ SQL-диалект меняется (MySQL у StarRocks, собственный у ClickHouse; переписываются DDL и SQL-функции), PL/pgSQL-логика мигрирует в UDF (Java/Python в StarRocks, Python в ClickHouse) либо во внешний оркестратор. Multi-statement BEGIN/COMMIT в StarRocks появились с v3.5 (Beta, июнь 2025), расширены в v4.0 — но с ограничениями относительно Greenplum-семантики (детали в A5). Сменить архитектуру в сторону Lakehouse (Trino + Iceberg или StarRocks в shared-data) Плюсы: ✅ Разделение хранения и вычислений с независимым масштабированием; ✅ Открытые форматы как Iceberg делают данные переносимыми между движками, единый storage-слой для DWH, ML и ad-hoc-аналитики. Главный выигрыш здесь не в скорости конкретного запроса, а в независимости данных от одного SQL-движка. Минусы: ⚠ Самая дорогая миграция по человеко-часам: перепроектирование схемы под Iceberg-партиционирование, переписывание ETL-пайплайнов, внедрение catalog-сервиса (Hive Metastore, Polaris), обучение команды новому стеку. Сюда же относится и операционная сложность Iceberg (snapshot management, compaction, orphan files). Первый путь (остаться в семействе форков) — отдельная тема, требует сравнения Cloudberry / Greengage / WarehousePG между собой, это уже тема коллег, кто плотно с этим занимается. Получается следующая развилка. Если берем второй путь, оставлять MPP-парадигму, для DWH-сценариев StarRocks к Greenplum ближе, чем ClickHouse, сразу по нескольким архитектурным моментам:
- Cascades-оптимизатор отрабатывает многотабличные JOIN-ы по той же логике, что ORCA в Greenplum — с переоценкой порядка по статистикам и broadcast/shuffle-решениями.
- Распределение задается явно на уровне DDL (DISTRIBUTED BY HASH(col) BUCKETS N) — у ClickHouse шардирование настраивается серверно.
- Репликация работает per-tablet — знакомая концепция после mirror-сегментов.
- План в EXPLAIN читается фрагментами с exchange-операторами вместо motion: знакомые приемы отладки перекосов, broadcast/redistribute-решений и колокации переносятся напрямую.
Если же выбран третий путь — менять архитектуру, в таком случае StarRocks и закроет все потребности, в shared-data режиме. Архитектурно это разделение хранения и вычислений: FE (frontend, метаданные) + CN (Compute Nodes, без хранения данных); сегменты с локальными дисками заменяются на объектное хранилище — S3, HDFS или любое S3-совместимое (MinIO, RustFS и т. д.). CN-узлы добавляются и снимаются без ребалансировки данных, потому что данных на них нет — только локальный кэш горячих сегментов. Вычисления масштабируются независимо от хранения. При этом query-движок остается тот же: SQL-диалект, DDL, Cascades-оптимизатор, EXPLAIN, операторы — все, что описано выше про путь 2.
Ограничение — режимы shared-nothing и shared-data взаимоисключающие в одной инсталляции, и переход между ними не поддерживается. В перспективе возможны изменения в этом вопросе, но это в будущем. Пока выбор режима— эторешение архитектурное и принимается на старте кластера.
Предположим, что решение о миграции уже принято, и даже решено мигрировать на StarRocks. Намеренно опускаем: сайзинг StarRocks-кластера, по этой теме будет отдельная большая статья, и различного рода бенчмарков*, сравнение StarRocks с Greengage/ClickHouse.
Этого добра (*) на просторах Habr полно, и некоторые авторы специализируются только на синтетических тестах в своих статьях, но, как показывает практика, все равно заказчик перед покупкой/внедрением делает пилот на своих данных и это рекомендуют все вендоры и интеграторы.
И саму миграцию данных как процесс — экспорт из Greenplum, загрузку в StarRocks (Stream Load / Broker Load / INSERT FROM FILES), валидацию, инкрементальный sync во время параллельной работы. Все это будет в Эпизод II. 11 областей миграции
 Прежде чем нырять в детали, посмотрим на картину целиком. Миграция Greenplum → StarRocks это не простое копирование DDL и данных. Обычно всплывают три слоя работ: схема хранения, SQL/процедуры и эксплуатационные процессы, не считая самой миграции данных. Задача разбивается на 11 ключевых областей (может и больше, у каждого свои нюансы), сгруппированных в три блока — от того, что меняется на уровне DDL, до того, что меняется в ежедневной эксплуатации. Блок A. Хранение и схема — пять областей. Здесь то, что нужно решить и описать в DDL: распределение и параллелизм запросов, формат хранения и компрессия, партиционирование, типы данных и их маппинг, PRIMARY KEY и ACID-семантика. Блок B. Запросы и семантика — три области. Здесь то, что переписывается на уровне SQL: хранимые процедуры и функции, SQL-диалект и его расхождения, materialized views и индексы. Блок C. Оперирование и нагрузка — три области.Здесь то, что меняется в эксплуатации: управление нагрузкой через resource groups, бэкап и репликация, VACUUM/ANALYZE и регулярное обслуживание. Блок А Любая миграция начинается с DDL: каждый CREATE TABLE в Greenplum нужно перевести на язык StarRocks. Ошибка в DDL потом дорого стоит: можно получить перекос, лишние пересылки, плохую компрессию или неудобный ETL-паттерн. От качества этого перевода зависит все остальное — производительность запросов, поведение ETL, корректность транзакционных гарантий. Главная разница на уровне DDL — StarRocks требует подумать о том, что в Greenplum было по умолчанию. В DDL Greenplum достаточно описать столбцы и distribution. В StarRocks к этому добавляется выбор табличной модели (Duplicate - по умолчанию/ Aggregate / Unique / Primary Key), число бакетов (BUCKETS N или auto-bucketing) и опциональное объявление колокации. A1. Распределение (Distribution by) В Greenplum распределение задается в DDL: DISTRIBUTED BY (col) — hash от столбца определяет, на каком сегменте окажется строка. Есть еще DISTRIBUTED RANDOMLY (равномерно без ключа) и DISTRIBUTED REPLICATED (вся таблица на каждом сегменте — для маленьких справочников). Когда JOIN идет по distribution-ключу обеих таблиц, пересылок нет — данные уже рядом. Иначе в плане появляется motion-оператор: Broadcast Motion рассылает маленькую таблицу всем сегментам, Redistribute Motion пересылает большую по новому ключу, Gather Motion собирает результат на master. Skew по distribution-ключу — главная операционная проблема. В StarRocks DDL читается похоже: DISTRIBUTED BY HASH(col) BUCKETS N. Главное отличие —это BUCKETS N: явное число бакетов на партицию (auto-bucketing; с v3.1 для Duplicate Key можно вообще опускать). В Greenplum параллелизм был привязан к числу сегментов; в StarRocks это отдельный механизм — разработчик/DBA сам решает, на сколько бакетов резать таблицу. Co-located JOIN в StarRocks объявляется явно через Colocation Group. В EXPLAIN вместо motion-операторов будут exchange-операторы — помимо классических Broadcast/Redistribute, StarRocks использует еще Bucket Shuffle и Colocate Exchange. Условный пример с DDL:
-- Greenplum CREATE TABLE fact_orders ( order_id bigint, customer_id bigint, amount numeric, dt date ) DISTRIBUTED BY (customer_id); -- StarRocks CREATE TABLE fact_orders ( order_id bigint, customer_id bigint, amount decimal(18,2), dt date ) DUPLICATE KEY(order_id) PARTITION BY date_trunc('day', dt) DISTRIBUTED BY HASH(customer_id) BUCKETS 32;
При миграции:
- Distribution key обычно переносится 1:1
- Bucket count: документация рекомендует 100 MB–1 GB сжатых данных на tablet (физическое воплощение bucket). Если получилось меньше числа BE-узлов, то надо взять число BE. С v2.5.7 есть auto-bucketing — можно положиться на него вместо ручного расчета.
- DISTRIBUTED REPLICATED прямого аналога не имеет: для маленьких справочников StarRocks обычно сам выбирает broadcast join (по умолчанию, исходя из размера таблицы), либо можно подсказать через broadcast hint.
A2. Форматы хранения и компрессия В Greenplum таблицы бывают трех типов хранения. Heap (по умолчанию) — обычный PostgreSQL-формат, под транзакционную нагрузку и UPDATE/DELETE. AO row (append-optimized) — для DWH с массовыми вставками. AO column — колоночное хранение с per-column компрессией (zlib, zstd). В StarRocks хранение по умолчанию колоночное. Таблицы специализируются под разные сценарии через табличную модель (Duplicate / Aggregate / Unique / Primary Key). Сжатие задается на уровне таблицы: LZ4 (по умолчанию, быстрая запись), ZSTD (выше степень сжатия), ZLIB, SNAPPY. С версии 3.2.3 в StarRocks есть hybrid row-column storage: данные хранятся одновременно колоночно и построчно — для быстрых point lookup. Фича помечена Preview в документации 4.x, работает только на Primary Key таблицах. Для миграции production ее пока не учитываем. По этой теме у меня на канале также выходил пост. При миграции:
- AO column-таблицы переезжают почти прозрачно, так как то же колоночное хранение и похожие кодеки;
- AO row превращается в Duplicate Key с колоночным форматом;
- heap с частыми UPDATE/DELETE — отдельный случай: нужна Primary Key модель или пересмотр архитектуры (если таблица была мелкая транзакционная — она может вообще не уехать на DWH-движок).
Компакция в StarRocks автоматическая, без manual VACUUM. A3. Партиционирование В Greenplum партиционирование задается при создании таблицы: PARTITION BY RANGE(col) или PARTITION BY LIST(col), с поддержкой multi-level (range внутри range). Для ETL используется ALTER TABLE ... EXCHANGE PARTITION — атомарная замена партиции на заранее подготовленную staging-таблицу.
Один из самых удачных механизмов Greenplum, как мне кажется. Атомарная подмена данных встроена в DDL движка и это задача, для которой в других OLAP-системах приходится собирать собственный паттерн, здесь решается одной командой.
В StarRocks партиционирование тоже задается в DDL: PARTITION BY RANGE(col) или PARTITION BY LIST(col). Дополнительно есть expression-partitioning (PARTITION BY date_trunc('day', dt)) — партиции создаются автоматически при вставке. И есть dynamic partitions для time-partitioning без ручного управления.Очень удобная вещь, я помню на первом месте работы в роли Oracle DBA, и первые мои задачи были ручное создание партиций и субпартиций, занимало много времени подготовить эти скрипты. При миграции:
- Range/list переносятся почти один в один;
- Expression-partitioning может упростить часть DDL: там, в Greenplum делали через cron-jobs или ручные ALTER TABLE ADD PARTITION;
- Прямого аналога ALTER TABLE EXCHANGE PARTITION в StarRocks нет. ETL-паттерн переписывается на TEMPORARY PARTITION + INSERT OVERWRITE: данные собираются во временную партицию, затем одной командой атомарно подменяется целевая.
Прямого аналога multi-level partitioning (SUBPARTITION) Greenplum в StarRocks нет — у SR partitioning одноуровневый. Аналогичные сценарии закрываются multi-column partitioning (PARTITION BY (col1, col2)) или expression-partitioning, который часто закрывает ту же потребность по time-иерархиям (year/month/day). A4. Типы данных и их маппинг На этом пункте я не хотел бы подробно останавливаться, так как большинство типов переносится один в один, но есть пара различий. Эти различия я вынес под спойлер, потому что в большинстве миграций это справочный, а не архитектурный блок.
Скрытый текст
- NUMERIC/DECIMAL. В Greenplum NUMERIC может быть с произвольной точностью (до 131 072 знаков до запятой). В StarRocks DECIMAL ограничен: DECIMAL128 до P=38 (стандарт), DECIMAL256 до P=76 (с v4.0). Без аргументов DECIMAL берёт дефолт DECIMAL(10, 0) — для большинства DWH-сценариев слишком мало, точность нужно указывать явно (DECIMAL(20,4) и т.п.). Перед миграцией нужно проверить, что значения укладываются в выбранные precision/scale — иначе переполнение.
- TIMESTAMP WITH TIME ZONE. В Greenplum это отдельный тип с явным учётом таймзоны. В StarRocks DATETIME хранит локальное время, конвертация идёт через session-параметр time_zone.
- JSONB → JSON. Greenplum хранит JSONB в бинарном формате; StarRocks — в формате JSON, который тоже хранится бинарно (функциональный аналог JSONB, не text JSON: whitespace и порядок ключей не сохраняются). На уровне SQL разница невелика, но синтаксис функций и индексация отличаются.
- ENUM, composite types, custom types в StarRocks отсутствуют. ENUM мигрирует в VARCHAR с проверкой допустимых значений на уровне ETL-слоя или приложения (CHECK constraints в StarRocks не поддерживаются). Composite types раскладываются на отдельные колонки, JSON-поле или STRUCT (semi-structured тип StarRocks с typed fields). Custom types — отдельная задача переписывания.
A5. PRIMARY KEY и ACID-семантика В Greenplum транзакционная семантика классическая PostgreSQL: ACID с уровнем изоляции READ COMMITTED, multi-statement транзакции (BEGIN ... COMMIT), ссылочная целостность (PRIMARY KEY, UNIQUE, CHECK работают; FOREIGN KEY. PRIMARY KEY и UNIQUE требуют, чтобы distribution-ключ был подмножеством constraint-столбцов), DDL внутри транзакции. Это позволяет писать ETL в том стиле, к которому привык pgsql-разработчик: начал транзакцию, выполнил несколько операций, закоммитил или откатил. В StarRocks ACID-семантика устроена иначе. Тип гарантий определяется табличной моделью, которая задается при создании таблицы:
- Duplicate Key — все строки сохраняются как есть, повторы не убираются. Подходит для логов и event-данных.
- Aggregate Key — преагрегация на вставке (SUM/MAX/MIN/REPLACE). Подходит для метрик.
- Unique Key — последняя запись побеждает (last-write-wins). Подходит для CDC-таблиц и slowly changing dimensions.
- Primary Key — ACID на уровне строки, поддерживает UPDATE/DELETE, оптимизирован под точечные запросы по ключу. Подходит для таблиц с частыми UPDATE/DELETE и нагрузок, где много точечных чтений.
Транзакционная гранулярность исторически была на уровне одной load-операции — каждый INSERT, Stream Load или Broker Load работал как отдельная атомарная транзакция. С v3.5появилась поддержка multi-statement транзакций со стандартным синтаксисом BEGIN ... COMMIT/ROLLBACK — изначально только для INSERT в одной БД. С v4.0она расширена до multi-table write-write транзакций (INSERT/UPDATE/DELETE). Для UPDATE/DELETE важно помнить, что в документации написано: поддержка относится к shared-data clusters. Однако это не полная замена для Greenplum-семантики. Существенные ограничения (проверил на последней версии v4.1.0):
- SELECT в той же транзакции не видит данные, измененные предыдущими DML (Limited READ COMMITTED).
- DML на одну таблицу — один тип: после UPDATE/DELETE нельзя сделать INSERT в ту же таблицу в той же транзакции.
- Только одна БД: cross-database транзакций нет.
- INSERT OVERWRITE в транзакции запрещен: атомарную подмену партиции придется делать отдельным шагом.
- Нет DDL внутри транзакции, savepoint, REPEATABLE READ.

Пример поддерживаемой мульти-табличной транзакции

Пример неподдерживаемой мульти-табличной транзакции При миграции:
- Выбор табличной модели — основное решение для каждой таблицы. Логи и сырые события в Duplicate Key. Метрики с агрегацией на вставке в Aggregate Key. Dimensions с семантикой последняя запись побеждает (last-write-wins) в Unique Key. Транзакционные таблицы и таблицы под частые UPDATE → Primary Key.
- Мульти-табличные транзакции в простых случаях (несколько INSERT в одной БД с возможным rollback) теперь покрываются нативно с v3.5. Сложные паттерны все равно переезжают в оркестратор с atomic-цепочками в Airflow / DolphinScheduler / dbt и компенсирующими шагами.
 Блок B. Запросы и семантика Главная разница между Greenplum и StarRocks на этом уровне — в расположении логики. В Greenplum значительную часть бизнес-логики можно реализовать прямо в базе: PL/pgSQL процедуры, тяжелые SQL-запросы с recursive CTE, manual REFRESH MV. В StarRocks движок намеренно «уже» по этим возможностям — часть работы переезжает в ETL-слой (Airflow, DolphinScheduler, dbt), часть — в UDF, а часть автоматизируется самим движком (auto-rewrite MV, auto-stats). B1. Хранимые процедуры и функции В Greenplum хранимые процедуры часто значительная часть рабочего кода в боевых системах. PL/pgSQL для основной логики, PL/Python для тяжелой обработки, тысячи строк в проде у крупных команд: ETL-функции с курсорами, аналитические функции с window-операциями, системные хранимки с DML и обработкой ошибок. В StarRocks CREATE PROCEDURE не поддерживается.
Issue #49439 с запросом на поддержку процедур закрыт без resolution; пользовательских stored procedures нет даже в 4.1. В 4.0 появились системные Iceberg-процедуры (rewrite_data_files, rewrite_manifests, expire_snapshots, remove_orphan_files) через CALL-синтаксис — но это maintenance для Iceberg-таблиц, не пользовательские процедуры. Для пользовательской логики — UDF на Java и Python.
Самое затратное по времени — переписывание ETL-функций в DAG-оркестратор. Здесь нет универсального решения: каждая процедура анализируется отдельно, разбивается на шаги, ставится в зависимости в оркестраторе или модели в dbt. Если в проде Greenplum накоплены тысячи строк PL/pgSQL — этот этап миграции будет самым трудозатратным, и часть логики вообще придется переосмысливать с нуля. Но есть и положительный момент, для команды миграция в эту сторону, кстати, дает архитектурные плюсы. ETL-логика в Airflow, DolphinScheduler или dbt лежит в Git наравне с продуктовым кодом, проходит code review, тесты, CI/CD — то, что в PL/pgSQL обычно организовывалось отдельно через миграционные скрипты. dbt автоматически строит граф зависимостей моделей и документацию; оркестратор показывает DAG с метриками каждой задачи. Плюс расширяется набор инструментов: в оркестраторе можно подключить любой Python (внешние API, ML-фичи), в dbt — макросы и Jinja-шаблоны. При миграции хранимая логика разъезжается на три слоя:
- ETL-оркестратор (Airflow, DolphinScheduler, dbt) — то, что было multi-step ETL-процедурами. Это самый большой кусок: SCD-функции, daily aggregations, snapshot processing.
- UDF (Java/Python) — точечные функции, которые вызываются из SQL и не зависят от данных в других таблицах. Маппинг 1:1 с PL/pgSQL функциями, возвращающими scalar или table.
- Materialized views — то, что было MV с manual refresh. В StarRocks MV умеют auto-refresh и auto-rewrite, и часть логики, которая раньше требовала процедуры, описывается декларативно.
B2. SQL dialect В Greenplum SQL — Postgres-семейство. Полный набор PG-фич: window-функции, recursive CTE, LATERAL JOIN, FILTER в агрегатах, ARRAY_AGG, GENERATE_SERIES, regexp-функции. Идентификаторы трехзвенные: database.schema.table. В StarRocks SQL — MySQL-семейство. Большинство стандартных конструкций совпадает (window-функции, basic CTE, JOIN-семантика), но есть несколько отличий:
Скрытый текст
- Иерархия имен. В StarRocks два уровня: database.table для нативных таблиц или catalog.database.table для external catalogs. Schema как промежуточный уровень не используется.
- LATERAL JOIN — прямого аналога нет. Часть случаев заменяется на CROSS JOIN UNNEST (для array/struct), часть — на pre-flattening в ETL.
- FILTER (WHERE …) в агрегатах работает (движок переводит в sum_if/count_if внутри). Альтернативно можно писать SUM(CASE WHEN cond THEN col END) для совместимости с другими диалектами.
- NULL ordering. В Postgres ORDER BY col ставит NULL last, в MySQL и StarRocks — NULL first. Для аналитика, привыкшего к Postgres-семантике, это часто ломает результаты тестов после миграции.
При миграции SQL-запросы проходят через автоматические замены простых случаев (CAST-ы, иерархия имен, datetime-форматы) и ручную правку нюансов (NULL ordering, LATERAL, recursive CTE). Регрессионное тестирование — обязательная часть, потому что многие отличия проявляются только на конкретных данных. B3. Materialized views и индексы В Greenplum materialized views — отдельная сущность, обновляются вручную через REFRESH MATERIALIZED VIEW. Поверх таблиц создаются индексы разных типов: btree (по умолчанию), gin (для JSONB и arrays), в GP 7 добавлен brin (для больших таблиц с естественной упорядоченностью), bitmap (для низкокардинальных колонок), expression-индексы (например, по LOWER(email)). DBA подбирает индекс под workload и поддерживает его. В StarRocks materialized views работают иначе — async или sync, и главное: с автоматическим query rewrite. Это значит, что клиентский SQL не меняется при добавлении MV. Допустим, есть MV с дневной агрегацией продаж, и BI-дашборд делает запрос SELECT customer_id, SUM(amount) ... GROUP BY customer_id к исходной таблице orders. Оптимизатор StarRocks сам распознает, что этот запрос можно посчитать через MV, и подставляет ее в план запроса — пользователь и BI-инструмент про MV не знают. В Greenplum для того же эффекта пришлось бы либо переписать запрос на обращение к MV вручную, либо обернуть всё в view. В StarRocks MV можно добавлять, удалять и пересоздавать, не трогая код дашбордов и приложений. Индексы в StarRocks устроены иначе:
- Sort key — основной механизм пропуска данных, задается при создании таблицы. Работает как кластерный индекс: данные физически отсортированы, сканирование по диапазону sort-ключа эффективно.
- Bloom filter — для high-cardinality колонок, по которым часто идут точечные запросы.
- Bitmap index — в целом, это тот же класс ускорения фильтров, но переносить GP bitmap indexes механически не стоит: сначала нужно понять, что они закрывали.
- Prefix index — автоматический, на основе sort-key.
- Inverted index (с 3.3) — для full-text search по строковым колонкам.
При миграции:
- MV переезжают с упрощением — то, что было manual REFRESH, в StarRocks становится async с auto-rewrite. Часть MV-логики, реализованной в Greenplum через процедуры, в StarRocks описывается одной CREATE MATERIALIZED VIEW.
- Индексы переписываются под другой паттерн. Btree редко нужен — sort key закрывает большинство случаев сканирования. Expression-индексы прямого аналога не имеют, выносятся в обычные колонки или MV. GIN-индексы тоже прямого аналога не имеют: для text search есть inverted index, для других случаев перепроектируется схема.
- Стратегия: сначала описать sort key для каждой таблицы под основной запросный паттерн, потом точечно добавить bloom/bitmap по горячим точкам.
 Блок C. Оперирование и нагрузка После DDL и SQL то, что администраторы делают каждый день, чтобы кластер продолжал работать — это управление нагрузкой, бэкапы и репликация, регулярное обслуживание (статистика, очистка, балансировка). Это слой, где у Greenplum-DBA уже сложились свои процессы и инструменты, и при миграции часть из них упрощается, а часть требует пересмотра. C1. Управление нагрузкой: resource queues / groups Главная разница на этом уровне — многое из того, что в Greenplum было ручным, в StarRocks делает сам движок. VACUUM, ANALYZE, REFRESH MV отрабатывают автоматически. Resource Groups покрывают тот же набор задач, что и Resource Queues, но настраиваются иначе. В Greenplum управление нагрузкой работает на двух уровнях. Resource Queues — ограничивают конкурентность (ACTIVE_STATEMENTS), приоритеты (PRIORITY), память (MEMORY_LIMIT). Запросы выше лимитов встают в очередь. Resource Groups — они дают более тонкий контроль CPU и памяти на уровне процессов, плюс изоляцию OOM. Подход StarRocks к управлению нагрузкой — шесть взаимодополняющих механизмов (это моя группировка; в документации они описаны раздельно):
- Multi-Warehouse (StarRocks Enterprise) — физически отдельные пулы compute-нод: ETL на своих, дашборды на своих. Данные общие, ресурсы раздельные.
- Resource Groups — логические лимиты CPU, памяти и concurrency внутри одного пула.
- Query Queues — если пороги превышены, запросы встают в очередь, а не роняют систему.
- Pipeline DOP — динамически подстраивает параллелизм под текущую нагрузку.
- Spill to Disk— тяжелые JOIN / AGG / SORT уходят на диск вместо OOM.
- Big Query Kill — автоматически прерывает запросы по лимитам памяти, CPU или scan rows.
C2. Backup и репликация В Greenplum надежность строится на нескольких механизмах:
- Mirror-сегменты — каждый primary segment имеет фиксированный mirror на другом узле. Failover автоматический.
- Standby master — резервная master-нода с журналом, может перехватить роль координатора, failover ручной.
- gpbackup/gprestore — параллельный backup всего кластера (или отдельных схем/таблиц) с компрессией и шифрованием.
В StarRocks модель надежности построена иначе:
- Tablet replication — каждый таблет реплицируется N раз (по умолчанию 3). Это N-replica с автоматическим распределением реплик по BE-узлам — модель отличается от fixed-pair mirror в Greenplum. При падении узла остальные реплики продолжают обслуживать запросы; поврежденные таблеты восстанавливаются автоматически.
- FE high availability — несколько FE-нод в режиме leader/follower через BDBJE-консенсус. При падении leader-FE один из follower-FE поднимается автоматически.
- Backup в объектное хранилище (для shared-nothing) — BACKUP и RESTORE команды загружают snapshot в S3-совместимое хранилище. Поддерживается резервное копирование per-table или per-database. В shared-data режиме вместо BACKUP/RESTORE используется отдельный механизм Cluster Snapshot.
- Резервный кластер на случай падения основного — два кластера с асинхронной репликацией по расписанию (например, каждые 15 минут). Одна команда переключает резервный в активный режим: допустимая потеря данных — от 15 минут, восстановление занимает минуты. Резервный кластер доступен на чтение в обычном режиме. Доступно в StarRocks Enterprise (Mirrorship EE с версии 3.3.5) и в Selena Lakehouse.
Главная архитектурная разница: в Greenplum резервирование жестко привязано к парам узлов (primary↔mirror), в StarRocks реплики распределяются по политике, и при добавлении/удалении BE-узлов реплики автоматически перебалансируются (если речь про shared-nothing). При миграции:
- Расписание бэкапов переезжает в BACKUP-команды StarRocks с целевым S3-хранилищем;
- Mirror-сегменты Greenplum концептуально становятся 3-replica tablet'ами в StarRocks (можно настроить и больше реплик для критичных таблиц);
- Standby master заменяется на multi-FE setup; рекомендуется минимум 3 FE-ноды для отказоустойчивости;
C3. Maintenance: VACUUM, ANALYZE, статистика, compaction В Greenplum maintenance — регулярный цикл операций, который занимает значимую часть времени DBA:
- VACUUM для heap-таблиц — освобождает мертвые строки после UPDATE/DELETE. На больших таблицах работает часами, и без него таблицы растут на диске.
- ANALYZE — пересчет статистики для оптимизатора. Нужен после массовых изменений данных, иначе планы запросов деградируют.
- VACUUM FULL / REINDEX — на сильно фрагментированных таблицах. Блокирующая операция.
- gp_toolkit / gp_segment_configuration — мониторинг состояния кластера, ребалансировка.
В StarRocks этот пласт работы сильно сокращен:
- Compaction (cumulative + base) — автоматическая в фоне. Не нужно ничего запускать руками.
- Auto-stats — статистика собирается в фоне, оптимизатор всегда видит свежие данные.
- REFRESH MV — async MV обновляются автоматически по расписанию или event-driven, без ручных действий.
Ручной ANALYZE остается как инструмент для особых случаев: крупная переливка данных, резкое изменение распределения значений, деградация конкретного плана. VACUUM как операции просто нет — место освобождается компактификацией. Это область, где StarRocks заметно проще в эксплуатации, и это реальный профит, который DBA в будущем получит от такой миграции. Освобождается значительная часть DBA-часов, ранее уходивших на VACUUM-расписания и контроль фрагментации. На этом первая часть — обзор различий между Greenplum и StarRocks по 11 областям: хранение и схема, запросы и семантика, операционный цикл заканчивается. Главный вывод первой части: миграция Greenplum → StarRocks не выглядит как прыжок в совсем чужую модель. У обоих движков есть MPP-подход, distribution, cost-based optimizer, exchange/motion-логика и привычная для DWH работа с большими таблицами. Но совместимость не полная: самые трудозатратные пункты — табличные модели, процедуры, SQL-диалект и partition exchange.
 В следующих эпизодах рассмотрим разные стратегии миграции данных и воспроизведем одну из них на тестовом стенде, разберем послемиграционный чек-лист и подведем итоговые выводы. Чтобы не пропустить: 🔹Подписывайтесь на этот блог на Habr 🔹Между статьями цикла — новости StarRocks в Telegram-канале @starrocks_selena (https://t.me/starrocks_selena)-Источник
|