Переехали с MySQL 8.0 на Postgres 17 и через девять дней откатились. Вскрытие
Рейтинг: 48.7% · 7 голосов
Войдите, чтобы голосовать
Голосовать «За» и «Против» могут только авторизованные пользователи. Войдите в свой аккаунт — или зарегистрируйтесь, это займёт минуту.
Нет аккаунта? Зарегистрироваться
Переехали с MySQL 8.0 на Postgres 17 и через девять дней откатились. Вскрытие
Расскажу как мы красиво вляпались, может кому сэкономит седые волосы. Вводные: интернет-магазин, MySQL 8.0.42, база 600 ГБ, пик 3500 rps на чтение. Захотели Postgres ради партиционирования и нормального jsonb, плюс девопсы давно ныли, что весь остальной зоопарк у нас на постгресе и им надоело держать два стека бэкапов.
Миграцию гнали pgloader-ом, на стейдже прокатили три раза, все зеленое. Переключились в ночь на воскресенье, даунтайм 40 минут, полет нормальный. А дальше началось.
День первый: посыпались жалобы, что поиск по артикулу не находит товары. В MySQL collation был utf8mb4_general_ci, регистронезависимый. В постгресе сравнение строгое, и весь легаси-код, где искали по email или артикулу без lower(), молча перестал находить. Таких мест насчитали 47.
День третий: легла админка. Там экран со счетчиками, восемь count(*) по большим таблицам. MySQL отдавал из статистики мгновенно, постгрес честно сканировал. Переписали на reltuples, но осадочек остался.
День пятый: дедлоки на апсертах. ON DUPLICATE KEY UPDATE конвертнули в ON CONFLICT, но порядок блокировок другой, под нагрузкой начало стрелять. Плюс автовакуум не успевал за таблицей заказов с ее диким update rate, bloat попер на глазах.
День девятый: бизнес сказал хватит. Откат на бэкап плюс ручная доливка заказов за девять дней скриптом. Двое суток ада.
Вывод для себя: постгрес не виноват, виновата оценка масштаба. Мы мигрировали базу, а мигрировать надо было приложение. Сидим на mysql дальше, выпиливаем регистрозависимые места и count(*), к осени попробуем второй заход.
Миграцию гнали pgloader-ом, на стейдже прокатили три раза, все зеленое. Переключились в ночь на воскресенье, даунтайм 40 минут, полет нормальный. А дальше началось.
День первый: посыпались жалобы, что поиск по артикулу не находит товары. В MySQL collation был utf8mb4_general_ci, регистронезависимый. В постгресе сравнение строгое, и весь легаси-код, где искали по email или артикулу без lower(), молча перестал находить. Таких мест насчитали 47.
День третий: легла админка. Там экран со счетчиками, восемь count(*) по большим таблицам. MySQL отдавал из статистики мгновенно, постгрес честно сканировал. Переписали на reltuples, но осадочек остался.
День пятый: дедлоки на апсертах. ON DUPLICATE KEY UPDATE конвертнули в ON CONFLICT, но порядок блокировок другой, под нагрузкой начало стрелять. Плюс автовакуум не успевал за таблицей заказов с ее диким update rate, bloat попер на глазах.
День девятый: бизнес сказал хватит. Откат на бэкап плюс ручная доливка заказов за девять дней скриптом. Двое суток ада.
Вывод для себя: постгрес не виноват, виновата оценка масштаба. Мы мигрировали базу, а мигрировать надо было приложение. Сидим на mysql дальше, выпиливаем регистрозависимые места и count(*), к осени попробуем второй заход.
✔ Лучший ответ сформирован автоматически — chase2
По регистронезависимости: citext до сих пор рабочий вариант, ставишь расширение и тип колонки, код трогать почти не надо. С PG 12 есть еще недетерминированные collation, но у них до 18-й версии не работал LIKE, так что для поиска по артикулам это была ловушка. По дедлокам на ON CONFLICT: сортируйте строки в батче по ключу перед апсертом, лечит 90 процентов таких стрельб. И автовакуум на горячих т…
Re: Переехали с MySQL 8.0 на Postgres 17 и через девять дней откатились. Вскрытие
✔ Лучший ответ — сформирован автоматически
По регистронезависимости: citext до сих пор рабочий вариант, ставишь расширение и тип колонки, код трогать почти не надо. С PG 12 есть еще недетерминированные collation, но у них до 18-й версии не работал LIKE, так что для поиска по артикулам это была ловушка. По дедлокам на ON CONFLICT: сортируйте строки в батче по ключу перед апсертом, лечит 90 процентов таких стрельб. И автовакуум на горячих таблицах надо крутить руками сразу, autovacuum_vacuum_scale_factor 0.01 и naptime пониже, дефолты для таблицы заказов это смерть.
Re: Переехали с MySQL 8.0 на Postgres 17 и через девять дней откатились. Вскрытие
Не согласен с выводом ТС. Проблема не в оценке масштаба, проблема в том, что стейдж не повторял боевую нагрузку. Дедлоки и отстающий автовакуум вылезают только под живым трафиком, хоть десять раз прогоняй pgloader на копии. Перед вторым заходом поднимите теневое окружение и лейте туда реальный трафик через зеркалирование, иначе наступите ровно туда же.
Re: Переехали с MySQL 8.0 на Postgres 17 и через девять дней откатились. Вскрытие
Мы такой же переезд делали в 2024, только полгода гоняли двойную запись в обе базы через debezium и кафку и сравнивали ответы ридеров. Скучно, дорого, зато переключение прошло без отката и без даунтайма вообще. Дешевых миграций баз не бывает, бывают отложенные дорогие.
Поделиться темой:
✈ Telegram
VK
- Похожие темы
-
- Внедрили ClickHouse, а Postgres всё равно никуда не делся. Так и должно быть?
20 ответов · 1698 просмотров
-
- Переехали с Kubernetes на docker-compose и сэкономили кучу времени — кто ещё так делал?
16 ответов · 1187 просмотров
-
-
-
- Команда из 8 человек тратила 60 часов в неделю на k8s. Переехали на docker-compose и выдохнули
9 ответов · 624 просмотров
-
- Решил кэшировать прямо в Postgres вместо Redis, чтобы не плодить зависимости. Норм идея?
3 ответов · 248 просмотров
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость