MAATRIX / Блог / Как проверить, что миграция прошла успешно: чек-лист

Как проверить, что миграция прошла успешно: чек-лист

MAATRIX

Миграция закончена: DNS переключён, сайт открывается, все довольны. И именно в этот момент чаще всего теряют данные, платежи или фоновые задачи — потому что «открывается» не значит «работает». Ниже — чек-лист, по которому можно пройти после любого переезда: сервера, сайта, базы данных, приложения. Не теория, а конкретные команды и что именно смотреть на каждом шаге.

Базовая доступность — не просто «открылось»

Первая проверка почти всегда одна: открыть сайт в браузере и убедиться, что он загрузился. Этого мало. Браузер может показать закэшированную версию, страницу ошибки с кодом 200 (так делают многие CMS и SPA — рендерят «красивую» 404 или 500 с HTTP-статусом 200), или контент со старого сервера через CDN, который ещё не обновил кеш.

Проверяйте не факт загрузки, а конкретный ответ:

curl -I https://example.com

Смотрите на:

  • код состояния — именно тот, что ожидается для этого URL (200 для главной, 301/302 для редиректов, 404 для несуществующих страниц — если сайт после миграции отдаёт 200 там, где раньше был 404, что-то настроено не так);
  • заголовок Server и любые кастомные заголовки, которые вы добавляли на новом сервере — их отсутствие означает, что запрос ушёл не туда, куда вы думаете;
  • заголовок X-Cache или аналогичный, если используется CDN — понять, отдаётся ли ответ из кеша или действительно с нового бэкенда.

Дальше — сверить контент, а не только код:

