Greenplum secrets🎩
698 subscribers
38 photos
8 videos
10 files
67 links
The channel about best practice coding for Greenplum / Канал о том как писать оптимальный код в Greenplum. by @smartyru
Download Telegram
И вот тут мне не даёт покоя тот факт, что динозавры появились 200 млн назад, а машина Тьюринга в 1936, но какой прогресс уже в развитии ИТ зоопарка, и в части концепций, и в части ДНК, на которых они реализованы
👍2👏1
Forwarded from Data Chaos
Greenplum: динозавр или рабочая лошадь в 2025

Greenplum - это движок, который долгое время был символом корпоративной аналитики.
В эпоху, когда Hadoop только взлетал и все мечтали о дешёвом "data lake", именно Greenplum давал то, чего так не хватало: SQL, транзакции и ACID.

🏦 В банках и телекоме это был настоящий game changer. Hadoop клал файлы и костылял через Hive без транзакций. Greenplum же позволял писать надёжные аналитические запросы, жить в SQL и быть уверенным в консистентности данных. Именно поэтому десятки проектов в 2010-х поднимались на Greenplum.

Что с ним сейчас
⚙️ Архитектура MPP по-прежнему рабочая;
🖥 Кластеры в проде до сих пор крутятся и обслуживают критичные процессы;
⛔️ Хайпа давно нет, а новые проекты почти не появляются;

Уже даже на data конференции 2 и 3 сорта, не приходит тот самый чел в сером в пиджаке, который рассказывает, как они «подняли хранилище на 200 ТБ и все офигели».😁

В конце 2023 Broadcom (после покупки VMware) фактически заморозила основную open-source ветку. Комьюнити жаловалось на редкие релизы и мёртвые пулл-реквесты, и теперь Greenplum в OSS-смысле выглядит как пациент в коме: вроде жив, но движения нет.

🚀 Modern Data Stack уже уехал
-Lakehouse решили вопрос ACID через Delta, Iceberg, Hudi
-Cloud-first модели с pay-as-you-go съели рынок
-Экосистема вокруг Icebrg, Airflow, Trino даёт гибкость и скорость, которой у Greenplum нет
-Интеграция с ML/LLM? Почти нулевая

За последний месяц у меня было несколько встреч с основными облачными провайдерами на нашем рынке. И никто из них не планирует в дальнейшем развивать этот продукт как часть их экосистемы.

Вопрос на 2025

Greenplum будет жить - потому что миграция с него стоит дорого, а бизнес не любит рисковать. А еще есть arenadata в РФ, которая успела подсадить больших корпов и госы на свой проприетарных GP и отказаться от него теперь очень сложно и дорого.
Но новые проекты? 🤔 Серьёзно, кто сейчас сознательно выберет Greenplum для старта?

Greenplum однажды сделал шаг в будущее раньше Hadoop — дал ACID там, где были только костыли. Но теперь сам остался в прошлом: закрытый OSS, стагнация и потерянный тренд.
🤡1
У меня только 1 вопрос к автору - а реально есть MPP аналог, такой же удобный, с полным Тьюрингом в режиме компилятора ( а не интерпретатора), интеграцией а-ля PXF с половиной МИРА, партициями, сжатием и все это в одном флаконе?
👍8
Дано 2 идентичных таблицы AOCO t1,t2 с K случайных чисел, причем t2 разбита на 2 партиции, для четных и нечетных n соотв-но.
Какой запрос быстрее:
select distinct n from t1 или select distinct n from t2_prt_odd union all select distinct n from t2_prt_even
Anonymous Poll
34%
1
49%
2
16%
Однаково
Решение теста выше: Solution of the test above
Как ни странно, запрос 1 кратно лучше, почти на порядок.
Что интересно, если t1 распилить на 2 отдельные таблицы, то в таком варианте дихотомии имеем в среднем выигрыш ~75% ( см. distinct_bench_single_vs_split.txt, 2 прогона).
Но в случае распила с партициями(что есть более жизненный сценарий, кмк), даже если они используются в запросе 2 явно в виде физических таблиц в плане появляется сортировка,
которая сьедает львиную долю run-time ( см. distinct_bench_single_vs_split_partitioned.txt).
Увы, этот самый external merge появляется даже при отборе уникального сета из одной таблицы-партиции.
⁉️А если взять CTE, на которую накинуть DISTINCT ? - болт, результат(план) тот же.
Ума не приложу, зачем так сделано, но реальность 6-ки пока такова.

