老服务器下个月初到期,续费价格有点高,趁着上周有活动新购了一台 4 核 8G 的机器。周末花了小半天时间,把跑在上面的几个个人站点、一个内部接口服务以及 MySQL 数据库全部平移了过去。
网站搬家本身不复杂,但小细节极多,一不留神就会遇到文件权限不对导致无法上传附件、或者数据库字符集不一致导致中文乱码等琐碎问题。这里把整体流程和踩坑细节记录下来,留个备忘。
1. 迁移前的环境准备与对齐
很多人一上来就急着拷数据,结果新机器环境不匹配,折腾半天跑不起来。最稳妥的做法是先在新机器上把运行环境对齐:
- 软件版本一致性:检查老机器上的 Nginx/Apache、MySQL 以及 PHP 版本。例如老机器用的是 MySQL 5.7 和 PHP 7.4,新机器尽量也装相同的版本,避免升级到 MySQL 8.0 之后出现 SQL 语法或默认密码认证机制不兼容的问题。
- PHP 扩展检查:比对已安装的 PHP 扩展(如 redis、fileinfo、exif、opcache 等),缺什么提前在新机器补装好。
- 提前调小 DNS 的 TTL:在迁移前 12 到 24 小时,去域名解析商后台把网站域名的 A 记录 TTL 改为 600(10分钟)或更小,这样在数据同步完成切换 IP 时能以最快速度生效。
2. 数据迁移方案选择与实操
针对不同体量的数据,搬家方式略有不同:
| 数据量规模 | 推荐迁移方式 | 核心优势 | 注意事项 |
|---|---|---|---|
| 10G 以内 | 宝塔自带的“一键迁移”插件 | 操作门槛低,自动配置数据库与站点 | 两端面板需开启 API 密钥,受限于双方服务器出口带宽 |
| 10G - 50G | 手动导出 SQL + 本地打包压缩 | 进度可控,不容易因中间网络波动中断 | 打包时排除 log 等缓存无用目录,尽量在低峰期进行 |
| 50G 以上 | 命令行 rsync 增量同步 + mysqldump | 耗时短,支持二次断点增量同步 | 需要熟悉基本的 Linux 命令与 SSH 互通操作 |
这次我的站点数据加起来大概 18G,为了省事且稳妥,我采用的是组合方式:
- 数据库导出:在老服务器通过面板自带的备份功能将数据库导出为
.sql.gz,或者直接在 SSH 下使用mysqldump -u root -p --single-transaction --default-character-set=utf8mb4 dbname > dbname.sql导出,确保字符集不丢失。 - 文件传输:静态资源与源码先打包成
tar.gz,直接通过scp命令从老服务器推送到新服务器的对应目录下解压,内网或者云厂商同地域互通的话速度非常快。
如果两台机器网络状况良好,使用宝塔官方软件商店里的“宝塔一键迁移API版本”也是个不错的省心方案,它会自动帮你把虚拟主机配置文件、SSL 证书和数据库建好。
3. 数据还原与本地 hosts 验证
新机器解压完文件、导入数据库后,千万不要直接把域名解析切过来,必须先做本地预检。
- 修改站点配置:检查新机器上站点的根目录路径、PHP 版本指定以及 Nginx 伪静态规则是否和老服务器一致。
- 更新数据库连接:修改网站配置文件(如 WordPress 的
wp-config.php或 Typecho 的config.inc.php),确认数据库名、用户名和密码与新服务器创建的一致。 - 本地 hosts 绑 host 验证:
C:\Windows\System32\drivers\etc\hosts,Mac/Linux 位于 /etc/hosts)。
- 添加一行:新服务器IP yourdomain.com。
- 清理本地 DNS 缓存后用浏览器访问,登录后台发布一篇测试内容、上传一张图片,确认全站路由、数据库读写、SSL 证书展示均无异常。
4. 几个迁移后容易遗漏的细节
验证通过后,将域名解析的 A 记录正式切换为新服务器 IP。切换完成后,记得核对以下几项:
- 文件属组权限:很多文件解压后所属用户会变成
root,导致网站程序运行时无法生成缓存或上传附件。在网站根目录下执行chown -R www:www /www/wwwroot/你的网站目录,将权限统一重置为 www 用户。 - 计划任务(Cron):宝塔面板自带的“计划任务”不会自动随数据迁过来,老机器上的备份脚本、日志切割、系统垃圾清理等定时任务,需要在新机器上手动重建。
- 防火墙端口放行:新机器如果开启了云厂商的安全组策略或面板自带的系统防火墙,记得放行常用业务端口(如 80、443 以及自定义的 SSH 端口)。
- 老服务器观察:老机器先不要急着清空,保留运行 2-3 天,观察访问日志(Nginx Access Log),确认基本没有回流访问后再停止老机器的服务,避免部分地区 DNS 缓存过长导致老数据被更新。