
Привет, Хабр! На связи Андрей Бородин, в Yandex Cloud я руковожу направлением разработки СУБД с открытым исходным кодом — и я попал в Яндекс через опенсорс. Я уже немного рассказывал, что и зачем мы делаем в опенсорсных БД с точки зрения облачных сервисов, где мы развиваем PostgreSQL, Greenplum, Cloudberry, Valkey и другие решения.
Но из этих историй часто ускользает человеческая сторона: мы занимаемся опенсорсом не только для того, чтобы сделать решения с открытым кодом более облачными, не только потому, что это модно, но и потому, что это приносит пользу не только продукту, но и самим разработчикам‑контрибьюторам.
На масштабах Яндекса возникают нетривиальные задачи, которые интересно решать. А когда мы делимся решениями с сообществом, то можем получить от них новый взгляд на проблему, и продолжить совместную разработку новой фичи в удобном формате: с кем‑то на условиях независимого сотрудничества, а кого‑то можем позвать в команду (как это было и со мной).
В общем, если придерживаться опенсорс‑философии, может возникнуть ситуация win‑win. Сегодня с коллегами Леонидом Борчуком @leborchuk и Дмитрием Сарафанниковым расскажу пару историй про то, как это бывает с опенсорсными СУБД.
История про кеш и проблему с подтранзакциями
Под капотом у PostgreSQL есть много интересных деталей. Например, подтранзакции, довольно удобные с точки зрения программиста. Вам о них обычно не требуется знать, пока в один прекрасный момент всё не начнет неожиданно сильно тормозить. На эту тему была статья от GitLab, в которой коллеги рассказывают, как и почему они устранили все подтранзакции у себя. Вот несколько графиков из статьи, которые наглядно показывают, как развиваются инциденты, связанные с подтранзакциями. Отдельные запросы тормозят настолько, что полностью перестают выполняться:

Эта проблема выражалась и с другой стороны — в мультитранзакциях. Такое бывает в случае, когда один tuple заблокирован несколькими транзакциями или апдейтами, вот пример:
\set aid random_zipfian(1, 100000 * :scale, 1.5)
SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
620 000 TPS, 0 MB\sec write
\set aid random_zipfian(1, 100000 * :scale, 5.0)
SELECT abalance FROM pgbench_accounts
WHERE aid = :aid FOR SHARE;
На эту тему также был хороший доклад Александра Короткова, где он обратил внимание, что select‑only‑нагрузка может порождать 15 МБ/с записи на диск только для того, чтобы расставить блокировки на tuple. Это делается через подсистему SLRU, не самую производительную в PostgreSQL, потому что она рассчитана на небольшие серверы. Проблема наблюдается, если эксплуатировать машину с 64 ядрами или больше, а на 32-ядерном процессоре воспроизвести её крайне сложно. Хотя и такое тоже бывает при определённом стечении нагрузки, когда есть микс из быстрых и спектра медленных транзакций.
Однажды это случилось и в Яндексе. 17 апреля 2020 года на меня завели тикет, в котором коллеги предлагали: «Давайте чинить SLRU». У нас произошёл инцидент, когда важная база была недоступна 20 минут, пока подсистема SLRU была занята чтением.

Подсистема оказалась однопоточной. Мы подстелили соломы, чтобы быстро купировать инцидент: расширили кеш, сделали SLRU больше, но увеличивать бесконечно было нельзя. Хотелось системного решения, которое устраняет проблему и защищает базу от внезапной деградации производительности.
Четыре года мы работали над этой проблемой. В апреле 2024 года в PostgreSQL 17 закоммитился патч, который состоит из моей доработки в кеш транзакций, подтранзакций и всего, что находится в SLRU.

Идея заключается в том, что я заимствовал технологию из процессорных кешей, разделив кеш на банки, и перенёс её в кеш транзакций.
Чуть позже Дилип Кумар из EnterpriseDB дописал распил локов на банки, и эта технология стала ещё лучше с точки зрения Lock contention. В таком виде оно было принято до этапа feature freeze.
После этого мы ещё немного дооптимизировали это решение: выяснилось, что такая же ситуация с проблемными транзакциями затрагивает все реплики, поскольку там было лишнее ожидание — это мы тоже починили и закоммитили в августе.
Сейчас сообщество уже уверено в надёжности этой технологии. Коллеги из EnterpriseDB даже научились воспроизводить исходную проблему и наглядно показывать её влияние на производительность. Вот графики из их доклада:

Мы видим, что без патча при желании можно положить базу в ноль. С наложением патча мы всё ещё видим деградацию — длинные транзакции по-прежнему вредят, патч здесь не панацея, но от даунтайма он спасает.
История про маленький, но полезный коммит в PostgreSQL
Не всегда нужны годы, для того, чтобы создать и закоммитить новый патч. Иногда мы обнаруживаем возможность для быстрых улучшений в пару строк, но которые было бы сложно найти, если бы не наши специфические задачи. Историей поделился Дмитрий Сарафанников.
Наверняка большинство знают, как выглядит наукастинг в Яндекс Погоде краткосрочный прогноз с шагом в 10 минут, который предсказывает погодные явления с коротким жизненным циклом. Самый распространённый вариант — это карты осадков или температуры.

Карты осадков на тот момент хранились в PostgreSQL в виде полигонов и времени, на которое они актуальны. Поиск по полигонам производился средствами PostGIS. Каждые 10 минут туда заливались новые прогнозы и удалялись старые. При этом запрос, ищущий нужные полигоны использовал JOIN двух таблиц.
В PostgreSQL реализовано три варианта, как выполнить JOIN: NestedLoop, HashJoin и MergeJoin. Планировщик при составлении плана запроса пытается оценить возможность выполнения и стоимость каждого способа соединения таблиц. MergeJoin возможен только по сортированным входным данным. Собственно, в таблице была колонка с временной меткой (timestamp) полигона, и был построен btree‑индекс по ней, который хранит данные в отсортированном виде и гарантирует порядок сортировке на входе MergeJoin. Для расчёта стоимости MergeJoin планировщик должен оценить диапазон значений колонки, для этого он пытается открыть индекс и прочитать первое и последнее значения колонки.
Проблема заключалась в bloat. VACUUM не удаляет bloat из индексов. А при удалении полигонов мы всё время удаляли самые старые по timestamp данные — те строки с начала индекса. При удалении старых полигонов строки, соответствующие минимальным значениям timestamp в индексе, становятся невидимыми. И для поиска минимального значения приходилось двигаться по индексу вправо, пока не найдём первую видимую строку.
Таким образом, время планирования запроса увеличилось с долей мс до десятков мс. Плюс к этому на планирование этого запроса полностью съедался весь CPU на реплике, хотя исполнение самого запроса занимало единицы мс. Всё это продолжалось, пока не придёт VACUUM и не почистит удаленное.
Идея фикса была в том, чтобы добавить snapshot нового типа: который видит только что удалённые строки, а фильтрует только строки, которые уже точно никому не видны, — и сканировать индекс, используя его. План выполнения получался таким же, а CPU на его выбор стало тратиться гораздо меньше.
Итого, в процессе разбора этой ситуации мы раскопали интересный эффект: текущая на тот момент инсталляция сканировала индекс с помощью SnapshotDirty, принимала незакоммиченные строки и отклоняла мёртвые строки. Получился вот такой коммит.
Нужно ли быть матёрым сеньором, чтобы начать что-то делать в опенсорсе?
Нет. Все прошлые истории выглядят сложно, но чтобы начать что‑то делать не обязательно 30 лет прокачивать свои скилы. Вселенная опенсорсных СУБД огромна, место найдется всем. Меня зовут Леонид Борчук @leborchuk и я занимаюсь Greenplum — MPP аналитической БД на основе PostgreSQL.
В мае 2024 года Greenplum стал closed source (молча, без каких‑либо официальных комментариев). Сообщество в ответ самоорганизовалось и продолжило развивать БД под названием Сloudberry. Первое время это был проект разработчиков из HashData (Пекин) и Яндекса (Москва), но спустя какое‑то время мы стали проектом Apache, и география участников проекта существенно расширилась.
Cloudberry был форкнут от greenplum в феврале 2022 года, ещё на этапе beta‑версии Greenplum 7. Было проделано много работы: в частности, что важно для дальнейшего повествования, ядро обновлено на PostgreSQL 14.4. Однако основной проект Greenplum продолжал развиваться и к моменту ухода в closed source команда разработки (спасибо им большое за это) выпустила две стабильные версии.
Когда мы начали стабилизировать Сloudberry, то обнаружили, что большинство проблем уже было исправлено за прошедшие два года с момента форка. Решили, что нужно превентивно бороться с проблемами: не ждать, когда столкнемся с багом, а черри‑пикнуть уже сделанные изменения. К сожалению, из‑за изменений ядра PostgreSQL просто так забрать изменения уже было нельзя. Нужно было понять, что делает каждое из изменений, и переписать его на новой кодовой базе.
Для оценки объема работы собрали список всех коммитов‑кандидатов на cherry‑pick. Получилось 2994 штуки в нашей комьюнити‑таблице. Далее мы прошлись по всем изменениям и разметили их: стоит ли брать это изменение или нет. Осталось 2195 коммита. На момент написания статьи более 1600 коммитов мы уже перенесли: это изменения в основные компоненты — executor и оптимизатор, а также критичные багфиксы. Остаётся еще много работы, и большей частью это фиксы в инфраструктуру вокруг БД и малозначимые изменения.
Работа над черри‑пиками уже сделанных изменений — отличный способ начать что‑то разрабатывать в проекте. У вас есть код, есть Cloudberry, который работает. И у вас есть уже поревьювленное изменение старой командой Greenplum. Дальше нужно понять, что делает это изменение, переписать его на новую кодовую базу, прогнать тесты, сделать пул‑реквест, и вот вы уже участвуете в проекте. Переписать готовое решение гораздо проще, чем с нуля разбираться с не самым простым кодом. Постепенно узнаёшь, как проект разбит на модули, какие есть либы и какие структуры используются в коде, за что они отвечают, учишься вносить изменения, правильно их тестировать и общаться с сообществом.
Приходите в это обсуждение, будем рады. Специалисты по PostgreSQL и Greenplum сейчас очень ценны.
Комментарии (11)
funca
09.06.2025 11:47Первое время это был проект разработчиков из HashData (Пекин) и Яндекса (Москва), но спустя какое‑то время мы стали проектом Apache, и география участников проекта существенно расширилась.
Иными словами, простые парни из Китая и РФ подарили свой проект США. Несколькими годами раньше это наверное воспринимались иначе, но сейчас выглядит как каламбур. Не критика, просто забавно.
С момента основания Apache Software Foundation выглядели как чокнутые собиратели разного добра со всего интернета. Они с радостью принимают к себе под зонтик как успешные в моменте проекты, так и давно мёртвые, которым место в музее или на свалке истории.
Фишка в том, что через эту организацию США предоставляют проектам эксклюзивную юридическую прописку на своей территории. В этом их ключевое отличие от, допустим, GPL или MIT, где юрисдикция проекта не определяется, что дает возможность контрибьюторам из разных стран в полной мере пользоваться своими гражданскими правами.
Юридически это работает так: если в проекте ASF засветились какие-нибудь американцы, то он автоматически сразу и весь целиком начинает подпадать под защиту местного законодательства, включая пресловутый экспортный контроль https://www.apache.org/licenses/exports/ (справедливости ради, сейчас на них не распространяются правила эмбарго. Но это буквально один абзац в законодательстве, который может быть перевернут в любой момент, а контрибьюторы или мейтейнеры из других стран остаться без доступа и не у дел).
hogstaberg
09.06.2025 11:47На всякий случай напоминаю, что и GPL не панацея если уж так случилось, что главные мейнтейнеры и организаторы проекта в США сидят (вдруг все уже забыли как Линус с Грегом исключили несколько российских разработчиков по-сути просто из-за совета юристов придерживаться требований экспортного контроля). У меня лично есть сильные подозрения, что в реальном мире все эти сорта лицензий опенсорса - разные профили одного и того же яйца,. И в любой непонятной ситуации на их нарушения закрывают глаза.
apcs660
09.06.2025 11:47спасибо за информацию, если посмотрим на лицензию apache 2.0, то получается что сеть покрытия лицензией apache 2.0 можно и нужно расширять - для блокирования проектов использующих продукты под лицензией апаче.
К примеру, модифицировал проект на основе апаче лицензии, но не все компоненты изменены и попадаем на блокировку: "Users can create derivative works and distribute them under different licenses, but must ensure that all unmodified parts of the original software remain under the Apache 2.0 license. "
Хотя, если дошло до эмбарго и блокировок, то на лицензии наплевать...
apcs660
09.06.2025 11:47раньше попадались ускорители для баз данных - CAM память (content addressable) и блок обычной (для удешевления). Ускорение поиска в несортированных массивах.
Вопрос специалисту: актуальна еще тема CAM памяти для ускорения баз или заглохла?
x4mmm Автор
09.06.2025 11:47Облака не очень любят специализированное железо: один и тот же гипервизор должен подходить для всех задач. Исключения встречаются: GPU для нейросетей и гейминга, атомные часы для Spanner. Но вот даже с этими часами подход не стал мейнстримом: алгоритмы видимости строк, основанные на времени, либо стараются сделать устойчивыми к отклонению часов (Clock-SI), либо делают из привычных компонент часы получше чем обычно (Amazon Time Sync Service).
Моя точка зрения — базы данных и так уже сильно повлияли на commodity-железо, компьютеры уже сделаны для баз данных и дальнейшая специализация не предвидится. Но не все со мной согласны! Если хотите вдохновится на более железячные базы данных — рекомендую доклад с SIGMOD 2019 про "Dark silicon — a currency we do not control" https://plds.github.io/slides/KTHTalk-pirk.pdf
apcs660
09.06.2025 11:4715 лет не смотрел тему CAM. Причем тут облака?
Глянул, приложения все те же - сетевые устройства, базы данных. Очень быстро и очень дорого.
360 миллиардов запросов в секунду поиск в таблице, для связу 40G+. Впечатляет...Устройство с чипом 20 мбит стоит больше пары тыс баксов. Сильно дешевле не стало, больших объемов все так же нет.
Продукт не массовый, вот и вся причина почему не используется опять же, в массовом сегменте.
https://ieeexplore.ieee.org/document/9211457 и прочие статьи, легко найти по запросу
Если CAM вдруг станет доступным и массовым, оно "перевернет доску" и ускорит очень многие приложения
Sleuthhound
09.06.2025 11:47Вот все говорят про оптимизацию ядра БД и прочие свистоперделки. А что про совершенствование инструментов работы с БД? Возмем к примеру pg_dump который до сих пор не умеет адекватно делать дамп с CREATE TABLE IF NOT EXISTS, а сделать дамп чтобы там не было CREATE SCHEMA public? И такого утилита не умеет. В результате чтобы этот дамп восстановить нужно еще его допилить sed/awk - Ну ребята, 21 век на дворе, а тут такое гэ. И смех и грех. Про другие "особенности" того же pg_dump я умолчу. Кстате во многих энтерпрайз форках все эти вещи допилили и довели до ума, но в ванилу никто не спещит добавлять эти удобства.
Что толку от шустрой БД если с ней нельзя нормально и удобно работать?
iamkisly
09.06.2025 11:47Если у базы не будет быстрого ядра, вы не будете с ней работать даже если у нее будут все удовлетворяющие инструменты. Да и к тому же, это же OS, если никто этого не сделал, то с этим можно относительно комфортно жить. Стало совсем не комфортно, и не можешь отказаться? Полезай в кузов.
hogstaberg
09.06.2025 11:47CREATE TABLE IF NOT EXISTS
Ненавязчиво советую вам почитать про понятия идемпотентности операций и консистентности данных (которые немношко важны в мире РСУБД). pg_dump чисто исходя из здравого смысла так уметь не должно. Оно должно уметь в
DROP ... IF EXISTS
(спойлер: оно умеет).
Sabirman
Пользуясь случаем хотел бы задать вопрос: насколько вообще востребована сейчас оптимизация баз данных? Ведь с нынешними объемами ОЗУ у подавляющего числа организаций все базы целиком в ОЗУ помещаются. У остальных в ОЗУ помещается горячая часть. Вот есть идеи для оптимизации PostgreSQL, но останавливает именно то, что непонятно кому это нужно.
x4mmm Автор
Далеко не все базы помещаются в ОЗУ, та же Почта, про базу которой мы много говорили — более петабайта. И паттерн нагрузки такой, что не рационально хранить всё в ОЗУ.
Но даже если и не брать в расчёт очень большие данные, есть что оптимизировать и в террабайтных данных, и в гигабайтных.
Стоит обсудить идеи по оптимизации в листе рассылки pgsql-hackers, насмотренность сообщества поможет определить на сколько эта оптимизация актуальна. Если же речь не об оптимизации ядра СУБД, то такие вопрос лучше всего обсудить на каком-нибудь митапе про управление данными.
Одно можно сказать уверенно: в управлении данными ещё очень много инженерных задач. Да, компьютеры быстрые, они быстрые давно, и новые горизонты производительности позволяют создавать новые неожиданные системы, создание которых раньше было бы слишком дорогим.