План миграции: ключевые этапы и оценка даунтайма
Перенос данных на новый сервер - задача, которая требует чёткой последовательности действий. Правильно выстроенный процесс сокращает время недоступности сервиса до 5–15 минут. Рабочий план миграции состоит из четырёх этапов.
Первый этап - подготовка исходного и целевого серверов. Вы синхронизируете окружения, создаёте резервные копии и уменьшаете TTL DNS-записей. Второй этап - синхронизация данных. Основной массив файлов переносится утилитой rsync, базы данных настраиваются на репликацию. Третий этап - переключение трафика. Вы изменяете DNS-записи или правила балансировщика и направляете пользователей на новую машину. Четвёртый этап - постмиграционная проверка и мониторинг.
Типичная длительность каждого этапа: подготовка занимает от 30 минут до нескольких часов в зависимости от объёма данных и сложности конфигурации. Первичная синхронизация файлов может длиться часы или даже сутки для терабайтных массивов. Финальная синхронизация и переключение трафика укладываются в 5–15 минут. Проверка после миграции требует минимум часа пристального наблюдения за логами и метриками.
Обязательный шаг, который нельзя пропускать - предварительное тестирование всей процедуры на стенде. Стенд должен максимально точно повторять продакшен-окружение. Если стенда нет, выделите время на создание его минимальной версии. Ошибка, обнаруженная на стенде, экономит часы аварийных работ на продакшене.
Это руководство дополняет общий план миграции серверов и фокусируется именно на переносе данных с минимальным простоем. Если вы ещё не провели аудит текущей инфраструктуры, начните с него.
Подготовка исходного и целевого серверов
Подготовительный этап определяет успех всей миграции. Различия в версиях операционной системы, библиотек или СУБД - самая частая причина сбоев после переключения трафика. Проверьте окружения до начала переноса данных.
Сравните версии ОС на исходном и целевом серверах. Выполните uname -a и cat /etc/os-release. Сверьте мажорные версии ядра и дистрибутива. Разница между CentOS 7 и Rocky Linux 9 критична для работы некоторых приложений. Проверьте версии интерпретаторов: php -v, python3 --version, node --version. Убедитесь, что на целевом сервере установлены те же или совместимые версии.
Установите необходимые пакеты. На целевом сервере должны присутствовать: rsync для синхронизации файлов, клиентские библиотеки для подключения к базам данных, веб-сервер той же версии. На исходном сервере дополнительных пакетов обычно не требуется - rsync уже установлен в большинстве дистрибутивов.
Настройте SSH-ключи для беспарольного доступа с исходного сервера на целевой. Сгенерируйте ключ командой ssh-keygen -t ed25519, скопируйте публичную часть через ssh-copy-id user@new-server-ip. Проверьте подключение: ssh user@new-server-ip 'hostname' должно отрабатывать без запроса пароля. Отсутствие беспарольного доступа сломает автоматизацию синхронизации.
За 24 часа до миграции уменьшите TTL DNS-записей до 300 секунд. Это критически важно. Стандартный TTL в 86400 секунд (сутки) означает, что после изменения A-записи часть пользователей будет попадать на старый сервер ещё 24 часа. TTL в 300 секунд сокращает окно неопределённости до 5 минут. Измените TTL в панели управления DNS-хостингом и дождитесь истечения предыдущего срока кеширования.
Создание резервной копии перед миграцией
Полный бэкап - страховка от любых нештатных ситуаций. Даже при идеально выполненной миграции резервная копия даёт уверенность в возможности отката. Создавайте бэкап непосредственно перед началом активных работ.
Для файловой системы используйте создание архива: tar -czpf /backup/full-backup-$(date +%Y%m%d).tar.gz --exclude=/proc --exclude=/sys --exclude=/dev --exclude=/tmp --exclude=/run --exclude=/mnt --exclude=/media /. Этот подход сохраняет права доступа, владельцев и временные метки. Альтернативный вариант - полная копия через rsync на отдельное хранилище: rsync -avz --delete / /mnt/backup-volume/.
Для баз данных создайте дампы. MySQL: mysqldump --all-databases --single-transaction --quick --lock-tables=false -u root -p > /backup/all-databases-$(date +%Y%m%d).sql. Флаг --single-transaction обеспечивает согласованное состояние для InnoDB-таблиц без длительных блокировок. PostgreSQL: pg_dumpall -U postgres -h localhost --clean --file=/backup/pg-all-$(date +%Y%m%d).sql. После создания дампа проверьте его целостность: для MySQL - grep -c 'CREATE TABLE' /backup/all-databases-*.sql должен вернуть ожидаемое количество таблиц. Для PostgreSQL - grep -c 'CREATE TABLE' /backup/pg-all-*.sql.
Храните резервную копию вне исходного и целевого серверов. Идеальный вариант - отдельное файловое хранилище или облачный бакет. Если миграция проходит между серверами одного дата-центра, скопируйте бэкап на третью машину.
Синхронизация файлов с помощью rsync
Rsync - основной инструмент переноса файловой системы между серверами. Утилита копирует только изменившиеся блоки данных, что позволяет выполнять инкрементальные проходы и сводить дельту к минимуму перед финальным переключением. Правильная стратегия синхронизации сокращает даунтайм до времени последнего прохода rsync плюс время переключения трафика.
Первый проход rsync переносит основную массу данных. Запустите команду: rsync -avz --progress --delete /var/www/ user@new-server-ip:/var/www/. Флаг -a (archive) сохраняет права, владельцев, симлинки и временные метки. -v включает подробный вывод. -z сжимает данные при передаче - полезно при миграции через интернет. --delete удаляет на целевом сервере файлы, которых уже нет на исходном. --progress показывает прогресс для каждого файла.
Для больших объёмов данных (сотни гигабайт и более) первый проход может занять часы. Запускайте его заранее, пока исходный сервер продолжает обслуживать пользователей. После завершения первого прохода выполните второй, инкрементальный: та же команда rsync передаст только файлы, изменившиеся с момента первого прохода. Разница во времени между первым и вторым проходом обычно составляет 10–30 минут для проектов среднего размера.
Исключите из синхронизации специальные файловые системы и временные директории. Добавьте флаги --exclude=/proc --exclude=/sys --exclude=/dev --exclude=/tmp --exclude=/run. Для веб-проектов исключите директории с кешем: --exclude=/var/www/html/cache. Открытые файлы (логи, базы данных при активной записи) rsync обрабатывает корректно - копирует состояние на момент чтения, но для баз данных синхронизация файлов не заменяет репликацию или дамп.
Финальная синхронизация перед переключением
Финальный проход rsync выполняется непосредственно перед переключением трафика. На этом этапе нужно остановить запись данных на исходном сервере. Для веб-приложений переведите сайт в режим обслуживания (maintenance mode) или переключите базу данных в режим read-only.
Остановите сервисы, которые пишут данные: веб-сервер можно не останавливать, но запретите запись на уровне приложения. Для MySQL выполните FLUSH TABLES WITH READ LOCK; - это запретит все изменения до снятия блокировки. Для PostgreSQL: ALTER DATABASE dbname SET default_transaction_read_only = on;.
Запустите финальный rsync: rsync -avz --delete --dry-run /var/www/ user@new-server-ip:/var/www/. Сначала выполните команду с флагом --dry-run, чтобы увидеть список файлов, которые будут синхронизированы. Убедитесь, что объём изменений соответствует ожиданиям - несколько изменившихся файлов, а не гигабайты данных. Затем выполните реальную синхронизацию без --dry-run. После завершения rsync целевой сервер содержит точную копию файловой системы исходного на момент остановки записи.
Миграция баз данных с репликацией
Репликация баз данных сокращает даунтайм до нескольких секунд - времени, необходимого для продвижения реплики до мастера. Подход работает для MySQL и PostgreSQL. Альтернативный метод - перенос дампа с остановкой записи - проще в настройке, но увеличивает время недоступности до минут или часов в зависимости от размера базы.
Выбор между репликацией и дампом зависит от допустимого времени простоя и объёма данных. База размером 100 ГБ восстанавливается из дампа 20–40 минут. Репликация сокращает этот интервал до 5–10 секунд на продвижение. Если ваш SLA допускает 15 минут простоя, метод с дампом приемлем. Если простой должен быть минимальным - настраивайте репликацию.
Настройка репликации MySQL
Настройка репликации MySQL начинается с исходного сервера. В файле /etc/mysql/my.cnf (или /etc/my.cnf) добавьте или измените параметры:
[mysqld]
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
binlog_do_db = your_database
bind-address = 0.0.0.0
Параметр server-id должен быть уникальным для каждого сервера в репликации. log_bin включает бинарный лог - основу репликации. binlog_do_db ограничивает репликацию конкретной базой данных. Перезапустите MySQL: systemctl restart mysql.
Создайте пользователя для репликации на исходном сервере:
CREATE USER 'replica_user'@'%' IDENTIFIED BY 'strong_password';
GRANT REPLICATION SLAVE ON *.* TO 'replica_user'@'%';
FLUSH PRIVILEGES;
Получите координаты бинарного лога: SHOW MASTER STATUS;. Запишите значения File и Position - они потребуются при настройке реплики.
На целевом сервере настройте my.cnf:
[mysqld]
server-id = 2
relay-log = /var/log/mysql/mysql-relay-bin.log
log_bin = /var/log/mysql/mysql-bin.log
read_only = ON
Импортируйте дамп с исходного сервера: mysql -u root -p < /backup/database-dump.sql. Затем настройте репликацию:
CHANGE MASTER TO
MASTER_HOST='source-server-ip',
MASTER_USER='replica_user',
MASTER_PASSWORD='strong_password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=12345;
START SLAVE;
Значения MASTER_LOG_FILE и MASTER_LOG_POS возьмите из вывода SHOW MASTER STATUS на исходном сервере. Проверьте состояние репликации: SHOW SLAVE STATUS\G. Поля Slave_IO_Running и Slave_SQL_Running должны показывать Yes. Параметр Seconds_Behind_Master показывает отставание реплики от мастера в секундах - перед переключением трафика дождитесь значения 0.
Настройка репликации PostgreSQL
Для PostgreSQL используется streaming replication. На исходном сервере измените postgresql.conf:
wal_level = replica
max_wal_senders = 3
wal_keep_size = 1024
listen_addresses = '*'
В файле pg_hba.conf добавьте правило для подключения реплики:
host replication replica_user new-server-ip/32 md5
Создайте пользователя для репликации: CREATE USER replica_user WITH REPLICATION ENCRYPTED PASSWORD 'strong_password';. Перезапустите PostgreSQL: systemctl restart postgresql.
На целевом сервере остановите PostgreSQL и очистите директорию данных: rm -rf /var/lib/postgresql/*/main/*. Выполните создание базовой копии: pg_basebackup -h source-server-ip -D /var/lib/postgresql/16/main -U replica_user -P -R. Флаг -R автоматически создаёт конфигурационные файлы для репликации. После завершения pg_basebackup запустите PostgreSQL на целевом сервере: systemctl start postgresql.
Проверьте состояние репликации на исходном сервере: SELECT client_addr, state, sync_state FROM pg_stat_replication;. Запись с state = 'streaming' подтверждает, что репликация работает. Отставание можно проверить запросом: SELECT pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS lag_bytes FROM pg_stat_replication;. Перед переключением дождитесь минимального значения lag_bytes.
Переключение трафика: DNS и балансировщики
Переключение трафика - самый ответственный момент миграции. Последовательность действий: сначала проверьте доступность сайта через новый IP, затем измените DNS-запись, затем остановите репликацию и продвиньте новый сервер до мастера.
Проверка через новый IP выполняется добавлением временной записи в локальный файл hosts на вашей рабочей машине: echo 'new-server-ip your-domain.com' >> /etc/hosts. Откройте сайт в браузере, проверьте основные функции. Убедитесь, что все страницы загружаются, формы отправляются, медиафайлы отображаются. После проверки удалите запись из hosts.
Измените A-запись домена на IP нового сервера в панели управления DNS. Благодаря уменьшенному TTL (300 секунд) изменение распространится в течение 5 минут. Для мгновенного переключения используйте балансировщик нагрузки (Nginx, HAProxy) или временный редирект на уровне веб-сервера: на старом сервере настройте проксирование всех запросов на новый IP. Это устраняет задержку DNS-кеширования для активных сессий.
После переключения трафика продвиньте реплику до мастера. Для MySQL: STOP SLAVE; RESET SLAVE ALL; и снимите режим read-only: SET GLOBAL read_only = OFF;. Для PostgreSQL: pg_ctl promote -D /var/lib/postgresql/16/main. С этого момента новый сервер принимает запросы на запись.
План отката: быстрое возвращение на старый сервер
План отката должен быть готов до начала переключения трафика. Скорость возврата на старый сервер определяет реальное время недоступности при проблемах. Алгоритм отката состоит из трёх шагов.
Первый шаг - обратное изменение DNS. Верните A-запись на IP старого сервера. Если использовался балансировщик или редирект, отключите их. Второй шаг - синхронизация данных обратно. Если на новом сервере успели появиться изменения (пользовательские данные, транзакции), их нужно перенести на старый сервер. Используйте rsync для файлов и дамп базы данных. Третий шаг - восстановление из бэкапа, если обратная синхронизация невозможна или данные повреждены. Именно поэтому полный бэкап перед миграцией обязателен.
Проверьте работоспособность старого сервера после отката: откройте сайт, выполните ключевые сценарии. Убедитесь, что данные консистентны. Только после этого сообщите команде о завершении отката.
Постмиграционная проверка и мониторинг
После переключения трафика начинается этап пристального наблюдения. Первые 15–30 минут критичны: в это время проявляется большинство проблем, не обнаруженных на этапе тестирования.
Сравните контрольные суммы критичных файлов между исходным и целевым серверами. Используйте md5sum или sha256sum для проверки конфигурационных файлов, загруженных пользователями данных, статических ресурсов. Команда diff -r /var/www/ /mnt/old-server/var/www/ покажет расхождения в файловых деревьях.
Проверьте целостность баз данных. Для MySQL: mysqlcheck -u root -p --all-databases проверит все таблицы на ошибки. Для PostgreSQL: pg_dump -U postgres dbname > /dev/null - успешное выполнение дампа подтверждает, что база читается без ошибок. Выполните функциональное тестирование веб-приложений: авторизация, создание и редактирование записей, загрузка файлов, поиск, интеграции с внешними сервисами.
Настройте мониторинг на новом сервере. Отслеживайте загрузку CPU, использование памяти, дисковый ввод-вывод, количество соединений с базой данных. Просматривайте логи веб-сервера и приложений на предмет ошибок: tail -f /var/log/nginx/error.log, tail -f /var/log/syslog. Особое внимание уделите ошибкам прав доступа (Permission denied) и проблемам с подключением к внешним сервисам.
Типичные ошибки и как их избежать
Практика показывает повторяющиеся ошибки при миграции данных. Знание этих ошибок до начала работ экономит часы восстановления.
Забыли уменьшить TTL DNS. Симптом: после изменения A-записи часть пользователей продолжает попадать на старый сервер в течение суток. Решение: всегда уменьшайте TTL до 300 секунд за 24 часа до миграции. Если забыли - настройте проксирование со старого сервера на новый до истечения кеша DNS.
Не остановили запись в БД перед финальным rsync. Симптом: после переключения часть данных отсутствует на новом сервере. Rsync копирует файлы баз данных в несогласованном состоянии, если СУБД продолжает запись. Решение: всегда переводите базу в read-only или останавливайте сервисы записи перед финальной синхронизацией. Используйте репликацию вместо rsync для переноса баз данных.
Не проверили совместимость версий ПО. Симптом: приложение выдаёт ошибки после запуска на новом сервере. PHP-скрипты падают с фатальными ошибками, Python-зависимости не устанавливаются. Решение: сверьте версии всех компонентов стека до миграции. Используйте контейнеризацию (Docker) для гарантии идентичности окружений.
Не настроили файрвол на новом сервере. Симптом: после переключения трафика сервис недоступен, хотя на сервере всё работает локально. Решение: проверьте правила iptables/nftables или файрвола облачного провайдера. Откройте порты 80, 443, порты баз данных, SSH. Проверьте доступность с внешнего IP до изменения DNS.
Начали миграцию без полного бэкапа. Симптом: при любой нештатной ситуации нет возможности восстановить данные. Решение: полный бэкап - первый шаг любой миграции. Храните его вне исходного и целевого серверов. Проверьте целостность бэкапа до начала активных работ.
Если вы планируете комплексную миграцию инфраструктуры, изучите типичные риски и скрытые сложности. Для проектов, связанных с переносом баз данных между разными СУБД, пригодится руководство по миграции баз данных. При необходимости облачной инфраструктуры для нового сервера рассмотрите облачные серверы Timeweb Cloud с гибким масштабированием ресурсов.