Недавно я получил статус Major Contributor в проекте PostgreSQL. Это довольно радостное для меня событие и интересное, поэтому коллеги попросили написать статью об этом. А чтобы я не сомневался — заботливо составили список достижений за меня. Получилось замечательно, но публиковать от своего имени статью вида «как я крут» я не хочу. Я совсем не против про это говорить, и из каждого утюга вещаю про разные технологии, сделанные моей командой или вот прям вообще мной. Но только в контексте «как использовать эти технологии», либо в узком кругу или личной беседе. 

Я решил написать другую статью: что у меня не получилось. Писал довольно спешно, поэтому, возможно, местами будет понятно только специалистам. Не расстраивайтесь, если что‑то неясно и пришлось гуглить. А вот если всё понятно — возможно, стоит меньше смотреть в монитор и чаще трогать траву.

Инкрементальное улучшение любой популярной технологии зачастую имеет негативные последствия. И в большинстве случаев предлагаемых в PostgreSQL доработок — вред превышает пользу. Построить что‑то новое, ничего не сломав, бывает трудно и в чистом поле, а ядро PostgreSQL в этом смысле — лабиринт с граблями.

Из всего, что я обещал сделать пользователям в Яндексе, клиентам Yandex Cloud, сотрудникам технической поддержки (и особенно Паше aka Amatol), своим руководителям и своим сотрудникам — из всего этого я сделал, по ощущениям, меньше трети. Большинство приключений конечной точкой имеют несколько технических тупиков, иногда я возвращаюсь к старым делам и нахожу новый путь. Чтобы оказаться в тупике подальше.

На этом пути я не один такой, достаточно вспомнить долгострой zheap, 64-битный счётчик транзакций, TDE, инкрементальные материализованные представления и много‑много других проектов поменьше.

Что же не получилось у меня на пути от первого сообщения в pgsql‑hackers до статуса Major Contributor?

Слияние страниц в B-дереве

До работы в Яндексе я специализировался на индексах. В первую же неделю моей работы мы разбирали различные проекты, которые Володя Бородин хотел поручить мне продвигать. Там были технологии резервного копирования, средства мониторинга и диагностики, управление трафиком, некоторые оптимизации — всё то, что он видел нужными компонентами создаваемой им платформы данных. На будущем сайте Yandex Cloud тогда было только видео с крутящимися вентиляторами серверов, а внутри Яндекса его продуктом уже пользовались!

И вот одной из особенностей создававшегося тогда PostgreSQL‑as‑a‑Service было регулярное пятничное перестроение B‑tree индексов с накопленным bloat. Тогда речь шла о десятках терабайт регулярно перестраиваемых индексов. Думаю, сейчас счёт уже идёт на петабайты.

Одна из причин того, что после очистки от удалённых данных страницы индекса оказываются расположены неоптимально — отсутствие в PostgreSQL реализации механизма «объединения» страниц B‑дерева. Алгоритм этой операции описан в статье «A symmetric concurrent b‑tree algorithm». 

B B‑дереве алгоритм этот довольно простой, его две стадии иллюстрируются вот такой вот диаграммой из статьи:

Конечно же, я знал про статью и оценил реализацию этого алгоритма в два дня работы. Искренне был уверен, что взял время с запасом. Но коллеги из сообщества разработчиков PostgreSQL сказали, что, скорее всего, ничего работать не будет, алгоритм плохо совместим с нашей реализацией B‑дерева. Я много раз возвращался к этому проекту, но пока упираюсь в два структурных ограничения:

  1. Алгоритм, предложенный учёными в модели pin‑ов PostgreSQL не даёт гарантии того, что IndexScan увидит какую‑либо индексируемую строчку не более одного раза.

  2. В PostgreSQL существует Backward scan, который может пропустить часть строк в гонке с объединением страниц.

Подробно последний подход к этой проблеме можно почитать тут

Сжатие протокола репликации