Oddly enough, query 1 is significantly better, almost an order of magnitude.
Interestingly, if t1 is split into two separate tables, this dichotomy solution yields an average performance gain of ~75% (see distinct_bench_single_vs_split.txt, two runs).
But if partitions are used (which is a more realistic scenario, in my opinion), even if they are explicitly used in query 2 as physical tables, the plan adds a sort,
which eats up the lion's share of runtime (see distinct_bench_single_vs_split_partitioned.txt).
Unfortunately, this same external merge occurs even when selecting a unique set from a single partition table.
⁉️But what if we use a CTE with DISTINCT? Doesn't matter, the result (plan) is the same.
I can't imagine why this was done, but this is the reality of the v6.


📌Собственно, за пререквизиты брал
Actually, I took it as a prerequisite
t1:
tst_100bln_dk - сет из 100 млрд чисел int4 в диапазоне 1..1 000 000 // a set of 100 billion int4 numbers in the range 1..1,000,000

t2:
create table tst_100bln_dk_part_by_n
(n int, prt_mod int)
WITH (appendonly=true,orientation=column,compresstype=zstd,compresslevel=1)
distributed by (n)
partition by list(prt_mod)
(partition p0 values (0),
partition p1 values (1),
default partition other);

-- Заполняем чет/нечет партиции по условию prt_mod = mod(n,2) :
-- Fill the even/odd partition according to the condition prt_mod = mod(n,2):
insert into tst_100bln_dk_part_by_n
select n, (n & 1)
from tst_100bln_dk
👍2😱2
Файлы // Files
Секрет 41 ( Доверяй, но проверяй: нюанс сбора статистики в партициях )
Оказия случилась с опросом выше, благодаря которой родился новый секрет, для тех, кто не зациклен на чтении документации.

Собственно, выявлена неожиданная особенность в 6ке,
gp_autostats_mode = on_no_stats не тригерит сбор статы в партицированой таблице, в которую вносим данные:
For partitioned tables, automatic statistics collection is not triggered if data is inserted from the top-level parent table of a partitioned table.

But automatic statistics collection is triggered if data is inserted directly in a leaf table (where the data is stored) of the partitioned table.



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

Таким образом, корректный ответ в опросе:2, мудрость толпы восторжествовала!
🔥Респект @alias cd='rm -rf ', заметившему брешь в моей логике и @Василий Антонов, подсветившему, что
такое поведение gp_autostats_mode в рамках документации.


В итоге, выигрыш от бисекции DISTINCT-а составил 36% по результатам 2х прогонов. ( расчет в файле ниже )
Подумаю, не запатентовать ли сию оптимизацию.

Secret 41 (Trust, but verify: the nuance of collecting statistics in partitions)
An unfortunate incident with the survey above gave birth to a new secret, for those who aren't fans of reading documentation.

A specific issue was discovered in version 6:
gp_autostats_mode = on_no_stats doesn't trigger stats collection in the partitioned table into which we insert data.

For partitioned tables, automatic statistics collection is not triggered if data is inserted from the top-level parent table of a partitioned table.

But automatic statistics collection is triggered if data is inserted directly in a leaf table (where the data is stored) of the partitioned table.


This is precisely what led to my false conclusion, because, being certain that
stats were collected in partitions due to the parameter above, I compared an object with stats to an object without stats.

Therefore, the correct answer is 2; the wisdom of the crowd has triumphed!
🔥Kudos to
@alias cd='rm -rf' for spotting a flaw in my logic, and to @Vasily Antonov for pointing out that
this behavior of gp_autostats_mode isn't a bug.

In the end, the gain from DISTINCT bisection was 36% based on two runs (calculations in the file below).
I'll consider patenting this optimization.
🫡4🔥3
Вопрос 5
#никогда не было и вот опять!
Создаю в 6ке вью v на табл-у t - делаю select * from v => permission denied for relation t
select * from t проблем не вызыввает.
drop + снова Создаю вью v на табл-у t ( идентичной командой под тем же пользаком ) - select * from v отработал.
Что это было ?
👻2
Please open Telegram to view this post
VIEW IN TELEGRAM
Учитываете ли при выборе схемы партицирования число партиций как параметр производительности ? Do you consider the number of partitions as a performance parameter when choosing a partitioning scheme?
Anonymous Poll
79%
Y
21%
N
И снова здравствуйте!
Дам мой комментарий к опросу выше, если это поможет тем, кто еще не определился.
Если кратко, у каждого будет свой ответ исходя из сценария использования ХД

