服务器数据迁移

芸殇
2026-10-31 / 0 评论 / 1 阅读 / 正在检测是否收录...

服务器迁移实战:从环境盘点到数据校验与业务切换

服务器迁移不仅是复制网站目录。数据库、运行库、服务启动配置、定时任务、证书以及外部访问地址,都可能影响迁移后的业务。

本文以 Linux、Nginx、PHP、MySQL 和 Supervisor 部署的业务为例,介绍允许停机时的一套迁移流程。Docker、跨系统或跨架构迁移需要调整具体方法。

本文所有 IP、域名、用户名和路径均为示例,不对应真实部署。192.0.2.10、198.51.100.20 是文档示例 IP,example.com 是示例域名,不能直接用于真实连接。不要在公开文章中放入真实凭据、内网拓扑、数据库配置或完整系统备份。

一、先明确迁移边界

开始前,至少确认:

  • 旧、新服务器的系统版本、CPU 架构、磁盘空间与内存。
  • 需要迁移的应用、数据库、上传文件和后台服务。
  • 是否允许停机,以及新服务器是否存在需要保留的数据。
  • 域名、CDN、对象存储、邮件服务和第三方 IP 白名单。
  • SSH 登录方式、操作权限和回退要求。

“迁移全部业务”不等于把旧系统根目录覆盖到新系统。新服务器的网络、SSH、磁盘挂载、主机身份和云厂商代理通常应保留自身配置。

本文采用“停机备份 → 传输恢复 → 核对数据 → 验证业务 → 切换入口”的流程。低停机迁移则需要数据库复制、增量同步和更严格的写入切换设计。

二、配置专用 SSH 密钥

在自己的管理电脑上生成专用密钥,按提示设置私钥口令:

ssh-keygen -t ed25519 -f ~/.ssh/migration_ed25519 -C migration-example

通过服务器控制台或现有可信连接,把 .pub 公钥的一整行加入两台服务器对应用户的 ~/.ssh/authorized_keys。不要把私钥上传到服务器。

目标用户的 SSH 目录权限应为:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

测试登录:

ssh -i ~/.ssh/migration_ed25519 deploy@192.0.2.10
ssh -i ~/.ssh/migration_ed25519 deploy@198.51.100.20

首次连接时,通过云控制台等可信渠道核对 SSH 主机指纹。不要为了省事全局关闭主机密钥检查。下文涉及系统目录的命令,应使用 sudo 或经过授权的管理员会话执行。

三、只读盘点旧服务器

先看系统、资源和服务:

cat /etc/os-release
uname -m
df -hT
free -h
lsblk
systemctl list-units --type=service --state=running --no-pager
ss -lntup
crontab -l

再看软件版本:

nginx -v
php -v
mysql --version
command -v docker
command -v supervisorctl

不能只看当前正在运行的服务,还要检查:

  • systemd 和旧式 init 启动脚本。
  • Supervisor 配置及其托管程序。
  • /etc/cron.d、各业务用户的 crontab 和 systemd timers。
  • 网站根目录、附件目录、软链接目标和外部挂载。
  • MySQL 实际数据目录及配置文件。
  • Nginx 虚拟主机、重写规则、证书和反向代理目标。
  • FTP 账户数据库、TLS 证书及被动端口设置。
  • 应用配置中的硬编码地址、数据库账号和外部依赖。

宝塔环境的软件可能位于 /www/server,网站可能位于 /www/wwwroot;其他环境应以实际配置为准。不要把包含密码的配置输出到公开日志或博客。

最终整理出一份私有迁移清单,写清每个服务的文件、配置、依赖、启动方式和验收方式。

四、选择迁移方法

场景通常采用的方法
同系统、同架构、相同软件版本选择性复制应用环境,验证动态依赖
系统、架构或数据库版本不同在新服务器安装目标环境,通过受支持的导出导入迁移
Docker Compose迁移 Compose、配置和持久化数据,单独设计数据库一致性备份
数据量大、停机要求短预同步文件、数据库复制或增量备份,最终暂停写入后切换

即使系统名称相同,动态库版本和软件编译参数也可能不同。复制可执行文件后,需要检查依赖并执行实际功能测试。

MySQL 数据目录不能随意跨版本复制。使用物理备份前,要核对数据库版本、存储引擎、加密密钥、目录布局及恢复方式;不确定时优先选择兼容的逻辑导出导入。

五、停止所有写入,再制作一致性备份

先备份新服务器自己的配置,并在云平台创建合适的恢复点。快照能否保证数据库一致性取决于创建方式,不能替代数据库一致性设计。

按应用依赖顺序停止旧服务器的写入来源,例如网站入口、任务队列和定时任务,然后停止数据库。以下服务名是示例,不能直接照搬:

sudo systemctl stop example-worker.service
sudo systemctl stop example-scheduler.service
sudo systemctl stop nginx.service
sudo systemctl stop php-fpm.service
sudo systemctl stop mysqld.service

停止前要先记录哪些服务原本在运行。停止后应检查进程和连接,不能仅凭停止命令没有报错,就认为没有写入。还需要排除远程数据库客户端、事件调度器和其他后台程序。

方案 A:逻辑导出数据库

逻辑导出需要数据库保持运行。应先停止应用写入,再导出,最后按迁移方案决定是否停止数据库:

mysqldump -u backup -p \
  --single-transaction --routines --events --triggers \
  --databases example_db > example_db.sql

--single-transaction 主要用于事务表的一致性视图,不会自动保证非事务表或并发 DDL 的一致性。导出账户权限、字符集和跨版本兼容性也需要检查。账号与授权通常应单独处理,不能假定只导出业务库就迁移了全部用户。

方案 B:数据库完全停止后复制数据目录

只在已确认版本和物理恢复方式兼容时采用。必须确认数据库进程已退出,复制实际数据目录以及恢复需要的配置和密钥。不要直接打包正在运行的数据库数据文件。

备份应用与配置

先创建仅管理员可访问的目录,再按盘点清单打包:

BACKUP_DIR=/var/backups/migration-example
sudo install -d -m 700 "$BACKUP_DIR"

sudo tar --acls --xattrs -czpf "$BACKUP_DIR/app.tar.gz" \
  -C /srv example-app

sudo tar --acls --xattrs -czpf "$BACKUP_DIR/nginx-config.tar.gz" \
  -C /etc nginx

单独备份数据库、证书、Supervisor、服务单元、定时任务及需要的用户文件。保留原文件所有者、权限、ACL 和扩展属性,并记录恢复要求。

不要无差别打包整个 /usr/local 或覆盖整个 /etc。其中可能包含云安全代理、机器身份、网络配置和不可迁移的运行状态。软件依赖应按清单安装或选择性迁移;云厂商代理通常由新实例自己维护。

记录软件包清单,便于补齐依赖:

# RPM 系统
rpm -qa > packages.txt

# Debian 系统
dpkg-query -W > packages.txt

软件包清单是盘点资料,不是可以无条件批量安装的脚本。

六、传输备份并校验

先在旧服务器生成哈希:

cd /var/backups/migration-example
sha256sum app.tar.gz nginx-config.tar.gz > SHA256SUMS

使用已核验主机身份的 SSH 连接传输文件。两端都可从管理电脑访问时,可以通过管理电脑中转,也可以在已配置安全认证的前提下使用 scp 或 rsync。

备份传输必须加密,目标目录也应限制访问。不要为了速度把备份放到公开下载目录。

在新服务器同一备份目录中验证:

sha256sum -c SHA256SUMS

同一云网络内传输通常能减少公网传输开销,但必须先确认网络互通、SSH 主机身份和访问控制。如果使用临时传输密钥,要限制来源与用途,并在完成后撤销目标端授权、删除临时私钥。

不要把管理电脑长期使用的私钥复制到旧服务器上。

七、在新服务器恢复

先安装兼容的软件和依赖,创建相应业务用户。恢复文件所有权时,核对旧、新服务器的 UID/GID,不能仅凭用户名相同就认定权限正确。

先查看归档内容,再解压到暂存目录:

sudo tar -tzf /var/backups/migration-example/app.tar.gz
sudo install -d -m 700 /var/backups/migration-example/staging
sudo tar --acls --xattrs -xzpf \
  /var/backups/migration-example/app.tar.gz \
  -C /var/backups/migration-example/staging

检查内容和路径后,再安装到预定业务目录。配置文件应与新服务器合并,避免覆盖网络、SSH、磁盘挂载和机器身份。

数据库恢复有两条对应路径:

  • 逻辑备份:启动兼容数据库,导入业务库并恢复必要授权,保持应用和任务关闭直至核对完成。
  • 停库物理备份:保持目标数据库停止,按数据库支持的物理恢复流程恢复,核对目录权限和配置后再启动。

逻辑备份导入示例:

mysql -u admin -p < example_db.sql

复制编译好的程序后,检查依赖:

ldd /path/to/trusted/application

只对可信程序使用 ldd。如果出现 not found,应优先从可信软件源安装依赖。不要直接覆盖新系统的 glibc、动态加载器等核心组件。

同时检查 SELinux 上下文、目录访问权限和应用可写目录,不要用全目录 chmod 777 或关闭 SELinux 来掩盖问题。

八、修改与服务器地址有关的配置

需要检查的常见位置包括:

  • 前端 API 地址和 WebSocket 地址。
  • 后端监听地址、回调地址和数据库连接。
  • Nginx 的 server_name、反向代理和重定向。
  • FTP 对外地址、第三方 IP 白名单。
  • 客户端保存的服务器地址。
  • DNS、CDN、负载均衡和对象存储跨域配置。

搜索时优先使用固定字符串,避免 IP 中的点被当成正则通配符:

rg -n -F '192.0.2.10' /srv/example-app /etc/nginx

搜索结果可能含有敏感配置,应在受控环境查看。逐项判断用途后再修改,不要对整个服务器执行全局替换。历史目录名、数据库名、备份记录中的旧地址不一定需要改;前端最好修改源码并重新构建。