В Яндексе принята модель резервирования на случай отказа «−1 дата‑центр». Поэтому базы PostgreSQL в Яндексе всегда распределены между дата‑центрами. А значит, каждое изменение в пишущем узле базы данных (Replication Primary) необходимо передавать на узел горячего резерва (Standby), который может выполнять читающие запросы.

По нашим экспериментам сжатие протокола репликации могло бы повысить нам производительность репликации в 20 раз!

И самое многообещающее обстоятельство этого вопроса: когда я задался вопросом об этом, в сообществе уже был готовый патч Константина Книжника

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

Что же было препятствием для этой технологии? Кажется, что на ранних этапах сильный тормозящий импульс имели соображения безопасности. Например, в TLS сжатие данных относительно недавно удалили. Почему? Потому что сжатие потенциально раскрывает криптографию. Этот эффект известен как CRIME. Если смешать секретные данные и данные, контролируемые нападающим, — сжатие данных длиной сетевого пакета будет выдавать, насколько данные нападающего похожи на секретные данные.

Но MySQL и Oracle в своём протоколе имеют сжатие данных, оно там появилось ещё до того, как CRIME был открыт. И эти базы данных не спешат удалять сжатие протокола: оно очень полезно, а эксплуатация CRIME крайне затруднительна. Да и разновидность CRIME есть в PostgreSQL в виде сжатия WAL. Именно поэтому управление WAL compression доступно только суперпользователю, который должен оценить риски. 

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

Крайние случаи гарантий синхронной репликации

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

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

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

Про это у нас с Женей Дюковым есть подробный доклад на Highload и доклад на FOSDEM

Этот вопрос неоднократно обсуждался с сообществом. Крупные облака (AWS RDS, Azure, Yandex Cloud) используют патч, функционально эквивалентный тому, что мы предложили сообществу.

Но убедить коммиттеров в необходимости запретить отмену нереплицированного запроса я пока не смог.

Ускорение компрессии pglz

В 2019 году за обедом я рассказал Володе Лескову о том, как в ClickHouse ускорили декомпрессию lz4 при помощи ансамбля аппаратно‑зависимых методов оптимизации. 

Володя увлекается олимпиадами и имеет медаль с чемпионата мира ACM ICPC. На идеи перекладывать байты более крупными фиксированными пачками он сказал что‑то в духе: «Асимптотически такие оптимизации ничего не меняют. Надо просто перекладывать байты расширяющимся диапазоном». Когда что‑то действительно просто, олимпиадники не говорят, что это просто — они пытаются показать пантомимой или вспомнить подходящий анекдот. А вот если они сказали «просто» — скорее всего, это что‑то, что можно найти в научных статьях или профильных форумах. Идею мы реализовали сразу после обеда, и она стала частью PostgreSQL, ускоряя декомпрессию кодека pglz.

Но Володя не остановился. В воскресенье, пока команда, которую он тренирует, писала контест, он написал аналогичное ускорение для сжатия.

Но эта оптимизация получилась громоздкой, и строчек кода там слишком много. 

В результате обсуждения мы пришли к тому, что надо оптимизацию разделить на четыре части. Но интереса и энергии уже не хватает, чтобы это сделать: Володя занимается совсем другими вещами, а у меня не хватает мозгов, чтобы разобраться в деталях кода в патче.

BFS vs DFS

Это лишь малая часть проектов, результат которых — нагретый воздух и чуть‑чуть улучшенная модель процессов базы данных в головах разработчиков. Как сказал коллега Кирилл Решке: «Теперь ты меньше не понимаешь Postgres».

Из этих проектов может показаться, что где‑то просто надо было быть настойчивее, выбирать меньшее направлений разработки, но зато в большем количестве случаев доводить проект до некоторого успеха, когда польза от разработки превышает вред и её можно использовать. Меня и самого иногда пугает, что некоторые проекты выглядят как известный мем:

