3.4 应用升级与数据迁移踩坑

先给一个判断

升级和迁移出事故,基本都是同一个原因:没备份就动手。 升级是“把数据交给新版本的代码处理”,迁移是“把数据搬到新地方”——两件事都改变数据的归属权。动手前的标准动作永远是一个:备份 + 验证备份可用。本节先讲升级,再讲迁移,最后给一份操作清单。

升级:官方的流程

1Panel 的应用升级入口在已安装列表的【可升级】页面。升级时可以勾选升级前备份应用、自动拉取最新镜像、自定义修改 compose.yml。生产应用升级,“升级前备份”那个勾永远是必选的。

不想升级某个应用,可以点【忽略升级】,之后在“查看忽略应用”里管理。

升级失败的常见原因

现象 原因 处理
升级失败、状态异常 新镜像拉取失败 看任务日志,网络问题
升级后应用起不来 新版本配置不兼容 用备份恢复,先看新版变更说明
升级后数据“没了” 数据卷没挂对 / 换了存储位置 先停手,查容器挂载(见下)
升级后一直 restart 依赖版本不匹配 查容器日志
升级后网站 502 升级拉起失败,OpenResty 连不上后端 先恢复,再查应用容器状态

最重要的一条判断:升级后数据看着没了,先不要任何“修复”操作。数据大概率还在,只是新版本容器没挂载到正确的数据卷。这时候乱动反而可能真把数据搞丢。

# 对比新旧容器的挂载点是不是同一个数据卷
docker inspect 容器名 --format '{{json .Mounts}}' | python -m json.tool

升级前必做的三件事

  1. 备份应用(升级页面勾选,或手动在已安装列表 → 备份);
  2. 看新版本的变更说明——大版本升级常伴随配置格式变化、数据库结构迁移,心里有数再点;
  3. 挑低峰期——升级过程应用是要重启的,会有短暂中断。

一个升级策略建议:核心应用不要追最新版本。等一个小版本出来、社区反馈没问题了再升,能避开绝大多数新版本 bug。升级这件事,慢就是快。

迁移:两种常见场景

场景一:应用到应用之间(换程序)——比如从 A 博客程序换到 B。这种迁移本质上是“数据格式转换”,1Panel 帮不了你,要用程序自带的导出导入工具。流程:旧程序导出 → 新程序导入 → 逐一验证。

场景二:服务器到服务器(换机器)——这是 1Panel 的强项。两种姿势:

姿势 做法 适用
备份搬运 备份应用/网站/数据库 → 下载 → 新机器导入恢复 单个或少量应用
整机迁移 用 1Panel 的迁移/快照能力 整体搬迁

备份搬运的操作要点:

  1. 旧机器上逐项备份:应用、网站、数据库分别备份,下载到本地;
  2. 新机器上先装好同款应用/运行环境,版本尽量一致(版本差异的坑见下面的兼容表);
  3. 导入恢复:网站用网站备份列表的“导入备份”,数据库用数据库的导入备份,应用用已安装应用的导入;
  4. 重建证书和解析——域名 A 记录指向新机器 IP,证书重新申请或导入(绑死了旧机器的证书要换);
  5. 验证后再关旧机器。

涉及面板本身的迁移,1Panel 有专门的迁移文档(主从节点迁移等),这不是本节能覆盖的,参考 1Panel 官方文档:安装部署 中的迁移章节,以官方文档为准。面板迁移涉及服务架构和节点角色,步骤相对复杂,务必照着官方文档一步步来,别自己发挥。

一个完整的复现与修复

现象:一个应用升级后状态异常,数据打不开,用户急了。

排查过程:

  1. 先看任务日志——这次升级因为勾选了升级前备份,存在一个备份点,心里有了底;
  2. docker logs 看新版本容器,报的是配置项格式不对(新版本改了配置文件结构);
  3. 翻官方变更说明,确实提到这个配置项的变化。

修复:先用备份把应用恢复到旧版本恢复服务;然后按新版本文档把配置项改好,重新升级,验证数据完整。

复盘要点:“升级前备份”这个勾,在这个时候就是救命的。另一点更值得记住——升级失败不要硬升,先恢复旧版保证业务,再慢慢研究新版本的要求。

反面教材:同一个应用,另一次没勾备份直接升级,结果新版本起不来、旧版本也回不去,最后只能手工捞数据卷里的文件重头来过。两个场景的差别,只是升睡前点没点那个勾。备份就是这么便宜,不备份就是这么贵。

