Экстремальная Миграция На Postgresql: Без Остановки, Потери И Тестирования



Экстремальная миграция на PostgreSQL: без остановки, потери и тестирования

Всего месяц назад Яндекс.

Деньги завершили миграцию сервиса профилей пользователей с Oracle на PostgreSQL. Итак, теперь у нас есть проверенное решение для переноса больших объемов данных.

никаких потерь И останавливается воспользовавшись их сервисом.

Ниже под катом я расскажу подробнее о том, как все происходило, почему мы выбрали SymmetricDS для миграции и почему без «ручных» усилий это все равно не удалось сделать.

Также поделюсь некоторыми наработками по вспомогательному коду для миграции.

Для первой миграции и тестирования решения мы выбрали сервис, обслуживающий профили пользователей.

В профиле есть история платежей, избранное, напоминания и другие подобные вещи – все важно, но не критично для работы системы.

У нас база данных без встроенной логики, поэтому нам нужно было только перенести на новую платформу сами данные и последовательности.

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

Команда миграции состояла из 4 человек, но это были разработчики Senior уровня и специалисты DBA. Чтобы небольшая команда могла справиться в короткие сроки, мы искали максимально автоматизированное решение проекта: без написания кода миграции данных, ручной сборки схемы базы данных и т. д. База данных содержит около 50 таблиц, поэтому вероятность человеческого вмешательства ошибка особенно велика при ручном преобразовании.

Обычно такие миграции выполняются с остановкой сервиса – в нерабочее время.

Но в Яндекс.

Деньгах платежи обрабатываются круглосуточно, поэтому остановить систему ради внутренних «оптимизаций» было невозможно.

Фактически, для этого компонента компания согласилась позволить нам сделать паузу на одну-две минуты без потери данных.

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

Поэтому методом мозгового штурма мы собрали и отобрали список подходящих продуктов для миграции:

  1. Оракул Золотые Ворота - может показаться, что это та самая серебряная пуля.

    По крайней мере, пока не увидишь цену.

  2. СимметричныйDS — происходит миграция схемы, она будет создана или обновлена при регистрации узла PostgreSQL в мастер-узле Oracle. Преобразовать данные при выгрузке или загрузке можно с помощью BASH, Java или SQL.
  3. Полное преобразование — можно переносить схему и данные, но возможности настройки ограничены, нет изменяемых преобразователей (кода для изменения данных при миграции).

  4. Миграция Oracle на PostgreSQL — передает схему, данные, внешние ключи, индексы.

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

  5. Набор инструментов для миграции базы данных ESF — переносит все, что делает Oracle to PostgreSQL Migration. Данные передаются в пакетном режиме; нет возможности миграции на несколько потоков.

  6. Ора2Pg — передает схему, данные, внешние ключи, индексы, возможна миграция в несколько потоков.

    Недостатки: медленная передача таблиц с типами blob/clob (около 200 записей/сек), нет преобразователя.

  7. Инструмент SQLData — мигрирует только схема, возможности настройки ограничены.

Остальные продукты на рынке либо уже заброшены их разработчиками, либо не имеют развитой поддержки в сообществе.

В результате мы выбрали Ора2Pg передать схему базы данных и СимметричныйDS для миграции данных.

В целом последний предназначен больше для синхронизации разных СУБД, чем для передачи данных.

Но в нашем случае это позволило обеспечить миграцию без остановки сервисов.

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

PostgreSQL неправильно обрабатывал некоторые запросы, которые без проблем выполнялись в Oracle. Например, ВЫБИРАТЬ * вызвало ошибку и остановило работу всех служб, зависящих от базы данных.

В общем, подобные просьбы — дурной тон; на самом деле они были разные, и я привел их просто как допустимый пример.

Оказалось, что это скорее проблема с драйвером Java, поэтому на момент проекта было проще не использовать проблемные запросы.

Позже эта ошибка исправленный.

Также были трудности с транзакциями при установке флага Автофиксация-ВЫКЛ.

.

В PostgreSQL код аварийно завершал работу, если транзакция не была предварительно открыта при ее выполнении.

Oracle вел себя иначе: транзакция откатывалась или завершалась кодом, попавшим в тот же поток выполнения.

Решение для PostgreSQL — написать код, который проверяет наличие явно открытой транзакции для всех запросов на изменение данных.

При выполнении запросов сервис профилей пользователей не задавал порядок сортировки выходных значений (ORDER BY), так как в Oracle отсутствие знака означает вывод в хронологическом порядке.

И при этом мы скатились к PostgreSQL, который отображал результаты запросов непоследовательно — мы причесывали код так, чтобы ORDER BY был везде.



Экстремальная миграция на PostgreSQL: без остановки, потери и тестирования

Был интересный нюанс с составными транзакциями, которые меняли данные как в исходной базе Oracle, так и в экземпляре, перенесенном на PostgreSQL. Чтобы обе базы данных имели одинаковые значения, наша команда разработала специальный менеджер транзакций.

Он синхронно открывал и закрывал транзакции в обеих СУБД.

Если в таких транзакциях возникали ошибки, их приходилось устранять вручную.

И мы идем Миграция данных происходила постепенно – по заранее утвержденному списку из 50 таблиц.

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

То есть в определенный момент, после передачи данных, для таблицы устанавливался специальный флаг, согласно которому сервис Я.

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

У нас был такой план, вот он под спойлером: Контрольный список миграции Oracle-PostgreSQL Что нужно сделать разработчику:

  1. получить таблицы DDL в PostgreSQL;
  2. выделить интерфейс для класса DAO;
  3. создать класс DAO для работы с PostgreSQL;
  4. создать флаг для переключения работы с Oracle DAO на PostgreSQL DAO;
  5. писать тесты для нового DAO с покрытием 80% и более (использование механизма jOOQ очень помогает избежать ошибок в синтаксисе SQL-запросов).

    Чем больше, тем лучше;

  6. запустить миграцию на тестовом стенде;
  7. выполнить миграции на приемочном стенде, обеспечить прохождение приемочных испытаний;
  8. Выпуск изменений боевой обстановки.

Руководство для администратора базы данных:
  1. получить от разработчика DDL таблицы для переноса в базу данных PostgreSQL, создать таблицу и все связанные с ней сущности;
  2. Уточните у разработчика способ миграции — нужно ли изначально загружать старые данные и синхронизировать новые записи? Если данных много, то по каким критериям можно ограничить объем первоначальной загрузки;
  3. настроить SymmetricDS для синхронизации таблицы;
  4. в одной транзакции запустить первоначальную загрузку (если требуется) и синхронизацию новых записей;
  5. периодически проверять статус загрузки и синхронизации;
  6. непосредственно перед переключением служб на PostgreSQL переместите последовательности в целевой таблице, чтобы зарезервировать первичные ключи.

О чем не следует забывать ответственному за процесс лицу:
  1. убедиться, что продакшен поддерживает работу с PostgreSQL для конкретной таблицы;
  2. проверить, что первоначальная загрузка данных в продакшене успешно завершена и включена синхронизация новых записей;
  3. попросить администратора базы данных перенести последовательности в PostgreSQL;
  4. переключить один экземпляр сервиса на работу с PostgreSQL, убедиться в отсутствии ошибок в логах и логике сервиса;
  5. переключить оставшиеся экземпляры службы;
  6. После полного переключения попросите администратора базы данных переименовать перенесенные таблицы в Oracle. Внимательно следите за ошибками в системе — какая-то «забытая» сервисная логика все же может попытаться работать с Oracle.
В процессе миграции некоторые из 50 таблиц работали на Oracle, другие — на PostgreSQL. Вот тут-то и пригодился SymmetricDS, мигрировавший данные из Oracle в PostgreSQL и тем самым обеспечивший согласованность как логики с мигрировавшими таблицами, так и теми, которые еще работали по старой схеме.

После переноса данных в сервисе проверялась галочка «работа с PostgreSQL» для каждой конкретной таблицы и запросы переносились в новую СУБД.

Сначала коммутацию тестировали на стенде отладки, затем на стенде приемки.

