- PVSM.RU - https://www.pvsm.ru -
Недавно я получил статус Major Contributor [1] в проекте PostgreSQL. Это довольно радостное для меня событие и интересное, поэтому коллеги попросили написать статью об этом. А чтобы я не сомневался — заботливо составили список достижений за меня. Получилось замечательно, но публиковать от своего имени статью вида «как я крут» я не хочу. Я совсем не против про это говорить, и из каждого утюга вещаю про разные технологии, сделанные моей командой или вот прям вообще мной. Но только в контексте «как использовать эти технологии», либо в узком кругу или личной беседе.
Я решил написать другую статью: что у меня не получилось. Писал довольно спешно, поэтому, возможно, местами будет понятно только специалистам. Не расстраивайтесь, если что‑то неясно и пришлось гуглить. А вот если всё понятно — возможно, стоит меньше смотреть в монитор и чаще трогать траву.
Инкрементальное улучшение любой популярной технологии зачастую имеет негативные последствия. И в большинстве случаев предлагаемых в PostgreSQL доработок — вред превышает пользу. Построить что‑то новое, ничего не сломав, бывает трудно и в чистом поле, а ядро PostgreSQL в этом смысле — лабиринт с граблями.
Из всего, что я обещал сделать пользователям в Яндексе, клиентам Yandex Cloud, сотрудникам технической поддержки (и особенно Паше aka Amatol), своим руководителям и своим сотрудникам — из всего этого я сделал, по ощущениям, меньше трети. Большинство приключений конечной точкой имеют несколько технических тупиков, иногда я возвращаюсь к старым делам и нахожу новый путь. Чтобы оказаться в тупике подальше.
На этом пути я не один такой, достаточно вспомнить долгострой zheap, 64-битный счётчик транзакций, TDE, инкрементальные материализованные представления и много‑много других проектов поменьше.
Что же не получилось у меня на пути от первого сообщения в pgsql‑hackers до статуса Major Contributor?
До работы в Яндексе я специализировался на индексах. В первую же неделю моей работы мы разбирали различные проекты, которые Володя Бородин хотел поручить мне продвигать. Там были технологии резервного копирования, средства мониторинга и диагностики, управление трафиком, некоторые оптимизации — всё то, что он видел нужными компонентами создаваемой им платформы данных. На будущем сайте Yandex Cloud тогда было только видео с крутящимися вентиляторами серверов, а внутри Яндекса его продуктом уже пользовались!
И вот одной из особенностей создававшегося тогда PostgreSQL‑as‑a‑Service было регулярное пятничное перестроение B‑tree индексов с накопленным bloat. Тогда речь шла о десятках терабайт регулярно перестраиваемых индексов. Думаю, сейчас счёт уже идёт на петабайты.
Одна из причин того, что после очистки от удалённых данных страницы индекса оказываются расположены неоптимально — отсутствие в PostgreSQL реализации механизма «объединения» страниц B‑дерева. Алгоритм этой операции описан в статье «A symmetric concurrent b‑tree algorithm [2]».
B B‑дереве алгоритм этот довольно простой, его две стадии иллюстрируются вот такой вот диаграммой из статьи:

Конечно же, я знал про статью и оценил реализацию этого алгоритма в два дня работы. Искренне был уверен, что взял время с запасом. Но коллеги из сообщества разработчиков PostgreSQL сказали, что, скорее всего, ничего работать не будет, алгоритм плохо совместим с нашей реализацией B‑дерева. Я много раз возвращался к этому проекту, но пока упираюсь в два структурных ограничения:
Алгоритм, предложенный учёными в модели pin‑ов PostgreSQL не даёт гарантии того, что IndexScan увидит какую‑либо индексируемую строчку не более одного раза.
В PostgreSQL существует Backward scan, который может пропустить часть строк в гонке с объединением страниц.
Подробно последний подход к этой проблеме можно почитать тут [3].
В Яндексе принята модель резервирования на случай отказа «−1 дата‑центр». Поэтому базы PostgreSQL в Яндексе всегда распределены между дата‑центрами. А значит, каждое изменение в пишущем узле базы данных (Replication Primary) необходимо передавать на узел горячего резерва (Standby), который может выполнять читающие запросы.
По нашим экспериментам сжатие протокола репликации могло бы повысить нам производительность репликации в 20 раз!
И самое многообещающее обстоятельство этого вопроса: когда я задался вопросом об этом, в сообществе уже был готовый патч Константина Книжника [4]!
Мы с командой подключились к обсуждению, от нас решением занимался Даниил Захлыстов. Со временем у автора оригинального патча интерес к вопросу, кажется, иссяк, и Даниил предпринял попытку оживить работу [5].
Что же было препятствием для этой технологии? Кажется, что на ранних этапах сильный тормозящий импульс имели соображения безопасности. Например, в TLS сжатие данных относительно недавно удалили. Почему? Потому что сжатие потенциально раскрывает криптографию. Этот эффект известен как CRIME [6]. Если смешать секретные данные и данные, контролируемые нападающим, — сжатие данных длиной сетевого пакета будет выдавать, насколько данные нападающего похожи на секретные данные.
Но MySQL и Oracle в своём протоколе имеют сжатие данных, оно там появилось ещё до того, как CRIME был открыт. И эти базы данных не спешат удалять сжатие протокола: оно очень полезно, а эксплуатация CRIME крайне затруднительна. Да и разновидность CRIME есть в PostgreSQL в виде сжатия WAL. Именно поэтому управление WAL compression доступно только суперпользователю [7], который должен оценить риски.
К тому времени, как сообщество пришло к консенсусу, что технология достаточно нужна, чтобы принять эти риски, — энергии авторов патча уже было недостаточно, чтобы продолжить работу над ним. Возможно, мы ещё вернёмся к этой теме.
Гарантии того, что ни один байт не будет потерян в случае потери узла кластера, основаны на синхронной репликации. Фиксация транзакции клиенту подтверждается только после того, как реплики получили все данные транзакции. В случае временного перебоя связи клиенту приходится дожидаться подтверждения, потенциально довольно долго.

