Как проверить перенос данных на новый сервер без ошибок: чек-лист из 5 шагов
Проверка переноса данных на новый сервер — это пять последовательных шагов: сверка контрольных сумм и объёмов файлов, валидация целостности баз данных и межтабличных связей, тест прав доступа и…
Почему важно проводить валидацию после миграции
После физического копирования байтов между серверами лежит скрытый пласт проверок. Утилиты вроде `rsync` или `robocopy` могут отчитаться об успешном завершении, но не умеют различать частично повреждённый сектор на диске-источнике, нарушенную транзакцию в PostgreSQL, несовпадающий collation в MySQL или устаревший токен для сервисного аккаунта. По данным отчёта Enterprise Strategy Group за 2025 год, у 62% компаний миграция между серверами сопровождалась хотя бы одним скрытым дефектом: от расхождения количества строк в таблицах до потери индексов, а полное восстановление занимало в среднем 11 часов.
Именно поэтому валидация после переноса — обязательный этап, а не опциональный. К ней предъявляют три требования:
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% — после подтверждения метрик.
| # | Проверка | Метод | Критерий «готово» | Кто отвечает | |
|---|---|---|---|---|---|
| 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 |
Когда валидация показывает расхождения и что делать
Несовпадения выявляются на любом из этапов. К этому нужно быть готовым заранее: без плана отката миграция превращается в инцидент. Опираются на сценарии, которые встречаются чаще всего.
Сценарий 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).
Любое расхождение фиксируется в журнале инцидентов с указанием причины, времени обнаружения, ответственного и корректирующих действий. Без такой записи валидация не считается закрытой.
Проверка первоисточников
Где сверить правила и документы
Ссылки помогают быстро перейти от советов в статье к официальным реестрам, правилам или справочным сервисам. Перед оплатой или претензией сохраняйте дату проверки.
