Как проверить перенос данных на новый сервер без ошибок: чек-лист из 5 шагов
Проверка переноса данных на новый сервер — это пять последовательных шагов: сверка контрольных сумм и объёмов файлов, валидация целостности баз данных и межтабличных связей, тест прав доступа и…

Почему важно проводить валидацию после миграции
После физического копирования байтов между серверами лежит скрытый пласт проверок. Утилиты вроде rsync или robocopy могут отчитаться об успешном завершении, но не умеют различать частично повреждённый сектор на диске-источнике, нарушенную транзакцию в PostgreSQL, несовпадающий collation в MySQL или устаревший токен для сервисного аккаунта. По данным отчёта Enterprise Strategy Group за 2025 год, у 62% компаний миграция между серверами сопровождалась хотя бы одним скрытым дефектом: от расхождения количества строк в таблицах до потери индексов, а полное восстановление занимало в среднем 11 часов.
Именно поэтому валидация после переноса — обязательный этап, а не опциональный. К ней предъявляют три требования:
По теме также можно посмотреть Краудфандинг и краудинвестинг: краудфандинг-площадки, краудинвестинг, краудлендинг для.
По теме также можно посмотреть ИИ и аналитика данных в банках: решения Mastercard для КР.
1. Воспроизводимость. Результат проверки одного и того же состояния должен совпадать независимо от администратора. Добиться этого можно фиксированными командами (sha256sum, pg_dump --schema-only, robocopy /MIR) и эталонными отчётами.
2. Сопоставимость источника и приёмника. Все сравнения выполняются между исходным и целевым сервером, а не «внутри нового сервера». Только так можно доказать, что данные не изменились в пути.
3. Документирование. Каждое действие оформляется отдельным артефактом: файл с контрольными суммами, лог проверки, скриншот результата SQL-запроса. Без артефактов валидация считается незавершённой.
Хорошая практика — отделять валидацию от самой миграции и проводить её на отдельной учётной записи с правами read-only на источник и read-write на приёмник. Это исключает случайную перезапись на источнике и даёт независимый аудитный след.
При планировании опираются на два показателя из непрерывности бизнеса:
- RPO (Recovery Point Objective) — допустимая потеря данных по времени. При RPO = 15 минут любая проверка должна уложиться в этот интервал, включая откат в случае несовпадения.
- RTO (Recovery Time Objective) — допустимое время простоя. Для production-систем редко превышает 1–4 часа, поэтому валидация занимает не больше 30% от RTO.
Если шаги валидации не укладываются в RPO/RTO, перенос разбивают на этапы или выносят в окно обслуживания с предварительным уведомлением пользователей.
Этап 1: Сверка контрольных сумм и объёма файлов
Первый шаг проверяет, что на уровне файловой системы приёмник получил ровно те же байты, что и источник. Для серверов на Linux применяют связку find + sha256sum + diff; для Windows — Get-FileHash + Compare-Object в PowerShell. SHA-256 предпочтительнее MD5: коллизии в MD5 к 2026 году легко генерируются за минуты на обычной рабочей станции.
Типичная последовательность на источнике:
cd /var/data
find. -type f -print0 | sort -z | xargs -0 sha256sum > /tmp/source.sha256На приёмнике:
cd /var/data
find. -type f -print0 | sort -z | xargs -0 sha256sum > /tmp/target.sha256
scp source:/tmp/source.sha256 /tmp/
diff -q /tmp/source.sha256 /tmp/target.sha256Если diff возвращает ненулевой код — списки файлов различаются. Дополнительно сверяют количество строк wc -l и совокупный размер du -sb. Расхождение больше 0,01% по объёму — повод прервать валидацию и повторить миграцию, не дожидаясь остальных шагов.
Под Windows аналогичная проверка идёт через PowerShell:
Get-ChildItem -Recurse | Get-FileHash -Algorithm SHA256 | Export-Csv hashes.csv
Compare-Object (Get-Content src.csv) (Get-Content dst.csv)Для больших объёмов (десятки терабайт) используют rsync -avh --checksum --dry-run — он сообщает только о файлах, у которых изменился размер или контрольная сумма, без реального копирования. Это ускоряет повторную проверку до десятков минут вместо часов.
Дополнительно сверяют временные метки: stat -c '%Y %n' на Linux или Get-ItemProperty LastWriteTime на Windows. Расхождение больше 1 секунды на уровне файла сигнализирует о неполной синхронизации или вмешательстве.
Этап 2: Проверка целостности баз данных и связей
После сверки файлов переходят к структурированным данным. Здесь сравнивают количество строк, контрольные суммы таблиц, состояние индексов, внешних ключей и ограничений (CHECK, UNIQUE, NOT NULL). Работа идёт на уровне СУБД, потому что часть данных может быть закодирована и не поддаваться побайтовой проверке.
Для PostgreSQL применяют встроенную функцию pg_checksums (включается для кластера) или считают хэши через hashtext() и md5():
SELECT count(*) FROM orders;
SELECT md5(string_agg(id::text, ',' ORDER BY id)) FROM orders;Эти же запросы выполняют на источнике и приёмнике под одной и той же ролью. Совпадение количества строк и агрегированного хэша даёт 99% гарантии целостности таблицы. Для таблиц больше 100 млн строк добавляют разбивку по партициям или диапазонам дат, чтобы избежать долгого агрегирования.
MySQL предлагает утилиту mysqlcheck с флагом --check --use-frm: она проверяет целостность таблиц по внутренним контрольным суммам движка InnoDB. На приёмнике запускают:
mysqlcheck -u root -p --check --all-databasesДополнительно сравнивают метаданные: information_schema.TABLES (DATA_LENGTH, INDEX_LENGTH, AUTO_INCREMENT) и information_schema.STATISTICS для индексов. Расхождение AUTO_INCREMENT чаще всего вызвано незавершённой репликацией.
MongoDB проверяют через db.collection.validate({full: true}) на ключевых коллекциях, а также через db.collection.stats() — размер, количество документов, размер индексов.
После успешной проверки таблиц переходят к межтабличным связям. Здесь возможны три дефекта:
1. Ссылочная целостность нарушена — внешний ключ orders.user_id → users.id ссылается на несуществующего пользователя. На production это невозможно (MySQL и PostgreSQL запрещают), но на staging БД с отключёнными FK может пройти. Проверяют SQL-скриптом:
SELECT o.id FROM orders o LEFT JOIN users u ON u.id = o.user_id WHERE u.id IS NULL;2. Дубликаты в уникальных индексах — перенесённые данные из двух систем сошлись в одну. Обнаруживается через SELECT field, count(*) FROM table GROUP BY field HAVING count(*) > 1.
3. Сломанные триггеры и представления — DDL-объекты могли не попасть в дамп. Сверяют системные каталоги: pg_trigger, mysql.proc, information_schema.VIEWS.
Все запросы и их результаты сохраняют в отдельный каталог validation/db/, а итог фиксируют в сводной таблице: таблица, источник строк, приёмник строк, источник хэша, приёмник хэша, расхождение, статус.
Этап 3: Тестирование прав доступа и конфигураций безопасности
Файлы и базы данных перенесены, но под старыми ACL, владельцами и сервисными учётками. Без проверки безопасности сервис либо не запустится (нет доступа на чтение), либо даст избыточные права (файлы конфигурации доступны группе world).
На Linux проверяют владельцев и права:
find /etc/app /var/app -not -user appuser -o -not -group appgroup
find /etc/app -perm -o+r # мировое чтение на чувствительные файлыЧувствительными считаются файлы с приватными ключами (.pem, .key), конфиги с паролями и сертификаты. Допустимый режим — 640 или 600, владелец — сервисный пользователь.
На Windows сравнение через icacls:
icacls C:\App\* /save acl.txt /t
icacls \\source\App\* /save src_acl.txt /t
fc /b acl.txt src_acl.txtРасхождения в ACE-записях, особенно в строках BUILTIN\Administrators или CREATOR OWNER, разбирают вручную.
Дальше проверяют конфигурации сервисов: nginx, Apache, systemd-unit, Windows Service. Сравнивают:
- путь к исполняемому файлу;
- переменные окружения (
EnvironmentFile,Environment=); - учётную запись запуска (
User=,logon_as); - сетевые порты и привязки;
- открытые файрволом правила (
iptables -L -n -v,netsh advfirewall firewall show rule).
Отдельно сверяют TLS-сертификаты. Частая ошибка — после миграции сертификаты остались на старом сервере, а новый использует самоподписанные. Проверяют через openssl x509 -in cert.pem -noout -subject -dates -issuer на источнике и приёмнике. Дата notAfter должна быть актуальной и совпадать между узлами.
Для сервисных аккаунтов (PostgreSQL → pg_hba.conf, приложение → API-ключ) проверяют:
- актуальность токена;
- наличие прав на новом сервере;
- совпадение
secrets-manager-ссылок, если используется Vault, AWS Secrets Manager или Azure Key Vault.
Без положительного результата этого шага переходить к функциональному тестированию нельзя: даже идеальные данные будут недоступны приложению.
Этап 4: Функциональное тестирование критических сервисов
Последний содержательный шаг проверяет, что мигрированные данные работают в реальных сценариях. Здесь применяют подход «снизу вверх»: сначала тестируют отдельные компоненты, затем интеграцию, затем end-to-end.
Начинают с проверки сетевой связности. С нового сервера вызывают:
ping -c 5 source.internal
traceroute db.internal
nc -zv api.internal 443
ss -tnp state establishedПинг должен укладываться в 50 мс внутри одного ЦОД и в 150 мс между регионами. Потеря пакетов — не больше 0,01%. Если тайм-ауты или Connection refused — возвращаются к Этапу 3 и проверяют правила firewall и маршрутизацию.
Дальше тестируют сервисы уровня приложения. Для веб-сервиса:
curl -fsS https://service.local/healthz
curl -fsS -H "Authorization: Bearer $TOKEN" https://service.local/api/v1/ordersВозвращённые коды должны быть 200 OK. Код 503 Service Unavailable сигнализирует о неполной инициализации (например, не подтянулся конфиг). Проверяют логи приложения: journalctl -u service-name --since "5 min ago" на systemd-серверах, Event Viewer на Windows.
Затем запускают интеграционные тесты, которые уже есть в проекте. Если таких тестов нет, составляют минимальный набор:
| Категория | Пример проверки | Допустимый результат |
|---|---|---|
| Чтение | GET /api/v1/customers/{id} | 200, поля совпадают с источником |
| Запись | POST /api/v1/orders | 201, запись появляется в БД приёмника |
| Авторизация | Запрос с истёкшим токеном | 401, без побочных эффектов |
| Очередь | Публикация задачи в RabbitMQ/Kafka | Сообщение доставлено и обработано |
| Поиск | Запрос в Elasticsearch/OpenSearch | 200, top-10 выдачи совпадают |
Все запросы подают как с production-токеном, так и с тестовым. Расхождение ответов между источником и приёмником — повод остановить миграцию и вернуться к Этапу 2.
Отдельно проверяют метрики производительности. Сравнение идёт на одинаковом железе, одинаковой нагрузке, одинаковом объёме данных. Допустимое отклонение по latency p95 — не больше 15% от источника. Если запросы на приёмнике выполняются на 30% дольше — высока вероятность, что индексы были созданы в неправильном порядке, не подключена оптимизация work_mem, либо СУБД не прогрела кэш.
После успешного функционального теста переключают DNS или балансировщик на новый сервер. Делают это в режиме canary: 5% трафика в течение 30 минут, 25% в течение часа, 100% — после подтверждения метрик.
Таблица проверки: чек-лист готовности инфраструктуры
Итоговый документ объединяет все этапы в одну таблицу. Заполняется ответственным за миграцию (чаще всего DevOps-инженером или SRE) и подписывается владельцем сервиса. Пустые или отрицательные ответы блокируют переключение трафика.
| # | Проверка | Метод | Критерий «готово» | Кто отвечает | |
|---|---|---|---|---|---|
| 1 | Контрольные суммы файлов совпадают | sha256sum + diff | 0 расхождений | DevOps | |
| 2 | Объём перенесённых данных | du -sb или `Get-ChildItem \ | Measure-Object` | Δ ≤ 0,01% | DevOps |
| 3 | Количество строк в таблицах | SELECT count(*) | Δ = 0 | DBA | |
| 4 | Хэш агрегата таблицы | md5(string_agg(...)) | строки источника = приёмника | DBA | |
| 5 | Ссылочная целостность FK | LEFT JOIN... WHERE NULL | 0 «висящих» строк | DBA | |
| 6 | Владельцы и права на файлах | stat, icacls | только разрешённые owner/group | Security | |
| 7 | Режимы приватных файлов | find... -perm -600 | 0 файлов с o+r | Security | |
| 8 | TLS-сертификаты валидны | openssl x509 -checkend 2592000 | > 30 дней до истечения | Security | |
| 9 | Сервисные учётки работают | проверка токенов, ACL | 0 ошибок 401/403 | DevOps | |
| 10 | Сетевая связность | ping, nc -zv | 0 потерь, latency p95 ≤ 150 мс | Network | |
| 11 | Endpoint /healthz отвечает | curl -fsS | 200 OK | DevOps | |
| 12 | Интеграционные тесты зелёные | CI-пайплайн | 100% pass | QA | |
| 13 | Latency p95 запросов | нагрузочный тест k6/wrk | Δ ≤ 15% к источнику | QA | |
| 14 | Бэкап приёмника настроен | Veeam/Bacula/rsnapshot | расписание активно | Backup-admin | |
| 15 | Мониторинг подключён | Zabbix/Prometheus | метрики поступают ≥ 5 мин | SRE | |
| 16 | Журнал аудита ведётся | syslog/journal forwarding | события пишутся | Security | |
| 17 | План отката готов | runbook + снапшот | RTO ≤ 30 мин | DevOps | |
| 18 | Уведомление пользователей | письмо/статус-страница | отправлено за 24 ч | Service Owner |
Таблица не покрывает всех особенностей конкретного стека, поэтому для своих систем добавляют дополнительные строки: например, проверку репликации в Patroni, состояние кластера etcd, версии helm-чартов в Kubernetes.
Когда валидация показывает расхождения и что делать
Несовпадения выявляются на любом из этапов. К этому нужно быть готовым заранее: без плана отката миграция превращается в инцидент. Опираются на сценарии, которые встречаются чаще всего.
Сценарий 1: расходятся контрольные суммы. Останавливают синхронизацию, фиксируют список отличающихся файлов и сравнивают по дате. Причины: прерванная передача, повреждение диска, вмешательство антивируса на Windows. Решение — повторный rsync только по проблемным файлам (rsync --files-from=missing.txt), затем повтор шага 1.
Сценарий 2: количество строк в таблице меньше. Причина — незавершённая транзакция в источнике на момент снимка или нарушение порядка применения WAL. Решение — восстановить БД из последнего проверенного бэкапа, повторить инкрементальную репликацию, повторно валидировать шаг 2.
Сценарий 3: внешние ключи нарушены. Это признак того, что в staging-режиме были отключены FK, либо часть таблиц перенесли позже остальных. Решение — выполнить перенос таблиц в порядке родитель → потомок, включить FK перед финальной сверкой.
Сценарий 4: права доступа не совпадают. Причины — разные ACL-схемы между серверами, миграция через root без сохранения xattr на Linux или Owner на Windows. Решение — повторное копирование с сохранением атрибутов: rsync -aX на Linux, robocopy /COPYALL на Windows. После повтора перепроверить шаг 3.
Сценарий 5: TLS-сертификаты просрочены или отсутствуют. Причина — на источнике были wildcard-сертификаты от внутреннего CA, не скопированные автоматически. Решение — выпустить новый сертификат на новом сервере или скопировать PKI-цепочку из защищённого хранилища.
Сценарий 6: интеграционные тесты красные. Здесь два направления: либо источник отдаёт «правильные» ответы за счёт старых костылей, либо приёмник работает «правильнее», и тесты устарели. Решение — сравнить трассировку запроса, понять, какая часть отличается, и сознательно выбрать, какую систему выровнять под какую.
Сценарий 7: нагрузочный тест просаживается на 30–50%. Причины: не активирован huge pages, отличается параметр max_connections, нет прогрева буферного пула. Решение — выполнить pg_prewarm или эквивалент, проверить конфигурацию СУБД, повторить прогон после прогрева.
Сценарий 8: раздел про логи и аудит не наполняется. Причина — journal/syslog не перенаправлен на центральный коллектор. Решение — настроить rsyslog/fluent-bit/Promtail, повторить запуск сервиса, дождаться поступления событий в SIEM (Splunk, ELK, MaxPatrol SIEM).
Любое расхождение фиксируется в журнале инцидентов с указанием причины, времени обнаружения, ответственного и корректирующих действий. Без такой записи валидация не считается закрытой.
Чек-лист перед переключением трафика
Перед переключением DNS или балансировщика на новый сервер прогоняют финальный чек-лист. Он собран из пунктов, пропуск которых в прошлом приводил к откату в production.
1. Все пункты таблицы готовности — «готово». Подтверждено подписью владельца сервиса.
2. Резервная копия приёмника создана. Полный снапшот диска или pg_basebackup последней версии, проверено восстановление на отдельной площадке.
3. Runbook отката написан и протестирован. Пошаговая инструкция: остановить сервис → переключить балансировщик на источник → восстановить DNS. Каждый шаг имеет ожидаемое время.
4. RPO и RTO пересмотрены. Если валидация заняла больше времени, чем запас в RTO, перенос откладывается до следующего окна обслуживания.
5. Изменения закоммичены и протегированы. В Git — релиз-тег release-2026-MM-DD, в artifact-registry — образ с новой версией конфигурации.
6. Пользователи уведомлены. Статус-страница (statuspage.io или собственная) показывает плановое окно, в почтовой рассылке — короткий анонс.
7. Дежурная смена подтверждена. В первые 2 часа после переключения на линии остаётся ответственный инженер и владелец сервиса.
8. Мониторинг и алерты активны. Проверены пороги: CPU, память, диск, ошибки приложения, ошибки БД, длина очередей.
9. Канареечное переключение проведено. 5% трафика в течение 30 минут без роста ошибок.
10. Ретроспектива назначена. Встреча по итогам миграции через 7 дней, чтобы зафиксировать уроки и обновить runbook.
Если хотя бы один пункт не выполнен, переключение переносится. Лучше сдвинуть срок, чем откатываться посреди ночи.