Почему нужно ждать? Потому что другие узлы кластера могут сформировать новый кластер и больше не принять транзакцию.
Однако клиенту доступна отмена транзакции, после чего эффект её становится видимым, и клиент может ошибочно подумать, что изменения данных произошли успешно.
Про это у нас с Женей Дюковым есть подробный доклад на Highload и доклад на FOSDEM [8].
Этот вопрос неоднократно обсуждался с сообществом. Крупные облака (AWS RDS, Azure, Yandex Cloud) используют патч, функционально эквивалентный тому, что мы предложили сообществу [9].
Но убедить коммиттеров в необходимости запретить отмену нереплицированного запроса я пока не смог.
В 2019 году за обедом я рассказал Володе Лескову о том, как в ClickHouse ускорили декомпрессию lz4 [10] при помощи ансамбля аппаратно‑зависимых методов оптимизации.
Володя увлекается олимпиадами и имеет медаль с чемпионата мира ACM ICPC. На идеи перекладывать байты более крупными фиксированными пачками он сказал что‑то в духе: «Асимптотически такие оптимизации ничего не меняют. Надо просто перекладывать байты расширяющимся диапазоном». Когда что‑то действительно просто, олимпиадники не говорят, что это просто — они пытаются показать пантомимой или вспомнить подходящий анекдот. А вот если они сказали «просто» — скорее всего, это что‑то, что можно найти в научных статьях или профильных форумах. Идею мы реализовали сразу после обеда, и она стала частью PostgreSQL, ускоряя декомпрессию кодека pglz [11].
Но Володя не остановился. В воскресенье, пока команда, которую он тренирует, писала контест, он написал аналогичное ускорение для сжатия [12].
Но эта оптимизация получилась громоздкой, и строчек кода там слишком много.

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

Но я убеждён, что аналогия с выкапыванием туннелей тут подходит плохо. Большинство незавершённых проектов создают инфраструктуру для того, чтобы какие‑то другие проекты могли завершиться и причинить пользу.
Говорят: «дорогу осилит идущий». Так вот, лабиринт с граблями тоже строится поступательно, но во многих направлениях сразу.
Автор: x4mmm
Источник [13]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/postgresql/436190
Ссылки в тексте:
[1] получил статус Major Contributor: https://www.postgresql.org/about/news/new-postgresql-contributors-2025-3158/
[2] A symmetric concurrent b‑tree algorithm: https://dl.acm.org/doi/pdf/10.5555/324493.324589
[3] тут: https://www.postgresql.org/message-id/flat/11A59C0C-A8C8-4642-8493-292D5DF8311D%40yandex-team.ru
[4] готовый патч Константина Книжника: https://www.postgresql.org/message-id/flat/aad16e41-b3f9-e89d-fa57-fb4c694bec25%40postgrespro.ru
[5] попытку оживить работу: https://www.postgresql.org/message-id/flat/ABAA09C6-BB95-47A5-890D-90353533F9AC%40yandex-team.ru
[6] CRIME: https://en.wikipedia.org/wiki/CRIME
[7] доступно только суперпользователю: http://github.com/postgres/postgres/commit/c2e5f4d
[8] доклад на FOSDEM: https://archive.fosdem.org/2021/schedule/event/postgresql_caveats_of_replication/
[9] мы предложили сообществу: http://www.postgresql.org/message-id/flat/D09F0F0D-D045-4739-910F-4462AD0E0758%40yandex-team.ru
[10] ускорили декомпрессию lz4: https://habr.com/ru/companies/yandex/articles/452778/
[11] ускоряя декомпрессию кодека pglz: https://github.com/postgres/postgres/commit/c60e520
[12] аналогичное ускорение для сжатия: https://commitfest.postgresql.org/patch/2897/
[13] Источник: https://habr.com/ru/companies/yandex/articles/964778/?utm_source=habrahabr&utm_medium=rss&utm_campaign=964778
Нажмите здесь для печати.