Итак, основываясь на тестах, которые свел в отчет, видим.
В каждом тесте использовалась одна и та же таблица "document" из 10 млр строк (S), равномерно распределенных по полю doc_date в интервале 2000 - 2025 гг с ключом doc_rk,
в которой менялась только схема партицирования, определяемая 2 параметрами - числом партиций на каждом уровне и числом уровней партицирования ( max 2 )
Отдельная строчка на каждой из 8 вкладок отчета ниже представляет отдельный тест.

В рамках теста на select (вкладки вида %select) использовался эталонный запрос
на отбор документов по диапазону дат + фильтр на источник, из которого загружен документ), извлекающий 7 млн строк:
select * from S 
where doc_date between '2021-01-01'::date and '2022-08-23'::date
and src_cd = 'foo'

В рамках теста на insert (вкладки вида %insert) подготовленная эталонная AOCO (без партиций) таблица "document_snap" переливалась в "document" через Insert as select с сохранением ключа
AORO - Append Only Row Oriented секционирована либо по дате док-та (1 level в названии вкладки), либо по дате док-та + SRC_CD (2 levels )
AOCO - Append Only Column Oriented секционирована либо по дате док-та, либо по дате док-та + SRC_CD

Параметр max_appendonly_tables = 10 000
Число сегментов кластера - 348.

Какие выводы можно сделать, изучив отчет ?
📌
Для операции select влияние числа партиций несущественно
Для одноранговых партиций ( все вкладки вида %1 level%) число партиций не влияет на скорость select, либо это влияние имеет место в пограничных случаях ( когда
число партиций близко к max_appendonly_tables (вкладка AORO, 1 level, select), либо когда число партиций близко к пределу, который определяется как
max_appendonly_tables, так и числом колонок таблы (см. AOCO,1 lvl, select).
Что касается 2х уровнего партицирования, влияние числа партиций практически отсутствует за исключением граничных случаев для строчной таблы (AORO, 2 levels, select)
📌
Для операции insert влияние числа партиций на перформанс запроса статистически значимо, т.е. прослеживается корреляция как между числом партиций в целевой таблице N
и временем выполнения запроса,
так и между средним потреблением RAM ( напр. AOCO, 1 lvl, insert, поле avg_mem_used_in_gb_per_segment ) и N.
К слову, случаи avg_mem_used_in_gb_per_segment < 0 - это баг 6ки, когда план запроса генерим в JSON формате ( на которых построен отчет ), но Аренадата уже фиксит.

p.s.
Для тех, кому нужно больше подробностей, напомню про
#DATA Почти все крупные компании РФ после PO сливают капитализацию ( даже Whoosh ). Но амбассадор MPP технологии не в их числе - за год Аренадата показала не только рост (IPO компании состоялось 1 октября 2024 ), но и дивиденды выплатила.
#DATA Almost all major Russian companies lose capital after IPOs (even Whoosh). But the MPP technology ambassador isn't among them – over the past year, Arenadata has not only shown growth (the company's IPO took place on October 1, 2024) but also paid dividends.
🤡83🔥1
Держали в руках перфокарту ? // Have you ever held a punch card in your hands?
Anonymous Poll
64%
Y
15%
N
21%
N ( но знаю как выглядит /*+but I know what it looks like+*/
Хранилище перфокарт в Национальном управлении архивов и документации США, 1950-е.

Каждая перфокарта — около 80 байт данных. В коробке их две тысячи, то есть всего 160 килобайт.
Вся эта стена информации — меньше, чем объём памяти современного телефона.

A punch card vault at the U.S. National Archives and Records Administration, 1950s.

Each punch card contains approximately 80 bytes of data. The box contains two thousand of them, or a total of 160 kilobytes.
This entire wall of information is smaller than the memory capacity of a modern telephone.
😱5😎2🔥1
Секрет 42 ( Галя, у нас отмена, вносите Distinct частями)
В секрете 41 мы ускорили DISTINCT на 36% бисекцией сета в партиции табл-ы.
Сегодня GP мне открыл новый секрет, совершенно случайно.

Потребовалось узнать число уников в 50 млрд AOCO табл-е каноническим запросом :
select  count(distinct id) cnt from tst

Через 1 час запрос неожиданно абортнулся по таймауту, несмотря на то, что ID - ключ дистрибуции и его безупречное распределение по ~350 сегментам, 2й запуск аналогично.
✡️Пришла шальная мысль ввиду моей одержимости законом Мерфи за неимением других вариантов в режиме read-only, а что если явно приказать ∑ шардировать DISTINCT ∑, коли данные позволяют.
На 95% был уверен, что исход будет тот же, т.к. опыт работы с 6кой не давал никаких зацепок, что может быть иначе.
На удивление запрос ниже отработал за 26 мин, 2й прогон - за 19 мин :
select sum(cnt) from (
select gp_segment_id, count(distinct id) cnt from tst
group by 1) a;


В итоге, по результатам 4х испытаний (2 из которых сделаны в ЧНН), профит как минимум вдвое.
Ума не приложу, за счет чего буст, планы ниже приложил.

Secret 42 (Galya, cancel it; just implement Distinct in parts)
In secret 41 (
https://t.iss.one/mpp_secrets/277), we accelerated Distinct by 36% by bisecting the set into table partitions.
Today, GP revealed a new secret to me, completely by accident.

I have to find the number of unique visitors in a 50 billion AOCO table using the canonical query:

select  count(distinct id) cnt from tst


After an hour, the query unexpectedly timed out, despite the fact that ID is the distribution key and its perfect distribution across ~350 segments. The second run was the same.
✡️A crazy thought occurred to me, due to my obsession with Murphy's Law and the lack of other options in read-only mode: what if I explicitly order ∑ to shard DISTINCT ∑ if the data allows it?
I was 95% sure the outcome would be the same, since my experience with GP 6 didn't provide any clues that it could be otherwise.
Surprisingly, the query below took 26 minutes, the second run took 19 minutes.

select sum(cnt) from (
select gp_segment_id, count(distinct id) cnt from tst
group by 1) a;


Ultimately, based on the results of four tests (two of which were conducted during peak hours), the profit at least doubled.
I have no clue how this boost is achieved; I've included the plans below.
🔥2
Планы запросов: Query plans
Канонический: Classic
Aggregate  (cost=0.00..8282.42 rows=1 width=8) (actual time=2135638.276..2135638.276 rows=1 loops=1)
-> Gather Motion 348:1 (slice1; segments: 348) (cost=0.00..8282.42 rows=1 width=8) (actual time=1401663.534..2135637.326 rows=348 loops=1)
-> Aggregate (cost=0.00..8282.42 rows=1 width=8) (actual time=1752231.829..1752231.830 rows=1 loops=1)
-> Seq Scan on tst (cost=0.00..4198.52 rows=159303174 width=13) (actual time=1.873..29095.001 rows=159415592 loops=1)
Planning time: 7.709 ms
(slice0) Executor memory: 301K bytes.
"* (slice1) Executor memory: 218876K bytes avg x 348 workers, 218976K bytes max (seg108). Work_mem: 218743K bytes max, 8814887K bytes wanted."
Memory used: 524288kB
Memory wanted: 8815186kB
Optimizer: Pivotal Optimizer (GPORCA)
Execution time: 2135652.775 ms

Оптимальный: Boosted
Aggregate  (cost=0.00..77329.99 rows=1 width=8) (actual time=604673.360..604673.360 rows=1 loops=1)
-> Gather Motion 348:1 (slice2; segments: 348) (cost=0.00..77329.99 rows=1 width=8) (actual time=604618.549..604673.179 rows=348 loops=1)
-> Aggregate (cost=0.00..77329.99 rows=1 width=8) (actual time=604592.376..604592.376 rows=1 loops=1)
-> HashAggregate (cost=0.00..77329.99 rows=1 width=8) (actual time=604582.705..604582.721 rows=6 loops=1)
Group Key: gp_segment_id
" Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 1 of 32 buckets; total 0 expansions."
""
" Extra Text: (seg2) Hash chain length 1.0 avg, 1 max, using 1 of 32 buckets; total 0 expansions."
""
" Extra Text: (seg329) Hash chain length 1.0 avg, 1 max, using 6 of 32 buckets; total 0 expansions."
""
-> Redistribute Motion 348:348 (slice1; segments: 348) (cost=0.00..58070.87 rows=159303174 width=17) (actual time=149192.161..474592.851 rows=881806966 loops=1)
Hash Key: gp_segment_id
-> HashAggregate (cost=0.00..49594.35 rows=159303174 width=17) (actual time=173402.695..498347.846 rows=147062079 loops=1)
" Group Key: gp_segment_id, id"
Extra Text: (seg154) 147062079 groups total in 160 batches; 33 overflows; 295547324 spill groups.
"(seg154) Hash chain length 10.6 avg, 91 max, using 19521970 of 50855936 buckets; total 46 expansions."
""
-> Seq Scan on tst (cost=0.00..4198.52 rows=159303174 width=17) (actual time=1.400..27443.299 rows=159415592 loops=1)
Planning time: 15.710 ms
(slice0) Executor memory: 495K bytes.
"* (slice1) Executor memory: 93879K bytes avg x 348 workers, 93923K bytes max (seg0). Work_mem: 92514K bytes max, 6909525K bytes wanted."
" (slice2) Executor memory: 188K bytes avg x 348 workers, 235K bytes max (seg2)."
Memory used: 524288kB
Memory wanted: 13819549kB
Optimizer: Pivotal Optimizer (GPORCA)
Execution time: 604731.078 ms
Forwarded from Colonelcassad
Когда пожар слишком удобен: южнокорейский цифровой апокалипсис

Сегодня в СМИ разошлась новость из Южной Кореи. В одной из самых технологичных стран мира случился настоящий цифровой коллапс. Горел главный правительственный дата-центр, и после пожара полстраны оказалось без госуслуг. Полиция не работает, таможня не работает, аналог наших Госуслуг лежит.

Власти говорят про халатность рабочих и несчастный случай с литиевыми батареями. Звучит логично, да? Но когда начинаешь разбираться в деталях, появляются очень неудобные вопросы.

Что сгорело на самом деле?

Вот тут начинается самое интересное. Пожар уничтожил 647 сервисов, это факт. Но большинство из них можно восстановить или хотя бы частично вернуть к жизни. А вот одна система испарилась полностью и безвозвратно — G-Drive.

Это цифровое сердце всей южнокорейской бюрократии: 858 терабайт документов — контракты, служебки, переписка, внутренние расследования. Документы 190 тысяч государственных служащих из 74 министерств и ведомств. За восемь лет, с 2017 по 2025 год.

Теперь внимание. G-Drive создавался с 2017 года специально как единое хранилище для всех чиновников. Власти запретили им пользоваться Google Drive (типа импортозамещение) и заставили держать всё в государственной системе.

И вот что удивительно: эту систему намеренно сделали без нормального резервного копирования. Официальное опровдание — "технические сложности из-за большого объема". Серьезно? В 2025 году, когда любой школьник умеет настроить бэкап, правительство самой технологичной страны не может скопировать 858 терабайт в другой регион?

Это всё равно что построить главный банк страны и не поставить на хранилище дверь, потому что "технически сложно".

Резервные копии были... в соседней серверной. Того же здания. Которое тоже сгорело. Естественно.

Дальше больше. У Южной Кореи был план — построить настоящий центр аварийного восстановления в городе Конджу. Защищенный даже от электромагнитного импульса, на случай войны с Северной Кореей.

Проект начали еще в 2012 году. И знаете, сколько его финансировали? Ноль. Тринадцать лет ноль финансирования. При трех разных президентах — и левых, и правых.

Центр достроили к 2025 году, его планировали запустить в октябре. Но на момент пожара 26 сентября он просто стоял пустой.

Кому это выгодно?


А теперь главный детективный вопрос. Посмотрите на хронологию уничтоженных данных: 2017-2025 годы.
2017-2022 — президент Мун Чжэин (левые)
2022-2025 — президент Юн Сок Ёль (правые)
2025 — президент Ли Чжэмён (левые)

Сгорели документы трех администраций. И левых, и правых.

858 терабайт документов — это компромат на всех. На обе партии. На всех министров. На весь бизнес, который работал с властью. На судей, прокуроров, силовиков.

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

Система была спроектирована хрупкой намеренно. Как кнопка "стереть всё" для всего госаппарата.

Центр в Конджу не финансировался 13 лет при РАЗНЫХ правительствах. G-Drive делали без нормального бэкапа. Батареи не меняли. Всё это — не ошибки, а функции системы.

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

Официальное следствие, скорее всего, накажет нескольких рабочих и мелкого чиновника. Козлы отпущения найдутся. А те, кто 13 лет создавал эту систему, кто блокировал финансирование защиты, кто проектировал "кнопку обнуления" — они останутся в тени.

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

@darpaandcia
🔥53🤨2