v11 升级到 v12
从 v11 升级到 v12 的完整指南,包含 MongoDB 到 PostgreSQL 的迁移步骤
v12 是一次重大版本升级,底层数据库从 MongoDB 更换为 PostgreSQL。虽然你的文章、评论、配置等数据都会保留,但升级过程中需要执行一次数据迁移,且需要短暂的停站维护。
如果你当前版本低于 v11,请先升级到 v11,再执行本指南。
升级前必读(3 分钟)
这次升级会变什么?
- 数据库:MongoDB → PostgreSQL(性能更好,数据关系更安全)
- 备份方式:以后用
pg_dump代替mongodump - 环境变量:旧的
DB_HOST、MONGO_CONNECTION等变量失效
什么不会变?
- 前端页面、API 接口和之前完全一致
- 你的文章、评论、图片、配置全部保留
- 登录方式、密码、API Key 不受影响
我需要停站多久?
| 数据规模 | 预估时间 |
|---|---|
| 文章 < 100 篇,评论 < 1000 条 | 5–10 分钟 |
| 文章 < 1000 篇,评论 < 1 万条 | 10–30 分钟 |
| 大型站点 | 30–60 分钟 |
升级 Checklist
开始前,请确认:
- 当前版本是 v11.x
- 服务器剩余磁盘空间 > 当前数据量的 2 倍
- 已准备好至少 30 分钟的维护窗口(期间不要发文章/评论)
第一步:备份(必须)
无论你用 Docker 还是源码部署,先执行备份:
# 进入你放 docker-compose.yml 的文件夹,或者 core 源码文件夹
cd ~/mx-space/core
# 备份 MongoDB 数据
docker exec -i $(docker ps -q -f name=mongo) mongodump --archive > backup-mongo-$(date +%Y%m%d).archive
# 同时打包整个数据目录(包含配置文件、图片等)
tar czvf mx-space-full-backup-$(date +%Y%m%d).tar.gz ./data验证备份:
backup-mongo-YYYYMMDD.archive文件大小不为 0mx-space-full-backup-YYYYMMDD.tar.gz包含data/mx-space目录
第二步:选择你的升级路径
数据迁移工具:@mx-space/mongo-pg-cli
无论 Docker 部署还是源码部署,核心步骤是同一个 CLI:
npx @mx-space/mongo-pg-cli@latest --mode dry-run
npx @mx-space/mongo-pg-cli@latest --mode apply它做三件事:
- 读取 v11 的 MongoDB
- 在目标 PostgreSQL 上跑 v12 的 schema migration
- 分配 Snowflake ID,把每个 collection 的数据写进对应 PG 表
两种模式:
dry-run(默认):只读,不写入。先跑这个看报告apply:写入。可重复执行,不会重复导入
环境变量(最少 2 个):
| 变量 | 说明 |
|---|---|
MONGO_URI | v11 MongoDB 连接串,如 mongodb://127.0.0.1:27017/mx-space |
PG_URL | v12 PostgreSQL 连接串,如 postgres://mx:mx@127.0.0.1:5432/mx_core |
SNOWFLAKE_WORKER_ID | 迁移产生的行的 worker id,建议留 900–999 给迁移用,默认 900 |
完整参数与故障排查见 CLI 自身的 README。
需要 Node.js 22+ 来跑 npx。如果服务器没有 Node,下面的 Docker 流程提供了用镜像内置 CLI 的备选方案。
Docker 部署升级
停止应用,保留 MongoDB 容器
关键:只停 app 服务,不要 docker compose down。MongoDB 容器需要继续运行,迁移脚本会从中读取数据。
cd ~/mx-space/core
# 只停业务进程,让 mongo 继续跑
docker compose stop app确认 MongoDB 仍在运行并对宿主机暴露 27017 端口:
docker ps | grep mongo
docker port $(docker ps -q -f name=mongo) | grep 27017
# 期望看到类似 27017/tcp -> 0.0.0.0:27017
# 没暴露则在旧 compose 里 ports: ["27017:27017"],重启 mongo 容器更新配置文件
# 备份旧配置(以防万一)
cp docker-compose.yml docker-compose.yml.v11.backup
# 拉取 v12 的 docker-compose.yml(已内置 PostgreSQL)
wget -O docker-compose.yml https://fastly.jsdelivr.net/gh/mx-space/core@master/docker-compose.yml启动新数据库
# 只启动 PostgreSQL 和 Redis,先不启动主服务
docker compose up -d postgres redis等待 10 秒后检查状态:
docker compose ps预期看到 postgres 和 redis 状态都是 healthy 或 Up。也确认 PostgreSQL 端口 5432 已映射到宿主机:
docker port postgres | grep 5432
# 期望看到 5432/tcp -> 0.0.0.0:5432执行数据迁移
这是最关键的一步。执行前请确保没有用户在发文章或评论。
方式 A(推荐):宿主机直接 npx
要求服务器装了 Node.js 22+。npx 会自动下载 CLI,连接 mongo 与 pg 两个本地端口:
MONGO_URI="mongodb://127.0.0.1:27017/mx-space" \
PG_URL="postgres://mx:mx@127.0.0.1:5432/mx_core" \
npx @mx-space/mongo-pg-cli@latest --mode dry-run确认报告无致命错误后,再 apply:
MONGO_URI="mongodb://127.0.0.1:27017/mx-space" \
PG_URL="postgres://mx:mx@127.0.0.1:5432/mx_core" \
npx @mx-space/mongo-pg-cli@latest --mode apply如果你的 mongo 数据库名不是 mx-space、PG 凭证不是 mx:mx,对应替换。
方式 B:服务器没装 Node.js — 用临时 Node 容器跑
跑一个一次性的 Node 容器代替 host node。容器需同时访问 mongo 和 postgres,最简单是 --network host(Linux 服务器适用;macOS/Windows 的 Docker Desktop 不支持,请改用方式 A):
docker run --rm --network host \
-e MONGO_URI="mongodb://127.0.0.1:27017/mx-space" \
-e PG_URL="postgres://mx:mx@127.0.0.1:5432/mx_core" \
node:22-alpine \
npx -y @mx-space/mongo-pg-cli@latest --mode apply如果 --network host 不可用,可改为 --network <v12 compose 网络名> 并先把旧 mongo 容器接入该网络(docker network connect mx-space_mx-space mongo),再用容器名 mongo:27017 与 postgres:5432 连接。
预期输出
Rows allocated: XXXX,数字与你的文章/评论数量接近Missing refs: 0(少量孤儿数据可接受)- 最后出现
✅ Migration finished without missing references.
如果报错怎么办?
| 错误提示 | 原因 | 解决 |
|---|---|---|
MongoServerSelectionError | mongo 端口未暴露 / 网络未联通 | 检查 mongo 容器是否映射 27017,或确认 --network 设置正确 |
Connection refused (postgres) | PG 还没启动好 | 等 30 秒重试 |
Missing refs > 0 | 有孤儿数据 | 通常可忽略,截图记录后继续 |
| 其他错误 | 未知问题 | 不要继续,保留日志,回滚到 v11(见下方回滚章节) |
启动 v12
docker compose up -d验证(逐项检查)
- 打开首页,文章列表正常显示
- 打开一篇文章,内容和评论都在
- 登录后台(
你的域名/proxy/qaqdmin),能正常登录 - 后台「其他 → 备份」页面能正常打开
- 发一篇测试文章,能正常发布和显示
- 删除测试文章,正常删除
全部通过 = 升级成功。
源码 / PM2 部署升级
停止服务
cd ~/mx-space/core/apps/core
pm2 stop ecosystem.config.js拉取 v12 代码
cd ~/mx-space/core
git fetch origin
git checkout v12.x.x # 替换为实际 tag,或 master 上的最新 v12
pnpm i安装 PostgreSQL
如果你服务器上还没有 PostgreSQL 16+:
# Ubuntu / Debian
sudo apt update
sudo apt install postgresql-16
# macOS
brew install postgresql@16
brew services start postgresql@16创建数据库:
sudo -u postgres psql -c "CREATE USER mx WITH PASSWORD 'mx';"
sudo -u postgres psql -c "CREATE DATABASE mx_core OWNER mx;"修改环境变量
编辑你的环境配置文件(.env 或直接在 ecosystem.config.js 里),删除旧变量:
- DB_HOST=xxx
- MONGO_CONNECTION=xxx添加新变量:
# 方式一:连接字符串(推荐)
PG_URL=postgresql://mx:mx@localhost:5432/mx_core
# 方式二:分开配置
PG_HOST=localhost
PG_PORT=5432
PG_USER=mx
PG_PASSWORD=mx
PG_DATABASE=mx_core
# 必须添加:单实例填 1 即可
SNOWFLAKE_WORKER_ID=1执行迁移
先试运行(只读 MongoDB,不写 PostgreSQL):
SNOWFLAKE_WORKER_ID=1 \
MONGO_URI="mongodb://localhost:27017/mx-space" \
PG_URL="postgresql://mx:mx@localhost:5432/mx_core" \
npx @mx-space/mongo-pg-cli@latest --mode dry-run确认报告无致命错误(Rows allocated 接近真实条数、Missing refs 数量可接受)后,正式迁移:
SNOWFLAKE_WORKER_ID=1 \
MONGO_URI="mongodb://localhost:27017/mx-space" \
PG_URL="postgresql://mx:mx@localhost:5432/mx_core" \
npx @mx-space/mongo-pg-cli@latest --mode applyapply 模式可重复执行:被 Ctrl+C 打断后再跑不会重复导入。
构建并启动
pnpm build
pnpm bundle
cd apps/core
pm2 start ecosystem.config.js第三步:清理旧数据库(可选)
建议 v12 稳定运行 48 小时 后再执行清理。保留旧数据是回滚的最后保障。
Docker 用户
cd ~/mx-space/core
# 删除旧 MongoDB 容器
docker compose rm -f mongo
# 删除 MongoDB 数据卷(名字可能不同,先查看再删)
docker volume ls
docker volume rm mx-space_mongo_data # 请替换为实际卷名源码用户
# 停止 MongoDB 服务
sudo systemctl stop mongod
# 是否卸载 MongoDB 请自行决定,建议至少保留备份文件 30 天如果失败,如何回滚
场景 1:迁移命令就报错了
最简单的回滚,直接恢复 v11:
# Docker
cd ~/mx-space/core
cp docker-compose.yml.v11.backup docker-compose.yml
docker compose up -d
# 源码
cd ~/mx-space/core
git checkout v11.x.x
pm2 restart ecosystem.config.js因为迁移过程只读 MongoDB 不写,所以回滚后数据完全和升级前一样。
场景 2:v12 启动了,但发现数据不对或功能异常
立即切回 v11:
# Docker
cd ~/mx-space/core
docker compose down
cp docker-compose.yml.v11.backup docker-compose.yml
docker compose up -d
# 源码
cd ~/mx-space/core/apps/core
pm2 stop ecosystem.config.js
cd ..
git checkout v11.x.x
pm2 start ecosystem.config.js场景 3:已经在 v12 写了新数据,又想回滚
这种情况比较麻烦,因为新数据在 PostgreSQL 里,回滚到 v11(MongoDB)会丢失这部分。建议:
- 优先在 v12 上排查修复问题(推荐)
- 如需帮助,带上错误日志发 GitHub Issue
常见问题
迁移会删除我的 MongoDB 数据吗?
不会。 迁移是读取 MongoDB → 写入 PostgreSQL,MongoDB 原封不动。这就是回滚安全的根本原因。
图片和附件会丢吗?
不会。 图片、附件存在文件系统或对象存储里,不在数据库中,完全不受影响。
迁移可以中断后再继续吗?
可以。 重复执行迁移命令不会重复导入已迁过的数据,所以可以放心重试。
我需要改前端吗?
一般不需要。 官方主题(Shiro / Kami / Yohaku)直接兼容。只有直接调用 API 的第三方工具可能需要更新 SDK。
为什么要换数据库?
PostgreSQL 是更成熟的关系型数据库,数据一致性更好,未来做复杂查询和统计分析也更方便。对日常使用而言,你感觉不到明显变化,但长期更稳定可靠。