Секрет 41 ( Доверяй, но проверяй: нюанс сбора статистики в партициях )
Оказия случилась с опросом выше, благодаря которой родился новый секрет, для тех, кто не зациклен на чтении документации.
Собственно, выявлена неожиданная особенность в 6ке,
gp_autostats_mode = on_no_stats не тригерит сбор статы в партицированой таблице, в которую вносим данные:
Собственно, это и стало причиной моего ложного вывода, т.к. я, будучи уверен, что
в партициях стата была собрана ввиду параметра выше, сравнивал объекты с статой и без.
Таким образом, корректный ответ в опросе: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.
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.
Оказия случилась с опросом выше, благодаря которой родился новый секрет, для тех, кто не зациклен на чтении документации.
Собственно, выявлена неожиданная особенность в 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
distinct_bench_single_vs_split_partitioned_on_stat.txt
5.6 KB
К секрету 41 // for Secret 41
Вопрос 5
#никогда не было и вот опять!
Создаю в 6ке вью v на табл-у t - делаю select * from v => permission denied for relation t
select * from t проблем не вызыввает.
drop + снова Создаю вью v на табл-у t ( идентичной командой под тем же пользаком ) - select * from v отработал.
Что это было ?
#никогда не было и вот опять!
Создаю в 6ке вью v на табл-у t - делаю select * from v => permission denied for relation t
select * from t проблем не вызыввает.
drop + снова Создаю вью v на табл-у t ( идентичной командой под тем же пользаком ) - select * from v отработал.
Что это было ?
👻2
Учитываете ли при выборе схемы партицирования число партиций как параметр производительности ? 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 млн строк:
В рамках теста на 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.
Для тех, кому нужно больше подробностей, напомню про
Дам мой комментарий к опросу выше, если это поможет тем, кто еще не определился.
Если кратко, у каждого будет свой ответ исходя из сценария использования ХД
Итак, основываясь на тестах, которые свел в отчет, видим.
В каждом тесте использовалась одна и та же таблица "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.
Для тех, кому нужно больше подробностей, напомню про
Telegram
Greenplum secrets🎩
Секрет 31 (Разбивай на счастье!)
Друзья, запасаемся попкорном. Будет лонгрид, т.к. было не так много времени, чтобы сократить матерьял, которым спешу поделиться.
Давно хотел познакомиться тет-а-тет с партишками в GP,
особенно на фоне слухов про них, зачастую…
Друзья, запасаемся попкорном. Будет лонгрид, т.к. было не так много времени, чтобы сократить матерьял, которым спешу поделиться.
Давно хотел познакомиться тет-а-тет с партишками в GP,
особенно на фоне слухов про них, зачастую…
#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.
#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.
🤡8❤3🔥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.
Каждая перфокарта — около 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 табл-е каноническим запросом :
Через 1 час запрос неожиданно ❌абортнулся по таймауту❌, несмотря на то, что ID - ключ дистрибуции и его безупречное распределение по ~350 сегментам, 2й запуск аналогично.
✡️Пришла шальная мысль ввиду моей одержимости законом Мерфи за неимением других вариантов в режиме read-only, а что если явно приказать ∑ шардировать DISTINCT ∑, коли данные позволяют.
На 95% был уверен, что исход будет тот же, т.к. опыт работы с 6кой не давал никаких зацепок, что может быть иначе.
На удивление запрос ниже отработал за 26 мин, 2й прогон - за 19 мин :
В итоге, по результатам 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:
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.
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.
В секрете 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.
Telegram
Greenplum secrets🎩
Секрет 41 ( Доверяй, но проверяй: нюанс сбора статистики в партициях )
Оказия случилась с опросом выше, благодаря которой родился новый секрет, для тех, кто не зациклен на чтении документации.
Собственно, выявлена неожиданная особенность в 6ке,
gp_autostats_mode…
Оказия случилась с опросом выше, благодаря которой родился новый секрет, для тех, кто не зациклен на чтении документации.
Собственно, выявлена неожиданная особенность в 6ке,
gp_autostats_mode…
🔥2
Планы запросов: Query plans
Канонический: Classic
Оптимальный: Boosted
Канонический: 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
Сегодня в СМИ разошлась новость из Южной Кореи. В одной из самых технологичных стран мира случился настоящий цифровой коллапс. Горел главный правительственный дата-центр, и после пожара полстраны оказалось без госуслуг. Полиция не работает, таможня не работает, аналог наших Госуслуг лежит.
Власти говорят про халатность рабочих и несчастный случай с литиевыми батареями. Звучит логично, да? Но когда начинаешь разбираться в деталях, появляются очень неудобные вопросы.
Что сгорело на самом деле?
Вот тут начинается самое интересное. Пожар уничтожил 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
🔥5❤3🤨2
Colonelcassad
Когда пожар слишком удобен: южнокорейский цифровой апокалипсис Сегодня в СМИ разошлась новость из Южной Кореи. В одной из самых технологичных стран мира случился настоящий цифровой коллапс. Горел главный правительственный дата-центр, и после пожара полстраны…
Я вот только не пойму, G-Drive это тот самый сервис Google Drive, которым весь мир пользуется, включая нас с вами?
Greenplum secrets🎩
Секрет 42 ( Галя, у нас отмена, вносите Distinct частями) В секрете 41 мы ускорили DISTINCT на 36% бисекцией сета в партиции табл-ы. Сегодня GP мне открыл новый секрет, совершенно случайно. Потребовалось узнать число уников в 50 млрд AOCO табл-е каноническим…
В итоге, снова командный интеллект рулит, спасибо за подсказу одному из самых активных гуру @novanto , который предложил самый простой вариант как продолжение секрета 42 :
который улучшил мой результат, а для таблицы с randomly распределением ускорение в среднем 4 раза (3 прогона )
Также благодарю @andre_rumyanec,@GaRin_1979 за снайперские разъяснения того, что я упустил из виду.
План запроса оставлю на память:
select count(*)
from (
select distinct id from tst) a;
который улучшил мой результат, а для таблицы с randomly распределением ускорение в среднем 4 раза (3 прогона )
Также благодарю @andre_rumyanec,@GaRin_1979 за снайперские разъяснения того, что я упустил из виду.
План запроса оставлю на память:
Aggregate (cost=0.00..27274.06 rows=1 width=8) (actual time=472431.983..472431.983 rows=1 loops=1)
-> Gather Motion 348:1 (slice1; segments: 348) (cost=0.00..27274.06 rows=1 width=8) (actual time=289343.460..472431.051 rows=348 loops=1)
-> Aggregate (cost=0.00..27274.06 rows=1 width=8) (actual time=320763.249..320763.249 rows=1 loops=1)
-> HashAggregate (cost=0.00..27274.06 rows=159303174 width=1) (actual time=178221.741..424697.199 rows=147062079 loops=1)
Group Key: id
Extra Text: (seg154) 147062079 groups total in 96 batches; 33 overflows; 295092493 spill groups.
"(seg154) Hash chain length 12.3 avg, 99 max, using 21653742 of 68157440 buckets; total 15 expansions."
""
-> Seq Scan on tst (cost=0.00..4198.52 rows=159303174 width=13) (actual time=0.318..26652.122 rows=159415592 loops=1)
Planning time: 7.094 ms
(slice0) Executor memory: 301K bytes.
"* (slice1) Executor memory: 186409K bytes avg x 348 workers, 186527K bytes max (seg108). Work_mem: 185027K bytes max, 6914497K bytes wanted."
Memory used: 524288kB
Memory wanted: 6914896kB
Optimizer: Pivotal Optimizer (GPORCA)
Execution time: 472454.119 ms
Telegram
Andrey Mazur
Dev, da, de
#никогда не было и вот опять.
Пытаюсь в динамике читать таблу в рамках моей ф-ии
select get_max_value('stg.foo')
Рвется код
query := format('SELECT MAX(version_id) FROM %I', p_table_name);
EXECUTE query INTO max_value;
с ошибкой ERROR: relation "stg.foo" does not exist
В статике
SELECT MAX(version_id) FROM stg.foo
выполняется.
Есть идеи куда копать ?
с SECURITY DEFINER И без проверял.
Пытаюсь в динамике читать таблу в рамках моей ф-ии
select get_max_value('stg.foo')
Рвется код
query := format('SELECT MAX(version_id) FROM %I', p_table_name);
EXECUTE query INTO max_value;
с ошибкой ERROR: relation "stg.foo" does not exist
В статике
SELECT MAX(version_id) FROM stg.foo
выполняется.
Есть идеи куда копать ?
с SECURITY DEFINER И без проверял.
🤡1
На заметку
Друзья, если ваш Data Governance созвучен с русским нелитературным словом, или иными словами вы запроектировали вашу ИС так не проактивно, что
понятия не имеете какие из тысяч таблиц вам нужны , а руководство в мыле сообщило, что в ХД дефицит места
и надо срочно что-то удалить, есть идея!
Метрика SOS, которую можно брать на вооружение : pg_stat_all_tables.seq_scan.
Каждый select, delete, update по любой таблице инкрементирует SOS до seq_scan+1,
тогда как служебныеanalyze, vacuum не аффектят.
Таким образом, сравнив снимок pg_stat_all_tables за период, можно узнать, что поменялось.
Благодарю @AndyDira за находку.
Век живи, век учись!
Note
Friends, if your Data Governance sounds like a Russian slang term, or in other words, you've designed your IS so inactively that
you have no idea which of the thousands of tables you need, and management has emailed you that there's a space shortage in the data warehouse
and something needs to be deleted urgently, I have an idea!
An SOS metric you can use: pg_stat_all_tables.seq_scan.
Every select, delete, or update for any table increments the SOS to seq_scan+1,
while the service functions analyze and vacuum have no effect.
Therefore, by comparing a snapshot of pg_stat_all_tables over a period, you can see what has changed.
Thanks to @AndyDira for the gem.
Live and learn!
Друзья, если ваш Data Governance созвучен с русским нелитературным словом, или иными словами вы запроектировали вашу ИС так не проактивно, что
понятия не имеете какие из тысяч таблиц вам нужны , а руководство в мыле сообщило, что в ХД дефицит места
и надо срочно что-то удалить, есть идея!
Метрика SOS, которую можно брать на вооружение : pg_stat_all_tables.seq_scan.
Каждый select, delete, update по любой таблице инкрементирует SOS до seq_scan+1,
тогда как служебные
Таким образом, сравнив снимок pg_stat_all_tables за период, можно узнать, что поменялось.
Благодарю @AndyDira за находку.
Век живи, век учись!
Note
Friends, if your Data Governance sounds like a Russian slang term, or in other words, you've designed your IS so inactively that
you have no idea which of the thousands of tables you need, and management has emailed you that there's a space shortage in the data warehouse
and something needs to be deleted urgently, I have an idea!
An SOS metric you can use: pg_stat_all_tables.seq_scan.
Every select, delete, or update for any table increments the SOS to seq_scan+1,
while the service functions analyze and vacuum have no effect.
Therefore, by comparing a snapshot of pg_stat_all_tables over a period, you can see what has changed.
Thanks to @AndyDira for the gem.
Live and learn!
❤4
Секрет 43 (Аннушка не опять а снова разлила масло или не все то золото, что CTE)
📌
Вероятно, самый известный закон старины Мерфи -
Если что-нибудь может пойти не так, оно пойдёт не так!
Вот еще пример, на этот раз, в противовес секрету, обратная сторона CTE, так сказать.
Я не устаю трубить, что join > 2 таблиц, особенно в MPP - это с большой вероятностью чревато..
Намедни принесли запрос, где идет join 4 таблиц, в.т.ч. 2 - CTE выражения, т.е. подзапросы.
ДНК запроса выглядит так
где t1,t2 - табл-ы без ключа,
cte_1..2 - подзапросы вида
📌
Отметим размеры выборок:
t1 - 20млн строк
t2 - <100k
cte_1 - 7 млн, полученная из 3 млрд строк
cte_2 - <50k, полученные из небольшого сета
Размер целевого сета: 20 млн строк.
Рез-т плачевный : 360 TB спиллов в 10 запусках такого запроса за 2 дн, каждый из которых шуршал 2ч.
⁉️
А все почему ?
Кодер не озадачился материализовать cte в отдельные таблицы, переключив запрос на которые
он выполнится за 1 мин без спилла.
При этом, уже не имеет значения, что t1,t2 остались RANDOMLY и в плане появилось 2 Broadcast-а
📌
Вероятно, самый известный закон старины Мерфи -
Если что-нибудь может пойти не так, оно пойдёт не так!
Вот еще пример, на этот раз, в противовес секрету, обратная сторона CTE, так сказать.
Я не устаю трубить, что join > 2 таблиц, особенно в MPP - это с большой вероятностью чревато..
Намедни принесли запрос, где идет join 4 таблиц, в.т.ч. 2 - CTE выражения, т.е. подзапросы.
ДНК запроса выглядит так
select * -- набор полей без преобразований
from t1
left join t2 on t2.parent_deal_num = t2.deal_num
left join cte_1 on t1.acc_num = cte_1.main_acc_num and coalesce( t1.x, t2.y) is null
left join cte_2 on t1.deal_num = cte_2.deal_num
где t1,t2 - табл-ы без ключа,
cte_1..2 - подзапросы вида
select DISTINCT id, first_value( ... ) OVER (PARTITION BY id ORDER BY version_id) from t
📌
Отметим размеры выборок:
t1 - 20млн строк
t2 - <100k
cte_1 - 7 млн, полученная из 3 млрд строк
cte_2 - <50k, полученные из небольшого сета
Размер целевого сета: 20 млн строк.
Рез-т плачевный : 360 TB спиллов в 10 запусках такого запроса за 2 дн, каждый из которых шуршал 2ч.
⁉️
А все почему ?
Кодер не озадачился материализовать cte в отдельные таблицы, переключив запрос на которые
он выполнится за 1 мин без спилла.
При этом, уже не имеет значения, что t1,t2 остались RANDOMLY и в плане появилось 2 Broadcast-а
Telegram
Greenplum secrets🎩
Секрет 2 (Ускоряем GROUP BY)
Обычный GROUP BY при наличии большого числа метрик можно ускорить, используя CTE, также снизив размер спилла
Secret 2(Speed up GROUP BY)
Simple GROUP BY operator with a lot of aggregates can be boosted using CTE (cutting spill…
Обычный GROUP BY при наличии большого числа метрик можно ускорить, используя CTE, также снизив размер спилла
Secret 2(Speed up GROUP BY)
Simple GROUP BY operator with a lot of aggregates can be boosted using CTE (cutting spill…
❤2
Translation
Secret 43 (How Annushka spilled the oil again or not all that is gold is CTE)
📌
Probably the most famous of old Murphy's Laws:
If anything can go wrong, it will!
Here's another example, this time, as opposed to the secret, the downside of CTEs, so to speak.
I never tire of trumpeting that a join of > 2 tables, especially in MPP, is highly likely to be dangerous.
The other day, someone brought me a query that joins 4 tables, including 2 CTE expressions, i.e., subqueries.
The query's DNA looks like this:
where t1,t2 are tables without a key,
cte_1..2 are subqueries akind of
📌
Note the sample sizes:
t1 - 20 million rows
t2 - <100k
cte_1 - 7 million, obtained from 3 billion rows
cte_2 - <50k, obtained from a small set
Target set size: 20 million rows.
The result is frustrating: 360 TB of spills in 10 runs of this query over 2 days, each running for 2 hours.
⁉️
And how come?
The coder didn't bother to materialize the cte into separate tables, switching the query to which
it will execute in 1 minute without a spill.
In this case, it no longer matters that t1 and t2 remain RANDOMLY and two Broadcasts appeared in the plan.
Secret 43 (How Annushka spilled the oil again or not all that is gold is CTE)
📌
Probably the most famous of old Murphy's Laws:
If anything can go wrong, it will!
Here's another example, this time, as opposed to the secret, the downside of CTEs, so to speak.
I never tire of trumpeting that a join of > 2 tables, especially in MPP, is highly likely to be dangerous.
The other day, someone brought me a query that joins 4 tables, including 2 CTE expressions, i.e., subqueries.
The query's DNA looks like this:
select * -- a set of fields without transformations
from t1
left join t2 on t2.parent_deal_num = t2.deal_num
left join cte_1 on t1.acc_num = cte_1.main_acc_num and coalesce(t1.x, t2.y) is null
left join cte_2 on t1.deal_num = cte_2.deal_num
where t1,t2 are tables without a key,
cte_1..2 are subqueries akind of
select DISTINCT id, first_value( ... ) OVER (PARTITION BY id ORDER BY version_id) from t
📌
Note the sample sizes:
t1 - 20 million rows
t2 - <100k
cte_1 - 7 million, obtained from 3 billion rows
cte_2 - <50k, obtained from a small set
Target set size: 20 million rows.
The result is frustrating: 360 TB of spills in 10 runs of this query over 2 days, each running for 2 hours.
⁉️
And how come?
The coder didn't bother to materialize the cte into separate tables, switching the query to which
it will execute in 1 minute without a spill.
In this case, it no longer matters that t1 and t2 remain RANDOMLY and two Broadcasts appeared in the plan.
Telegram
Greenplum secrets🎩
Секрет 2 (Ускоряем GROUP BY)
Обычный GROUP BY при наличии большого числа метрик можно ускорить, используя CTE, также снизив размер спилла
Secret 2(Speed up GROUP BY)
Simple GROUP BY operator with a lot of aggregates can be boosted using CTE (cutting spill…
Обычный GROUP BY при наличии большого числа метрик можно ускорить, используя CTE, также снизив размер спилла
Secret 2(Speed up GROUP BY)
Simple GROUP BY operator with a lot of aggregates can be boosted using CTE (cutting spill…
❤1
Вопрос 6
Пытаюсь выполнить SQL скрипт размером 1 МБ, рвет с ERROR: stack depth limit exceeded/
БД рекомендует Increase the configuration parameter "max_stack_depth" (currently 2048kB)
Я конечно попилю на части, но почему рвется, когда стакан только наполовину полон ?
Пытаюсь выполнить SQL скрипт размером 1 МБ, рвет с ERROR: stack depth limit exceeded/
БД рекомендует Increase the configuration parameter "max_stack_depth" (currently 2048kB)
Я конечно попилю на части, но почему рвется, когда стакан только наполовину полон ?
Greenplum secrets🎩
На заметку Друзья, если ваш Data Governance созвучен с русским нелитературным словом, или иными словами вы запроектировали вашу ИС так не проактивно, что понятия не имеете какие из тысяч таблиц вам нужны , а руководство в мыле сообщило, что в ХД дефицит места…
Кстати, интересно отметить, что
By the way, it is interesting to note that
Есть идеи, почему разница ?
Any ideas why there is a difference?
By the way, it is interesting to note that
select seq_scan from pg_stat_all_tables where relname = 'foo' => 5
select sum(seq_scan) from gp_dist_random('pg_stat_all_table')s where relname = 'foo' => 2415Есть идеи, почему разница ?
Any ideas why there is a difference?