Mix SpaceMix Space

v11 升级到 v12

从 v11 升级到 v12 的完整指南,包含 MongoDB 到 PostgreSQL 的迁移步骤

v12 是一次重大版本升级,底层数据库从 MongoDB 更换为 PostgreSQL。虽然你的文章、评论、配置等数据都会保留,但升级过程中需要执行一次数据迁移,且需要短暂的停站维护。

如果你当前版本低于 v11,请先升级到 v11,再执行本指南。

升级前必读(3 分钟)

这次升级会变什么?

  • 数据库:MongoDB → PostgreSQL(性能更好,数据关系更安全)
  • 备份方式:以后用 pg_dump 代替 mongodump
  • 环境变量:旧的 DB_HOSTMONGO_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 文件大小不为 0
  • mx-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

它做三件事:

  1. 读取 v11 的 MongoDB
  2. 在目标 PostgreSQL 上跑 v12 的 schema migration
  3. 分配 Snowflake ID,把每个 collection 的数据写进对应 PG 表

两种模式

  • dry-run(默认):只读,不写入。先跑这个看报告
  • apply:写入。可重复执行,不会重复导入

环境变量(最少 2 个):

变量说明
MONGO_URIv11 MongoDB 连接串,如 mongodb://127.0.0.1:27017/mx-space
PG_URLv12 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

预期看到 postgresredis 状态都是 healthyUp。也确认 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:27017postgres:5432 连接。

预期输出

  • Rows allocated: XXXX,数字与你的文章/评论数量接近
  • Missing refs: 0(少量孤儿数据可接受)
  • 最后出现 ✅ Migration finished without missing references.

如果报错怎么办?

错误提示原因解决
MongoServerSelectionErrormongo 端口未暴露 / 网络未联通检查 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 apply

apply 模式可重复执行:被 Ctrl+C 打断后再跑不会重复导入。

构建并启动

pnpm build
pnpm bundle
cd apps/core
pm2 start ecosystem.config.js

验证

与 Docker 验证清单相同(见上方第 6 步)。


第三步:清理旧数据库(可选)

建议 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)会丢失这部分。建议:

  1. 优先在 v12 上排查修复问题(推荐)
  2. 如需帮助,带上错误日志发 GitHub Issue

常见问题

迁移会删除我的 MongoDB 数据吗?

不会。 迁移是读取 MongoDB → 写入 PostgreSQL,MongoDB 原封不动。这就是回滚安全的根本原因。

图片和附件会丢吗?

不会。 图片、附件存在文件系统或对象存储里,不在数据库中,完全不受影响。

迁移可以中断后再继续吗?

可以。 重复执行迁移命令不会重复导入已迁过的数据,所以可以放心重试。

我需要改前端吗?

一般不需要。 官方主题(Shiro / Kami / Yohaku)直接兼容。只有直接调用 API 的第三方工具可能需要更新 SDK。

为什么要换数据库?

PostgreSQL 是更成熟的关系型数据库,数据一致性更好,未来做复杂查询和统计分析也更方便。对日常使用而言,你感觉不到明显变化,但长期更稳定可靠。


还需要帮助?

On this page