九、启动与验证

先验证配置,再按依赖顺序启动:数据库 → 应用运行环境 → 后台服务 → Web 入口 → 定时任务。

sudo nginx -t
sudo systemctl daemon-reload
sudo systemctl start mysqld.service
sudo systemctl start php-fpm.service
sudo systemctl start example-worker.service
sudo systemctl start nginx.service

不要过早开启会发邮件、扣款、调用第三方接口或执行破坏性清理的定时任务。应先确认目标地址和业务状态,避免新旧两台同时执行同一任务。

1. 数据核对

备份哈希一致只能证明传输文件一致,还需要检查恢复结果:

  • 网站文件数量、哈希、软链接、权限和上传目录。
  • 数据库列表、表数量、精确行数以及关键业务记录。
  • 在兼容版本和方法下比较业务表校验值。
  • 执行数据库支持的完整性检查。

例如,小型 MySQL 数据库可在安排好负载后使用:

mysqlcheck -u admin -p --check example_db

表校验方法、锁和性能影响应按数据库版本、存储引擎评估。大库不要直接照搬可能长时间占用资源的检查命令。

2. 服务与端口

systemctl --failed --no-pager
systemctl is-active nginx mysqld php-fpm
ss -lntup
supervisorctl status

systemd 显示 active 不一定说明实际业务进程正常。有些旧式服务脚本退出成功,但守护进程可能没有启动,应同时检查进程、监听端口和日志。

3. 切换 DNS 前验证网站

使用 --resolve,让请求直达新服务器,同时保留正确域名、Host 和 TLS SNI:

curl --resolve blog.example.com:443:198.51.100.20 \
  -I https://blog.example.com/

不要使用 -k 作为证书验收方式。证书过期或域名不匹配,需要正确处理。

首页返回 200 只是基础检查。还要测试登录、数据库查询、文件上传下载、后台任务、API、WebSocket,以及客户端实际连接。FTP 则应测试登录、TLS 和被动模式传输,不能只看 21 端口。

4. 重启验证

确认服务已按预期启用开机自启,在维护窗口内重启新服务器。重连后再次检查数据库、网站、后台服务、定时任务、挂载和交换空间。

重启前应确保有控制台恢复入口,避免配置错误导致 SSH 无法重新连接。

十、切换 DNS 和客户端地址

正式切换前,应再次确认旧服务器不会产生新写入。如果预同步期间仍有写入,必须停写并做最后一次增量同步或重新导入。

将需要迁移的域名 A 记录指向新 IP,检查是否存在仍指向旧服务器的 AAAA 记录,并同步处理 CDN 或负载均衡源站。

不要假定修改解析控制台中的记录就一定生效:注册商实际委派的 NS 必须正确。迁移 DNS 服务商时,还需要迁移邮件、验证记录等完整配置,并协调已有 DNSSEC 的 DS 记录,防止解析验证失败。

客户端使用旧 IP 时,需要更新地址;使用域名时,通常随 DNS 生效而切换。仍应考虑缓存、长连接和客户端本地配置。

HTTPS 证书也要验证:可安全迁移仍有效且覆盖域名的证书,也可在验证条件具备后重新申请。证书私钥必须限制访问,并确认自动续期任务和部署钩子在新服务器有效。

十一、保留回退能力

切换后保留旧服务器和备份一段观察期,旧业务保持停止或隔离,避免双写。不要立即删除旧数据或释放实例。

回退不是简单把 DNS 改回去:如果新服务器已经接受了写入,必须先处理新数据,否则会丢失切换后的业务记录。应事先定义停写、数据回同步、入口切回和验证步骤。

确认稳定后,再按保留策略处理备份、撤销临时访问、清理迁移凭据,并安排旧实例下线。

十二、如何判断迁移完成

可以把完成状态分成三层:

阶段验收内容
数据与环境恢复文件、数据库、配置和依赖已恢复并核对
服务运行验证进程、端口、日志、证书和重启自启正常
业务切换验收域名与客户端已切换,真实业务操作通过,监控稳定

只有首页能打开,不能代表全部业务验收完成。记录已测试的范围和未覆盖的功能,才能明确剩余风险。

十三、迁移中容易踩的坑

问题改进方法
打包运行中的数据库文件停库物理备份,或使用数据库支持的一致性备份
整体覆盖 /etc、/usr/local按清单选择性恢复,保留新主机网络、身份和云代理
忽略证书和 FTP TLS 文件将证书、私钥和协议实际连接列入验收
用户名相同但权限异常核对 UID/GID、ACL、SELinux 上下文
服务显示 active,但端口没监听检查进程、日志和真实连接
新旧两台同时执行定时任务在明确切换点迁移任务执行权
只改 DNS A 记录同时检查 NS、AAAA、CDN、DNSSEC 和缓存
全局替换旧 IP根据配置含义逐项修改,保留必要的历史目录与数据
迁移后立刻删除旧实例保留观察期和可执行的回退方案
把运维记录直接改成公开博客删除真实标识、凭据和拓扑,使用文档专用示例
0

评论 (0)

取消