Как стать автором
Обновить

Роковой каскад: JIT, и как обновление Postgres привело к 70% отказов на национальном сервисе критической важности

Время на прочтение 12 мин
Количество просмотров 18K
Всего голосов 43: ↑41 и ↓2 +39
Комментарии 14

Комментарии 14

Хоть авторы и не увидят, но есть подозрение, что jit не кэшировался из-за баунсера

Вот тут (правда, всего лишь 2019 год) на 7 слайде говорится, что можно кэшировать вручную: http://ivannikov-ws.org/2019/docs/Buchatskiy.pdf

И дальше интересно:

With minor modifications to PostgreSQL query plan data structures we can save a pointer to generated machine code and reuse it together with prepared GENERIC plan. But this is not enough as absolute addresses of run-time data structures that we use during code generation change on every query execution. At the run-time the execution control flows from JIT to PostgreSQL functions and vice versa. => Need to update obsolete addresses in generated machine code before it can be used again.

Простите душнилу, но не могли бы мд разметку переделать под хабр, совсем чуть чуть глаз режет при чтении)

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

А кривые ссылки поправил, да

Спасибо за перевод, очень интересно!
В целом я не понимаю людей которые обновляют major version на проде через две недели после выхода и на след. день после релиза облачного провайдера. Другое поколение. Можно обозвать меня бумером - так оно и есть.
И да, если погонять нагрузку в staging подольше, то вероятность обнаружения ошибки увеличивается.

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

Жаль, что автор не написал, какие ещё были сделаны изменения.

Я просмотрел комменты на dev.to. Про мониторинг не очень понятно.
Но в целом мне кажется что система у них неоправданно сложная и большая - он упоминает "we have ~8 billion records in the DB". Это примерно 120 записей на каждого британца. Зачем? Почему нет агрегации за прошлые месяцы?

Мне кажется, надо пойти в комменты и накомментировать там 🙂 Может, займусь...

Да тут вся картина говорит о каком-то лютом бардаке. "Почему мы не смогли увернуться от пуль, когда стреляли себе в ногу из пулемёта".

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

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

А что вы предлагаете, ждать и надеяться что кто-то наступит на тот же баг что случится у вас, его зарепортят и починят? Сколько именно нужно ждать? Придерживаться ли ритуалов вроде "никогда не ставить x.0"? Какие это даст гарантии? Может вообще не обновляться?

И да, если погонять нагрузку в staging подольше, то вероятность обнаружения ошибки увеличивается.

Вот же правильный ответ, только на stg можно гонять следующий релиз задолго до собственно релиза. А если на stg под рабочей нагрузкой идеально работает хоть альфа, что мешает выкатить хоть альфу в прод если от этого будет профит? Тем более что можно выкатить на 10% кластера и мгновенно откатить?

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

Это, возможно, только верхушка проблем с JIT. С год назад я чинил в 13.0 устойчивое падение бэкенда в llvmjit на FreeBSD. В двух словах, там оказалось что LLVM не умеет инлайнить функции с обращениями к thread local storage, а под FreeBSD в TLS хранятся параметры локали, которые используются из функций типа isspace(). isspace(), в свою очередь, используется много где в коде PostgreSQL, в частности при конвертации типов (чтобы пропустить не значащие пробелы), например при конвертации текста/json в bool (boolin()), где оно, собственно и падало. В Linux, видимо, isspace() устроена по другому, поэтому там это так сильно не стреляло.

Так вот, оказалось что testsuite постгреса не прогонялся с JIT вообще (он даже не собирался с поддержкой JIT; ЕМНИП там код должен был собираться два раза - по классике для обычных вызовов и в объектный код LLVM для JIT). Не знаю, может быть с тех пор это починили, но непокрытую тестами фичу я бы на месте авторов постгреса не стал выкатывать.

Зарегистрируйтесь на Хабре , чтобы оставить комментарий