curl -s https://example.com | grep -o '<title>.*</title>'
diff <(curl -s https://example.com/) <(curl -s https://old-server-ip/ -H "Host: example.com")

Второй diff полезен, пока старый сервер ещё жив: вы буквально видите разницу в HTML между старой и новой версией. Если diff большой и необъяснимый — не переключение DNS виновато, а что-то не так с самой миграцией контента.

Отдельно проверьте с чистого клиента — без локального DNS-кеша и без cookie:

curl -I --resolve example.com:443:NEW_IP https://example.com

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

Функциональная проверка критичных путей

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

Составьте список из 3-7 сценариев, которые реально приносят деньги или критичны для сервиса, и пройдите каждый вручную хотя бы один раз после переезда:

  • регистрация нового пользователя и вход в личный кабинет (проверяет сессии, куки, домен куки — частая проблема при смене домена/поддомена сервера);
  • оформление заказа до экрана оплаты (проверяет корзину, расчёт доставки, интеграцию с платёжным шлюзом);
  • реальный тестовый платёж на минимальную сумму, если это возможно — не просто открытие формы оплаты, а прохождение до конца с подтверждением от платёжной системы;
  • отправка формы обратной связи или заявки — дошло ли письмо/уведомление, не залипло ли в очереди;
  • загрузка файла пользователем (аватар, документ, фото товара) — записался ли файл туда, где его ожидает найти сервер (частая ошибка: путь к хранилищу захардкожен на старый сервер);
  • поиск по сайту, если он использует отдельный индекс (Elasticsearch, Sphinx, встроенный поиск CMS) — индекс на новом сервере может быть пустым или не обновляться.

Каждый пункт — это конкретное действие мышью и клавиатурой, а не «эндпоинт отвечает 200». API может быть здоров и одновременно бизнес-логика за ним — сломана: например, платёжный шлюз принимает запрос, но ключ указывает на тестовый режим, и деньги реально не списываются, хотя пользователь видит «Оплачено».

Если есть автотесты (Selenium, Playwright, Cypress) — прогоните их против нового адреса. Если нет — ручной проход по сценариям занимает не больше 20-30 минут и экономит часы разбирательств с недовольными пользователями.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS

Целостность данных — сверка, а не доверие

Самая опасная иллюзия при миграции — «раз скрипт переноса отработал без ошибок, данные перенеслись полностью». Скрипт может отработать без ошибок и при этом перенести 99,7% строк — например, из-за обрыва соединения на последней пачке или лимита по таймауту, который тихо прервал INSERT пачками.

Пока старый сервер ещё не выключен, сравните количество записей в ключевых таблицах на старом и новом сервере:

-- на старом сервере
SELECT COUNT(*) FROM users;
SELECT COUNT(*) FROM orders;
SELECT COUNT(*) FROM orders WHERE created_at > NOW() - INTERVAL 1 DAY;

-- то же самое на новом

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

Для больших таблиц точный COUNT(*) может быть медленным — ориентируйтесь на порядок величины через системные представления (information_schema.tables в MySQL, pg_stat_user_tables в PostgreSQL), а точное сравнение делайте по контрольной сумме диапазона, а не по всей таблице разом:

SELECT MD5(GROUP_CONCAT(id, updated_at ORDER BY id)) FROM orders WHERE id BETWEEN 1 AND 100000;

Для файлов, загруженных пользователями (аватары, вложения, товарные фото), сравните не количество, а контрольные суммы — имя файла может совпадать при разном содержимом, если копирование где-то оборвалось:

find /var/uploads -type f -exec sha256sum {} \; | sort > new-checksums.txt
# то же самое на старом сервере в old-checksums.txt
diff old-checksums.txt new-checksums.txt

Для больших объёмов удобнее rsync --checksum --dry-run — он покажет список отличающихся файлов без реального копирования:

rsync -avzn --checksum old-server:/var/uploads/ /var/uploads/

Пустой вывод — все файлы идентичны. Непустой — список того, что нужно перекопировать вручную, прежде чем выключать старый сервер.

Проверка интеграций — протестировано, а не «должно работать»

Внешние сервисы — платёжные шлюзы, почтовые API, вебхуки от курьерских служб, интеграции с CRM — обычно настроены по IP или домену, и после миграции указывают либо в никуда, либо всё ещё на старый сервер.

Пройдите по списку всех внешних интеграций и для каждой явно проверьте:

  • Исходящие вебхуки (ваш сервер → внешний сервис): убедитесь, что во внешней панели (платёжный шлюз, CRM, служба доставки) URL вебхука указывает на новый адрес, а не остался старым по инерции;
  • Входящие вебхуки (внешний сервис → ваш сервер): отправьте тестовое событие через панель сервиса (у большинства платёжных систем и CRM есть кнопка «отправить тестовый вебхук») и проверьте в логах нового сервера, что событие дошло и обработалось;
  • API-ключи и allowlist по IP: если внешний сервис ограничивает доступ по IP-адресу отправителя, новый сервер должен быть добавлен в этот allowlist до переключения трафика, иначе запросы будут молча отклоняться с 403;
  • SMTP/почтовые интеграции: отправьте реальное письмо через форму сайта и проверьте, что оно дошло, а не зависло в очереди — новый сервер может быть заблокирован провайдером почты из-за отсутствия репутации у нового IP;
  • Вебхуки платежей: платёж может пройти на стороне платёжной системы, но уведомление об успешной оплате («callback») — не дойти до нового сервера, если URL callback вручную не обновлён в личном кабинете эквайринга. Это самый частый и самый дорогой по последствиям пропуск в чек-листе.

Проверка каждого пункта — это реальный тестовый запрос с подтверждением результата в логах, а не чтение документации о том, что «интеграция должна работать одинаково». История вебхуков в панели платёжного шлюза обычно показывает статус доставки и код ответа — если там 4xx или 5xx, проблема на вашей стороне, даже если сайт в остальном работает нормально.

Фоновые процессы — cron реально выполнился

Cron-задачи — самое незаметное место, где миграция ломается тихо: расписание настроено, crontab -l показывает нужные строки, а по факту задача не отработала ни разу, потому что путь к скрипту в crontab указывает на несуществующую на новом сервере директорию, или переменные окружения из .bashrc не подхватываются в неинтерактивной cron-сессии.

Не полагайтесь на то, что раз задача прописана в crontab — значит, она выполняется. Дождитесь первого ожидаемого запуска и проверьте логи:

grep CRON /var/log/syslog | tail -50
# или на системах с journald
journalctl -u cron --since "1 hour ago"

Отдельно проверьте лог самой задачи, если она пишет в файл:

tail -n 50 /var/log/myapp/backup.log
ls -la /var/backups/ | tail -5   # появился ли новый файл с ожидаемым временем

Если задача критична (бэкапы, email-рассылки, обработка очередей), не ждите пассивно первого запуска — настройте мониторинг доходимости через healthchecks.io или аналог: cron-задача при успешном завершении делает curl на уникальный URL, и алерт приходит именно в момент, когда пинг не пришёл, а не через неделю, когда обнаружится, что бэкапов не было (мониторинг cron-задач через healthchecks.io). Это особенно важно сразу после миграции — на старом сервере проверка не стояла, потому что «оно и так всегда работало», а на новом окружении гарантий пока нет.

Проверьте также системные таймеры, если используются вместо classic cron (systemctl list-timers), и часовой пояс сервера — миграция в другую страну нередко меняет TZ по умолчанию, и задачи, привязанные к времени суток, начинают выполняться на несколько часов раньше или позже.

Производительность — не хуже, чем было

Миграция редко ставит целью «то же самое, но на новом железе» — обычно ожидается прирост или как минимум паритет. Но паритет не гарантирован автоматически: на старом сервере годами копился прогретый кеш (opcache, кеш ORM-запросов, файловый кеш веб-сервера), настроенный swap, подобранные параметры буферов базы данных — и всё это на новом сервере снова с нуля.

Сравните время отклика ключевых страниц до отключения старого сервера, пока есть с чем сравнивать:

curl -o /dev/null -s -w "connect: %{time_connect}s, ttfb: %{time_starttransfer}s, total: %{time_total}s\n" https://example.com/

Для более полной картины под нагрузкой — короткий прогон ab или wrk на некритичный эндпоинт (не на боевую форму оформления заказа, чтобы не насоздавать тестовых заказов):

wrk -t4 -c50 -d30s https://example.com/catalog

Ориентируйтесь не на абсолютные цифры (они зависят от канала, географии клиента и момента замера — не воспринимайте конкретные миллисекунды как эталон), а на сравнение «до» и «после» в одинаковых условиях. Частые причины замедления: не прогрет opcache/кеш приложения после деплоя, не настроен innodb_buffer_pool_size (по умолчанию маленький, рассчитан не на боевую нагрузку), не включено сжатие gzip/brotli, диск медленнее (сетевой vs локальный NVMe).

Отдельно проверьте, что кеширующие слои реально работают, а не просто настроены: если использовался Redis/Memcached — убедитесь, что приложение подключается именно к новому инстансу, а не пытается достучаться до старого IP и потому тихо работает без кеша, что не вызывает ошибок, но сильно замедляет отклик.

Мониторинг и алерты — на новой инфраструктуре, до отключения старой

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

Минимальный набор для проверки:

  • аптайм-мониторинг (Uptime Kuma, внешний сервис) указывает на новый адрес и реально присылает тестовый алерт при остановке сервиса — проверьте, остановив сервис на минуту в тестовом окне (настройка мониторинга доступности сайта);
  • мониторинг ресурсов (диск, память, CPU) развёрнут на новом сервере с самого начала, а не «поставим через неделю, когда осядет» — именно в первую неделю нагрузка непредсказуема;
  • пороги алертов пересчитаны под новое железо — если новый сервер сильнее старого, старые пороги по CPU/RAM могут быть избыточно чувствительны или, наоборот, слишком мягкими;
  • канал доставки алертов (Telegram, email, Slack) протестирован именно с нового сервера — не предполагайте, что раз конфиг скопирован, токен бота и webhook URL по-прежнему валидны.

Практический совет, который экономит нервы: не отключайте старый сервер сразу после переезда. Держите его в режиме ожидания хотя бы 1-2 недели — выключенным для внешнего трафика (снят из DNS, остановлены платные внешние интеграции), но включённым и доступным по SSH. Это даёт три вещи: возможность быстро сравнить данные, если через несколько дней обнаружится расхождение; возможность мгновенного отката, если на новом сервере вылезет проблема, не пойманная в первый день проверки; и время скачать финальный дамп базы и файлов на случай, если что-то было упущено в первой сверке. Стоимость лишней недели аренды несопоставима со стоимостью восстановления данных, которые оказались утеряны, потому что старый сервер уже стёрт. Если нужен ориентир, в каком режиме держать резервный сервер — горячем или холодном — и сколько это стоит, это отдельный вопрос с своими компромиссами (резервный сервер: горячий или холодный режим).

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Сколько времени держать старый сервер после миграции?

Минимум неделю, лучше две — этого хватает, чтобы поймать расхождения, которые не видны в первый день (недельные cron-задачи, отчёты, обращения пользователей к редко используемым функциям).

Можно ли автоматизировать весь этот чек-лист?

Частично — доступность, коды ответов и контрольные суммы файлов легко завернуть в скрипт и гонять по расписанию. Функциональные сценарии (оформление заказа, вход в кабинет) надёжнее проверять руками хотя бы один раз, автотесты под них стоит писать заранее, а не в спешке сразу после переезда.

Что делать, если после проверки нашлась пропажа данных, а старый сервер уже выключен?

Если сервер не удалён физически (просто остановлен) — поднимите его снова, снимите свежий дамп недостающих таблиц и файлов, перенесите точечно. Поэтому пункт «не выключать сразу» в чек-листе — не перестраховка, а рабочая страховка.

Как проверить целостность данных, если таблицы огромные и полный COUNT(*) выполняется долго?

Сравнивайте по диапазонам с контрольной суммой (MD5(GROUP_CONCAT(...)) по батчам ID) вместо полного прохода, и ориентируйтесь на статистику из information_schema/pg_stat_user_tables для быстрой прикидки порядка величины.

Нужно ли тестировать реальный платёж на боевую сумму?

Минимальную сумму с последующим возвратом — да, стоит один раз пройти. Тестового режима платёжного шлюза недостаточно: он проверяет код интеграции, но не проверяет, что боевые ключи и callback-URL реально настроены на продакшн-окружение нового сервера.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →