Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Откат миграции данных: возврат к прежнему состоянию

Откат миграции данных: как вернуть прежнее состояние и где точка невозврата

Откат миграции данных: отличие от отката схемы, сохранение старой структуры, обратный перенос, восстановление из копии, точка невозврата и подготовка плана.

Прямой ответ

Откат миграции данных сложнее отката схемы. Изменение структуры отменяется обратной командой, а перенос значений требует либо сохранённой старой структуры, либо восстановления из копии.

Различие вариантов отката:

Ситуация Способ отката Время
Старая структура сохранена, чтение не переключено Прекращение записи в новую Секунды
Старая структура сохранена, чтение переключено Возврат чтения на старую Минуты
Старая структура удалена, есть двойная запись Обратный перенос Часы
Старая структура удалена, двойной записи нет Восстановление из копии Часы, потеря данных после копии

Ключевое правило — старая структура и запись в неё сохраняются до подтверждения корректности. Пока это условие выполняется, откат сводится к изменению конфигурации; о фазах — в статье про двойную запись.

Точка невозврата наступает при удалении старой структуры либо прекращении записи в неё. После этого новое хранилище содержит данные, которых нет в старом, и возврат требует обратного переноса.

Обратный перенос — не зеркальная операция. Три причины:

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

2. Значения, изменённые после переключения, существуют только в новом хранилище. Возврат без переноса этих изменений теряет данные.

3. Преобразование может быть необратимым. Разделение строки адреса на компоненты обратимо, а вычисление агрегата из деталей — нет.

Восстановление из копии — последний вариант:

1. Определить момент до начала миграции.
2. Восстановить базу на этот момент.
3. Перенести изменения, внесённые после восстановления.

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

Откат схемы выполняется инструментом миграций, если обратная операция определена:

def downgrade() -> None:
    op.drop_column("orders", "currency")

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

Что делает откат невозможным

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

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

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

Нарушение согласованности резервной копии. Копия, снятая до завершения переноса, не отражает изменения, внесённые после. Откат к такой копии теряет данные, созданные в промежуточный период.

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

Практический критерий: откат возможен, пока исходная структура существует и согласована с новой. Момент, когда это перестаёт быть правдой, — точка невозврата, и она фиксируется в плане явно.

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

Практика: подготовка к откату

1. Пишите план отката до начала миграции. Процедура, составленная в момент проблемы, выполняется медленно и с ошибками.

2. Сохраняйте старую структуру до подтверждения. Удаление до проверки лишает быстрого отката.

3. Продолжайте запись в старое хранилище. Двойная запись сохраняет возможность возврата чтения без потери данных.

4. Фиксируйте точку невозврата в плане. Момент, после которого откат требует переноса, определяется заранее и согласуется.

5. Проверяйте откат на стенде. Возврат, который не проверялся, в момент инцидента выполняется впервые.

6. Делайте резервную копию перед миграцией. Точка восстановления нужна для варианта с восстановлением из копии; о стратегиях — в статье про резервное копирование.

7. Определяйте критерии отката заранее. Условия, при которых выполняется возврат, формулируются до начала, а не обсуждаются в момент проблемы.

8. Ведите журнал миграции. Время начала, объём и выполненные фазы нужны для выбора способа отката; о процессе — в статье про миграцию данных.

Рекомендации:

  1. Не считайте откат схемы откатом данных. Обратная миграция возвращает структуру, но не значения.
  2. Учитывайте изменения после переключения. Данные, созданные в новом хранилище, при откате теряются, если не переносятся.
  3. Различайте полный и частичный откат. Возврат отдельной таблицы проще возврата всей миграции.
  4. Проверяйте необратимость преобразования до начала. Если обратное преобразование невозможно, план отката строится на копии.
  5. Согласуйте допустимую потерю данных. При восстановлении из копии теряются изменения после точки восстановления, и это принимается решением.

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

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

  1. Диагностика. Ошибка затрагивала 40 тысяч записей, созданных до определённой даты. Значение в новой колонке было неверным, а исходные данные для пересчёта удалены вместе со старой колонкой.
  2. Причина. Старая структура удалена по расписанию, а проверка исторических записей ограничилась выборкой недавних. План отката предполагал возврат чтения, но возвращать было некуда.
  3. Действия. (а) Восстановили базу из архива на момент до удаления колонки в отдельном экземпляре; (б) извлекли исходные значения для затронутых записей; (в) пересчитали значения в продуктивной базе по извлечённым данным; (г) изменили правило: удаление старой структуры выполняется после проверки исторических записей по всему диапазону дат; (д) добавили сверку по сегментам с разделением по периодам создания.
  4. Результат. Значения восстановлены, а процедура удаления старой структуры дополнена проверкой исторических данных.

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

FAQ

Чем откат миграции данных отличается от отката схемы? Откат схемы отменяет изменение структуры обратной командой. Откат данных требует сохранённой старой структуры либо восстановления из копии.

Где точка невозврата? В момент удаления старой структуры либо прекращения записи в неё. После этого возврат требует переноса данных.

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

Как выбрать способ отката? По состоянию: сохранена ли старая структура, продолжается ли запись в неё, есть ли резервная копия на нужный момент.

Источники: PostgreSQL docs (WAL-архивирование и PITR), Alembic docs, Martin Fowler — ссылки в шапке.