Сила факапов
Я честно и последовательно считаю, что ошибки — самое ценное, что происходит в профессиональной деятельности. Те, кто притворяются, что не ошибаются — врунишки, и будут биты первыми. Сила факапов, в том, что это ценнейший источник опыта!
Короче, мой факап: в середине 2010х делали проект, огромные нагрузки, куча пользователей. Это был конкурс с пиком активности под ~80 000 ежедневных пользователей и 320 000 регистраций на круг.
Мы со своей стороны, как продакшен-команда, занимались разработкой, запуском и сопровождением. Проект находится на 6 неделе релиза. Большинство проблем решено, всё стабильно, конкурсная механика работает, как часы. Приходит клиент и говорит: "ой, мы забыли про ФЗ-152 и не сделали удаление персональных данных".
Дело срочное, не терпит отлагательств, я берусь в ночи сделать таску. В целом она простая: удалить профиль и сделать вложенный запрос по id пользователя к таблице с интеграциями (vk/fb/tw/фитнес-трекеры), и удалить данные, с ним ассоциированные.
Как выглядит это удаление: DELETE FROM steps WHERE oauth_id IN (SELECT oauth_id FROM auth WHERE user_id = 322)
Написал запрос, отладил локально, работает! Делаю релиз в прод (где-то 3 ночи), захожу в админку. Выбираю 3х пользователей (которых надо было удалить). Жму удалить, крутится лоадер... крутится... и крутится. Я понимаю — дело дрянь. Смотрю в базу, а она каждую секунду худеет на пару гигабайт 🫠
Дальше ребут, бъю в карабельную рынду поднимаю техдира заказчика, звоним индусам (девопс был на аутсорсе, что стоит отдельного поста!), начинаем им объяснять, что надо сделать, а там не то, чтобы опытные разработчики… Люди вообще плохо понимают, что происходит.
Итого: за 4 часа всё восстановили, потеряв безвозвратно примерно 8 часов данных (по части пользователей, так как базу я увел в ребут, как только понял, что происходит). В чем же была причина? Ха! Я опечатался, во вложенном запросе, вместо SELECT написал SLECT. То есть, просто пропустил букву!
Но почему оно удалило всю базу? SQL-движки ведь гарантируют лексическую проверку запроса перед исполнением? В случае опечатки лексер должен выкинуть ошибку. И ты по умолчанию доверяешь своему инструменту.
А что случилось у меня? У меня была древняя версия MariaDB (актуальная на тот момент). И в ней был баг. Если лексер выкидывает ошибку при парсинге вложенного запроса, то вместо ошибки исполнения он отбрасывал весь CONDITION и запрос уходит на исполнение без условий =)
То есть запрос вида (опечатка во вложенном SELECT): DELETE FROM steps WHERE oauth_id IN (SLECT oauth_id FROM auth WHERE user_id = 322) превратился в: DELETE FROM steps И этот баг успешно вытер мне всю базу)
Но по-настоящему факап был не в опечатке и не в системе управления БД, а в самой архитектуре. Мы хранили ПДн 320 тысяч пользователей в системе без детального аудита операций, без изоляции тестовых сред и автоматического контроля доступа.
Сейчас, когда появились облака, которые закрывают вопрос надежности и исполнения ФЗ-152, стало жить легче. И в них есть автоматические бэкапы, защита виртуализации, сетевая изоляция, средства обнаружения и предотвращения вторжений — всё, как у Рег.облака.
Поделитесь своим опытом факапов, а эксперты Рег.облака разберут лучшие кейсы и покажут, как можно было избежать проблем. Авторов историй ждет спасительный мерч от провалов.
П.С. И не забудьте забрать стикерпак «Я выжил в 404» — он поможет пережить сложные моменты в работе.
В этом посте были ссылки, но мы их удалили по правилам Сетки