数据迁移的通用清单

无论哪种迁移,按这个顺序走:

  1. 旧环境保留,迁移完成并验证之前不要删任何东西;
  2. 在新环境先空跑一次,确认流程通;
  3. 迁数据,用导出/导入而不是直接复制文件(数据库直接复制文件目录是不可靠的,MySQL 的数据文件强依赖版本和存储引擎状态);
  4. 验证——核心数据对一遍,走一遍核心功能;
  5. 观察——新环境跑一两天,确认没有隐藏问题;
  6. 才清理旧环境。

“迁移完马上就删旧的”是最常见的悲剧。多留几天旧环境占不了多少资源,但能救你于水火。

停机窗口怎么选

迁移难免要短暂停服(切数据那一下)。经验做法:

  • 通知用户:提前发公告,写清楚“几点到几点可能中断多久”;
  • 冻结写入:切数据前把旧站设为只读或暂停(避免切换过程中新数据写到旧库被丢下);
  • DNS 缓存:换机器必换解析,TTL 提前调小(比如 600 秒),能让用户更快切到新机器。

升级后的验证与回滚

升级完成不等于升级成功。至少确认这三件事:

  1. 容器稳定运行——过 10 分钟再看一眼,没有在反复重启:
# 确认容器是 Up 状态且启动时间没变
docker ps --filter "name=容器名" --format "{{.Names}} {{.Status}}"
  1. 核心功能正常——登录、读写各走一遍;
  2. 版本号真的变了——新的镜像 ID / 版本号对得上。

如果升级失败需要回滚:已安装应用的备份列表里选【恢复】,应用回到升级前的状态(含旧版本镜像数据)。注意:回滚的前提是你升级前备份了。没备份的时候想回滚,只能卸了重装旧版本,数据就得靠应用自己的数据卷了——流程能走通,但要脱一层皮。

版本兼容:最容易翻的坑

组合 风险 建议
数据库跨大版本(如 5.7 → 8.0) 字符集、SQL 语法变化 先验证,最好同版本迁移
应用跨大版本 配置格式、插件不兼容 看变更说明,先备份
PHP 跨大版本 老程序可能在 8.x 上白屏 保留旧运行环境
面板跨大版本 数据结构变化 用官方迁移方案

一个具体建议:PHP 网站升级运行环境前,先在新的 PHP 环境上空跑一次程序再切换(创建一个测试网站,文件复制过去,绑定测试域名验证)。

数据库跨版本迁移的特别提醒:MySQL 5.7 的备份恢复到 8.0 实例上,可能遇到字符集 utf8 → utf8mb4 的默认值变化、保留字冲突(8.0 把 RANK、SYSTEM 等词收为保留字)等问题。能同大版本迁移就同大版本;非要跨,先在一个空实例上完整导入一遍试水,别直接往生产库上导。

迁移后验证清单

迁移完了,至少验证这些:

  • [ ] 能正常访问首页和后台
  • [ ] 登录功能正常
  • [ ] 核心数据条数和迁移前一致
  • [ ] 一次完整的“写入 → 读取”操作(发篇文章、传个图)
  • [ ] 计划任务/备份任务还在正常跑
  • [ ] HTTPS 证书还有效(换机器后证书要重新签发或导入)

最后一条尤其容易忘:新机器上的应用一般没有证书,或者证书绑的是旧 IP/域名,记得在证书模块重新处理(见 2.3 节)。迁移后 24 小时内“网站突然打不开”,排第一的原因就是证书没跟上。

一句大实话

升级和迁移这件事,慢一点不丢人,出事才丢人。所有的操作清单看着繁琐,核心就一句话:给自己留退路。备份是退路,旧环境是退路,低峰期操作也是退路——有退路的时候,你才敢放心大胆地往前走。

本节要点

  • 升级必勾“升级前备份”,核心应用别追最新版;
  • 升级后数据“没了”先停手,查容器数据卷挂载,多半是没丢只是找不到了;
  • 迁移用导出/导入,不要直接复制数据库文件;
  • 旧环境在验证通过前一律保留;
  • 迁移后 HTTPS 证书重新处理一次;
  • 升级失败先回滚保业务,别跟新版本死磕。

下一节:应用和数据库都搞定了,如果系统本身卡得不行——进入第四章,性能与资源治理。