Но я убеждён, что аналогия с выкапыванием туннелей тут подходит плохо. Большинство незавершённых проектов создают инфраструктуру для того, чтобы какие‑то другие проекты могли завершиться и причинить пользу.

Говорят: «дорогу осилит идущий». Так вот, лабиринт с граблями тоже строится поступательно, но во многих направлениях сразу.

Комментарии (20)


  1. Sleuthhound
    10.11.2025 14:41

    Спасибо за статью Андрей и за uuid v7 который наконец-то в ядре v18.

    Кажеться, что Postgres давно бы мог излечиться от многих врожденных болячек, но консервативный подход core team делает свое дело - тормозит развитие Postgres.

    Или я не прав?


    1. x4mmm Автор
      10.11.2025 14:41

      Я очень раз что новый UUID полезен :)

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

      В случае с Постгресом всё, конечно, не так однозначно, нам надо двигаться вперёд. Но осторожно, стараясь ничего не сломать.

      То что UUIDv7 не вошёл в PostgreSQL 17 из-за того, что feature freeze случился за две недели до принятия RFC 9562 - это, по моему мнению, конечно плохо. Надо было коммитить год назад, мой код был готов.

      Но в общем случае - в операционной базе данных стабильность превыше всего.


      1. Sleuthhound
        10.11.2025 14:41

        Это вечная борьбы - делать новые революционные фичи и не сломать старое. Что выбрать?

        Многие продукты, как мне кажеться, нашли этому решение.

        Например, тот же MySQL с 2023 года формирует Innovation релизы в которых есть супер-новые фичи, да возможны проблемы, но есть выбор - сиди на LTS или бери Innovation

        У Clickhouse так же есть LTS ветки и обычные.

        Не из мира БД - Haproxy, Zabbix, nginx и бог знает еще что, так же придерживаются концепций LTS релизов и быстрых релизов с новыми фичами.


        1. vanxant
          10.11.2025 14:41

          Не представляю себе реальных пользователей бета-версий СУБД с чем-то сложнее домашнего бложика или стартапа с главным активом в виде дизайна презентации. Потерять данные, потому что какая-то транзакция полгода назад некорректно реплицировалась, и теперь у нас остатки по складам не сходятся? Нужно останавливать склад на недельную инвентаризацию? Нет, спасибо.

          Меня лично прям прёт от подхода, когда выходит в среднем 1 версия софтины в год и всё, никаких минорный версий и патчей. И она просто работает, ичсх без багов.


          1. Sleuthhound
            10.11.2025 14:41

            Речь не о бета выпусках (они кстате есть), а о смене модели формирования релизов и мышления в core team. Чтобы выделить какой-то roadmap ликвидации основных болячек, да хоть какой-то roadmap (которого в принципе нет, там написано no formal list of feature requirements required for development), позволить принимать патчи более оперативно и не мурыжить авторов годами.

            Возьмем к примеру патч с 64-битным счетчиком транзакций от постгреспро - уверен он оттестирован и проверен, но не принимают в ванилу, почему? Он большой, затрагивает много чего… очень интересная причина. А может причина в том что он исправит родовую травму и у платных дистрибутивов постгрес будет -1 платная фича?

            Тот же патч Андрея (uuid v7) который не вошел в 17 версию по смешной причине с rfc.

            Есть и другие интересные и нужные патчи которые остались висеть в комитфестах без продвижения потому что автор просто устал ждать и убеждать.

            Любой новый функционал должен покрываться тестами и соответствовать каким-то адекватным требованиям и при наличии таковых он имеет право быть принятым, но…


            1. x4mmm Автор
              10.11.2025 14:41

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

              Мы в Ржакенхилле (офис команды разработки в Екатеринбурге) играем в игру "назови 10 причин не коммитить это". В простой версии для commitfest item. В сложной - для commit log.

              Роберт говорит "we tend to make a committer anyone who understands what actually can be committed". Думаю, это гипербола, но всё же что-то в этом есть.


              1. maximvf
                10.11.2025 14:41

                Как тут не вспомнить fail story из PG 18:

                525392d Don't lock partitions pruned by initial pruning

                1722d5eb Revert "Don't lock partitions pruned by initial pruning"

                Бета нужна. И тестеры тоже нужны.


              1. Sleuthhound
                10.11.2025 14:41

                Внимание дефицитно наверно потому, что все они работают в каких-то компаниях на full time, а роль комитера в postgres она в режиме совместительства. Интересно есть ли разработчики внутри postgres кто работает только там на full time?

                Почему же контрибьюторов не сильно много? Рискну предположить, что из-за модели разработки, из-за высокого порога вхождения. Кажеться, что сама модель разработки postgres далека от совершенства и даже не пытается измениться. Комитфесты, рассылки в hackers, присылание файлов patch, боже даже irc есть (интересно там кто-то есть?), система ревьювинга и коллективной разработки из прошлого века (уж простите, я избалован github/gitlab/gitea/forgejo/jira и прочими удобными инструментами, забросайте меня помидорами, я их люблю).


                1. x4mmm Автор
                  10.11.2025 14:41

                  Вот тут есть определённое искажение восприятия, которое я часто встречаю. Абсолютное большинство коммиттеров и контрибьюторов full time работают над Постгресом. И уровень разработки открытого кода на голову выше любой коммерческой разработки.

                  Да, процесс разработки сложился до того, как появился git. Тем более Github. Но сам процесс редко является проблемой. А вот когнитивная сложность системы, высокая связность движущихся частей - является причиной проблем. Linux модульный и там есть коммиттеры в разные части. Коммиттер Postgres внося изменения отвечает за всю систему + совместимость с расширениями, драйверами, экосистемой из тулзов.


                  1. Sleuthhound
                    10.11.2025 14:41

                    >Абсолютное большинство коммиттеров и контрибьюторов full time работают над Постгресом.

                    Согласен, работают, но речь то про другое. Работают ли они full time над ванилой или full time над ответвлением постгрес в рамках коммерческой компании где они трудоустроены? Это все же разные постгрес и разные процессы. Какой процент времени они готовы тратить на ванилу, а какой на коммерческий продукт компании? Я уверен, что у все этот процент есть, так же как и есть список фичей которые коммерческая компания готова отдать в ванилу, но примут ли это в ванилу - риторический вопрос.

                    >Но сам процесс редко является проблемой

                    Не согласен. Вот пришел человек с патчем, предлагает фичу/багфикс, а в ответ тишина, пушит патч по 10 раз и снова тишина. Это не проблема когнитивной сложности системы, до этой части процесса дело даже не дошло. Это проблема процесса разработки, когда у комитеров/ревьюверов нехватка времени/сил или чего-то еще, чтобы проверить этот патч или хотя бы дать ответ человеку - мол хэй, ты молодец, но мы тут что-то загружены, давай ты пушнешь патч через пару недель когда будет посвободней. Ну а когда большой патч с классной фичей отклоняют, что мол мы не можем его проревьювить, мы боимся что он что-то поломает в неочевидном месте? По-моему это тоже проблемма процесса - мы не можем наладить процесс тестирования продукта, чтобы тесты покрывали наиболее важные части кода и когда мегафича что-то ломает, то тесты бы это отражали.


                    1. x4mmm Автор
                      10.11.2025 14:41

                      Работают ли они full time над ванилой или full time над ответвлением постгрес в рамках коммерческой компании где они трудоустроены? Это все же разные постгрес и разные процессы.

                      Нет, когда я говорю Постгрес - я имею ввиду ванильный Постгрес, а не что-то типа Постгреса. Абсолютное большинство коммиттеров и контрибьюторов full time работают над Постгресом. А не чем-то типа.

                      И да, коммерческие компании готовы отдать в ваниллу что угодно. Но оно не того качества, которое требует ванила.


                      1. Sleuthhound
                        10.11.2025 14:41

                        Любопытно про что угодно и не того качества.

                        Но если честно, я в это слабо верю. Если ПостгресПро отдает приличное количество наработок в ванилу, то например от Тантор я не вижу рвения (или они втихушку это делают?). Возможно причина отчасти как раз в качестве кода, типа "А ну и так сойдет для ком. клиентов", но сдается мне, что есть и другая составляющая. Ну честно, не верю я что компания готова по доброте душевной отдать коммерческие наработки в ванилу. Ну выложили бы тогда все патчи у себя на сайте - берите люди добрые, у кого хватит сил и терпения - патчите и собирайте свои версии постгрес, а у кого еще и железные яйца, то используйте в проде. Но реальность увы другая Андрей.


                      1. x4mmm Автор
                        10.11.2025 14:41

                        Моё мнение - любой форк строго хуже ваниллы. Причём это касается даже мастера ванилы, который хуже релиза. А свежий релиз хуже прошлогоднего. Настоящий Постгрес начинатеся где-то с версии х.3 или х.4.

                        Ребята и из ПгПро, и из Тантора выкладывают патчи и чинят баги в ванилле - это замечательно. Сравнивать их коммерческие продукты не берусь (и даже не буду делать выводов из толпы PgPro в 40 человек в pgsql-hackers, хотя это хочется отметить! Тантор есть в хакерсах, это тоже замечательно, ждём остальных)


  1. antoxin
    10.11.2025 14:41

    Прошу пояснить насчет CRIME. Поток репликации ведь может быть зашифрован SSL. Какая разница что при этом льется, сжатые данные или нет?


    1. x4mmm Автор
      10.11.2025 14:41

      Если у нападающего есть возможность писать в базу данных и сделать так, чтобы его изменения сжимались вместе с какими-нибудь секретными данным - по длинне передаваемых данных он может понять насколько его данные похожи на секрет. Тут лучше поподробнее почитать CRIME, это очень инетерсная штука. Из-за неё сжатие удалили из TLS, сжатие существенно ослабляет криптографию.


      1. vanxant
        10.11.2025 14:41

        Вы очень сильно преувеличиваете, как и авторы CRIME.

        Из общего TLS может и удалили. Но в http/2 и 3, а также в большинстве других распространённых протоколов, использующих TLS, уже есть своё сжатие, и им ещё одно сжатие нафиг не впилось. И на секурность не влияет.


    1. vanxant
      10.11.2025 14:41

      Не обращайте внимания, это сугубо теоретические розовые сопли. Для атаки на репликацию postgres вам нужен а) доступ на прослушку канала репликации между шардами; б) ровно один писатель в мастер БД, который шлёт "сикретные сикреты" (одни и те же) с низкой энтропией и в) возможность слать свои запросы с произвольным текстом. Тогда, если вы случайно угадаете "секрет" или его достаточно длинную непрерывную часть в своём запросе, вы увидите, что сжатый пакет репликации имеет размер меньше, чем несжатый (ну так работают алгоритмы на базе LZW, не передают одно и то же дважды).

      Автору статьи хочу посоветовать привести пример хоть одной реальной системы, где "секреты" - например, access token'ы - обладают низкой энтропией и передаются в открытом виде (типа пароля 12345). И честно признаться, виноват ли тут CRIME или может всё-таки лень юзера с таким паролем.


      1. x4mmm Автор
        10.11.2025 14:41

        Начнём с того, что я не преувеличиваю, а констатирую наблюдаемые свойства атаки, указывая на все ограничения. В рассылке я, точно также как и вы, был сторонником включения сжатия, но настройкой суперпользователя. И сообществе в итоге пришло именно к такому консесусу по этому вопросу.

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

        Из приведённых вами примеров. Доступ на прослушку? Подходите творчески, достаточно доступа к мониторингу, например роли pg_select_all_data, чтобы увидеть представление со статистикой по сети. Ровно один писатель в БД в период времени длинной в сотни микросекунд. Это редкость? Нет. Секретные данные вместе с несекретными? Ну, допустим, у пользователя есть право менять свой пароль. Хэш его пароля лежит на одной страничке с md5 админа. Full page image уехавший по сети раскрывает пароль админа. Наконец, про энтропию - вам не нужно угадывать весь хэш за один раз, вы можете сделать тысячу смен паролей и подобрать хэш постепенно, по одному байту. В pgsql hackers можно найти эксплойт, который за 400 смен паролей атакующего вытаскивает хэш суперюзера, с которым потом можно зайти в базу. Любую, без особой специальной подготовки, просто включить сжатие и получить доступ к мониторингам базы!

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


        1. vanxant
          10.11.2025 14:41

          В pgsql hackers можно найти эксплойт, который за 400 смен паролей атакующего

          вы забыли одно маленькое условие - в этот момент никто другой с базой работать не должен от слова совсем. Не самый частый случай для продовой базы с секретной инфой.

          Подходите творчески, достаточно доступа к мониторингу, например роли pg_select_all_data

          Да блин, ну это смешно. Если у меня есть pg_select_all_data, то я уже суперадмин. Зачем мне подбирать хэш, если я имею право его тупо прочитать?

          не относитесь к безопасности своих систем вот так

          ну а как? У каждой меры "безопасности" есть своя цена. В случае со сжатием репликации - это цена канала между серверами, отнюдь не нулевая. А вы рассказываете про появившихся откуда-то неизвестных атакующих с pg_select_all_data. Это театр, а не инженерия.


          1. x4mmm Автор
            10.11.2025 14:41

            вы забыли одно маленькое условие - в этот момент никто другой с базой работать не должен от слова совсем. Не самый частый случай для продовой базы с секретной инфой.

            Во-первых, уязвимость остаётся уязвимостью, даже если для эксплуотации требуется тишина. Во-вторных, не требуется, изменения пройдут в несколько сотен байт WAL, которые часто окажутся подряд даже в очень нагруженной системе. Но это всё не важно, я не хочу публично развивать идеи эксплуотации CRIME.

            Да блин, ну это смешно. Если у меня есть pg_select_all_data, то я уже суперадмин. Зачем мне подбирать хэш, если я имею право его тупо прочитать?

            Нет, это не так, pg_select_all_data не может читать pg_authid. Но цель, конечно, выйти из базы и атаковать соседние системы.

            цена канала между серверами, отнюдь не нулевая

            Это так с точки зрения применения в конкретной системе.

            А с точки зрения массового продукта, сообществе Postgres не хочет чтобы настройки по-умолчанию приводили к известной уязвимости. Кроме этого, у security team есть определение уязвимости, под которое CRIME попадает, если сжатие ключено сервером из коробки.

            А вы рассказываете про появившихся откуда-то неизвестных атакующих с pg_select_all_data. Это театр, а не инженерия.

            Доступ к мониторингу может быть получен другим способом. Типичные взломы проводятся с комбинацеий уязвимостей, кроме того приправляются социальной инженерии. В моём примере CRIME используется для выхода из СУБД на машину, но цели и условия могут быть иные. Я не ломаю вашу базу, я только демонстрирую, что уязвимые к таком вектору атаки системы существуют.

            ну а как?

            Если вы администрируете базу данных - просто обновляйте софт вовремя. Основной вектор атаки в большинстве случаев - эксплуотация известных уязвимостей, если против вас используют zero day - вы бы не писали эти вопросы. Если вы разрабатываете приложение - временами просматривайте OWASP всем коллективом разработчиков - уже это сделает вашу систему намного более сложной целью в куче других атакуемых систем. Если вы разрабатываете базу данных... фиг знает, стоит изучать все существующие уязвимости. Могу порекомендовать мои работы: тренажер github.com/x4m/pg_cve_demo/ и статью https://xakep.ru/2021/12/03/postgresql-cve-history/