Если все в порядке, переключитесь на производство и переименуйте таблицу в Oracle (чтобы понять, используется ли еще где-нибудь старая таблица).



Экстремальная миграция на PostgreSQL: без остановки, потери и тестирования

На схеме показана суть идеи: после создания дубликата базы данных на PostgreSQL в сервисе устанавливается новый флаг db, после чего все обращения переходят к новой базе данных.

Но самое сложное было выбрать правильный момент для переключения.

Фактически у нас было 3 варианта миграции, в зависимости от критичности и сложности таблицы:

  1. Перенос всей таблицы с последующим переключением .

    Этот вариант подходил в случаях, когда некоторые запросы могли быть потеряны (пользователя могут попросить нажать кнопку еще раз, или сработает автоматическое продолжение операции).

  2. На уровне дата-центра (ДЦ, всего их 2).

    Способ переноса критических таблиц, при котором сначала переносим первый дата-центр на PostgreSQL, а в процессе его включения отключаем второй (от Oracle).

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

    Простоев в работе сервисов не было.

  3. Использование метода «остаточного сжатия» .

    Оставляем 2 инстанса: Oracle для обработки запросов, опоздавших на переключение и новый PostgreSQL. Новые задачи обрабатывались в новой базе данных, а старые удалялись после выполнения в оставшемся Oracle. Так подвинулись очереди в базе данных — автоматические платежи, напоминания и т.д.

Не обошлось и без трудностей.

При первоначальном формировании схемы базы данных для PostgreSQL конвертер не выдал 100% готовую версию, чего в целом ожидали.

Мне пришлось вручную изменить некоторые типы столбцов, исправить последовательность и разбить схему на таблицы и индексы.

Однако последнее – для порядка и общей эстетики.

Чуть позже выяснилось, что SymmetricDS не синхронизирует таблицы размером более 150 ГБ.

Поэтому мне пришлось сесть за код и придумать обходной путь для таких случаев.

Однако и здесь не обошлось без серебряной пули.

SymmetricDS не переносила поля CLOB\BLOB, если они превышали общий размер таблицы, поэтому нам приходилось писать очереди миграции вручную.

Мы также сталкивались с весьма экзотическими случаями, когда миграция с Oracle на PostgreSQL приводила к резкому падению производительности.

Ничего не оставалось, как вручную анализировать каждый отдельный случай.

Например, для одной таблицы нам пришлось выделить поле CLOB в отдельную таблицу, переместить ее на SSD-диск и читать это поле только при необходимости.

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

Экстремальная миграция на PostgreSQL: без остановки, потери и тестирования

На схеме показано схематическое изображение новой таблицы в PostgreSQL с «отступом» между старыми и новыми данными в 1000 ключей.

То есть, если последний ключ в таблице был 100, то при передаче к этому значению добавлялось еще 1000, чтобы SymmetricDS могла свободно синхронизировать ключи 101, 102 и все остальные, не затирая новые данные.

Отделочная лента В течение запланированного квартала наша небольшая команда перенесла 80% таблиц на PostgreSQL. Остальные 20% — это большие таблицы (в среднем более 150 ГБ), включая комбинированную таблицу с большими полями CLOB\BLOB. Все это пришлось выполнять вручную в течение следующих 1,5 месяцев.

Тем не менее, комбинация SymmetricDS и Ora2Pg выполнила большую часть рутинной работы, как того требовали условия задачи.

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

Но Яндекс.

Деньги уже готовят десант к предстоящей конференции День ПГ'17 , который пройдет в Санкт-Петербурге.

Приходите на расширенный разговор и готовьте каверзные вопросы.

Однако предлагаю поднять самые актуальные темы прямо здесь, в комментариях.

Очень интересно прочитать о вашем опыте миграции и, возможно, о том, что мы упустили.

В Репозитории Яндекс.

Деньги вы найдете код для решений, описанных в статье:

  • Источники диспетчера транзакций
  • Код класса для проверки существования транзакции.

Теги: #платежные системы #postgresql #Разработка для электронной коммерции #oracle #миграция баз данных
Вместе с данным постом часто просматривают: