Skip to content

Latest commit

 

History

History
405 lines (278 loc) · 12.1 KB

File metadata and controls

405 lines (278 loc) · 12.1 KB

升级到 MX Space v12

v12 将底层数据库从 MongoDB 更换为 PostgreSQL。你的文章、评论、配置等所有数据都会保留,但需要执行一次迁移操作。

数据迁移工具已独立为 npm 包 @mx-space/mongo-pg-cli v12 镜像不再内置 migrate-mongo-to-postgres.ts 脚本,也不再内置 mongodump / mongo-tools。所有迁移命令都通过 npx @mx-space/mongo-pg-cli@latest 执行(要求宿主机或临时容器有 Node.js 22+)。

升级前必读

这次升级会变什么?

  • 数据库:MongoDB → PostgreSQL(性能更好,数据更安全)
  • 备份方式mongodumppg_dump(以后备份用新命令)
  • 环境变量DB_HOST / MONGO_CONNECTION 等旧变量失效,改用 PG_URL
  • 镜像内容:v12 镜像不再附带 mongodump 与旧迁移脚本;备份与迁移须在宿主机或一次性容器中完成

什么不会变?

  • 前端页面、API 接口和之前完全一致
  • 你的文章、评论、图片、配置全部保留
  • 登录方式、密码、API Key 不受影响

你需要做什么?

你的部署方式 操作复杂度 预计停站时间
Docker(多数用户) 中等 5–30 分钟
源码/PM2 部署 较高 10–60 分钟

⚠️ 升级前务必备份。迁移工具是只读且幂等的,但备份是最后一道保险。


升级 Checklist

开始前,确认以下事项:

  • 当前版本是 v11.x(v10 或更早请先升到 v11)
  • 已备份 MongoDB 数据(见下方命令)
  • 服务器或临时容器有 Node.js 22+(用于跑 npx
  • 服务器剩余磁盘空间 > 当前数据量的 2 倍
  • 已准备好至少 30 分钟的维护窗口(期间不要发文章/评论)

第一步:备份(必须)

无论你用哪种方式部署,先在 MongoDB 仍在运行的状态下执行备份。注意 v12 的 docker-compose 已不含 mongo 容器,本步要在仍是 v11 的 mongo 容器上做。

# 进入你放 docker-compose.yml 的文件夹,或者 core 源码文件夹
cd ~/mx-space/core

# 方式 A:现存 v11 mongo 容器中已自带 mongodump
docker exec -i $(docker ps -q -f name=mongo) mongodump --archive > backup-mongo-$(date +%Y%m%d).archive

# 方式 B:宿主机有 mongodump
mongodump --uri="mongodb://localhost:27017/mx-space" --archive=backup-mongo-$(date +%Y%m%d).archive --gzip

# 方式 C:什么都没有,临时容器
docker run --rm --network host mongo:7 \
  mongodump --uri="mongodb://127.0.0.1:27017/mx-space" --archive --gzip > backup-mongo-$(date +%Y%m%d).archive.gz

# 同时打包整个数据目录
tar czvf mx-space-full-backup-$(date +%Y%m%d).tar.gz ./data

验证备份:确认 archive 文件大小不为 0,且 .tar.gz 包含 data/mx-space 目录。


第二步:迁移工具

无论部署方式,迁移命令都是同一个:

# dry-run(默认):只读 mongo,模拟迁移,不写 PG
npx @mx-space/mongo-pg-cli@latest --mode dry-run

# apply:真正写入 PG,幂等可重跑
npx @mx-space/mongo-pg-cli@latest --mode apply
变量 默认 说明
MONGO_URI mongodb://127.0.0.1:27017/mx-space 源 v11 MongoDB URI
PG_URL PG_HOST/PG_PORT/... 拼接 目标 PostgreSQL URI
SNOWFLAKE_WORKER_ID 900 迁移产生的行的 worker id,建议保留 900–999 给迁移用

完整参数与故障排查见 @mx-space/mongo-pg-cli README


第三步:根据部署方式选择升级路径

路径 A:Docker 部署

A1. 停止应用,保留 MongoDB 容器

关键:只停 app 服务,不要 docker compose down。MongoDB 容器需要继续运行,CLI 会从中读取数据。

cd ~/mx-space/core
docker compose stop app

确认 mongo 仍在运行并对宿主机暴露 27017:

docker ps | grep mongo
docker port $(docker ps -q -f name=mongo) | grep 27017
# 期望看到  27017/tcp -> 0.0.0.0:27017

A2. 拉取 v12 配置

# 备份旧配置
cp docker-compose.yml docker-compose.yml.v11.backup

# 拉取新的 docker-compose.yml(已内置 PostgreSQL)
wget -O docker-compose.yml https://fastly.jsdelivr.net/gh/mx-space/core@master/docker-compose.yml

A3. 启动 PostgreSQL

# 只启动数据库,先不启动主服务
docker compose up -d postgres redis

等待 10 秒,确认 PostgreSQL 健康,并暴露 5432:

docker compose ps
docker port postgres | grep 5432
# 期望看到 postgres 状态为 healthy,端口 5432/tcp -> 0.0.0.0:5432

A4. 执行数据迁移

宿主机有 Node.js 22+ 时,最简单:

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

宿主机没有 Node.js(仅 Linux,--network host 才支持本机端口):

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 不可用(macOS / Windows Docker Desktop),可改为加入 v12 compose 网络,并先把旧 mongo 容器接入:

docker network connect mx-space_mx-space mongo
docker run --rm --network mx-space_mx-space \
  -e MONGO_URI="mongodb://mongo:27017/mx-space" \
  -e PG_URL="postgres://mx:mx@postgres:5432/mx_core" \
  node:22-alpine \
  npx -y @mx-space/mongo-pg-cli@latest --mode apply

预期输出

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

如果报错

错误 原因 解决
MongoServerSelectionError mongo 端口未暴露 / 网络未联通 检查 mongo 容器是否映射 27017,或确认 --network 设置正确
connection refused(PG) PG 还没启动好 等 30 秒重试
Missing refs > 0 有孤儿数据 通常可忽略,截图记录后继续
其他错误 未知问题 不要继续,保留日志,回滚到 v11

A5. 启动 v12 服务

docker compose up -d

A6. 验证

逐项检查:

  • 打开首页,文章列表正常显示
  • 打开一篇文章,内容和评论都在
  • 登录后台(你的域名/proxy/qaqdmin),能正常登录
  • 后台「其他 - 备份」页面能正常打开
  • 发一篇测试文章,能正常发布和显示
  • 删除测试文章,正常删除

全部通过 = 升级成功。


路径 B:源码 / PM2 部署

B1. 停止服务

cd ~/mx-space/core/apps/core
pm2 stop ecosystem.config.js

B2. 拉取 v12 代码

cd ~/mx-space/core
git fetch origin
git checkout v12.x.x  # 或 master 上的最新 v12 tag
pnpm i

B3. 安装 PostgreSQL

如果你还没有 PostgreSQL 16+:

# Ubuntu/Debian
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;"

B4. 配置环境变量

编辑 apps/core/.envecosystem.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

# 必须添加:工作节点 ID,单实例填 1
SNOWFLAKE_WORKER_ID=1

B5. 执行迁移

# 先试运行(不写入,只检查)
SNOWFLAKE_WORKER_ID=900 \
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

# 确认无报错后,正式迁移
SNOWFLAKE_WORKER_ID=900 \
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

迁移阶段建议把 SNOWFLAKE_WORKER_ID 设为 900–999,与运行时实例的 worker id 错开,详见 CLI README。

B6. 构建并启动

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

B7. 验证

同 Docker 验证清单(见 A6)。


第四步:清理(可选,建议 48 小时后再做)

确认 v12 运行稳定后:

# Docker 用户:删除旧 MongoDB 容器和数据卷
docker compose rm -f mongo
docker volume rm mx-space_mongo_data  # 名字可能不同,用 docker volume ls 查看

# 源码用户:停止并卸载 MongoDB
sudo systemctl stop mongod
# (保留备份文件,卸载与否自行决定)

如果升级失败,如何回滚

场景 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

场景 2:v12 启动了,但数据不对或功能异常

立即切回 v11:

# 停止 v12
docker compose down  # 或 pm2 stop ecosystem.config.js

# 恢复 v11 配置和代码
cp docker-compose.yml.v11.backup docker-compose.yml  # Docker
git checkout v11.x.x                                # 源码

# 启动 v11(仍然连 MongoDB)
docker compose up -d  # 或 pm2 start ecosystem.config.js

MongoDB 数据在迁移过程中只读不会被修改,所以回滚后数据完全和升级前一样。

场景 3:已经在 v12 写了新数据,想回滚

这种情况比较复杂,因为新数据在 PostgreSQL 里,回滚到 MongoDB 会丢失这部分。建议:

  1. 先导出 v12 新增的内容(手动复制文章等)
  2. 或者直接在 v12 上排查修复问题(推荐)
  3. 如需帮助,带上日志发 GitHub Issue

常见问题

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

不会。迁移是只读 MongoDB 写入 PostgreSQL,MongoDB 原数据不动。这也是为什么回滚到 v11 是安全的。

Q: 我有很多图片和附件,会受影响吗?

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

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

可以。CLI 持久化 mongo_id_map,重复执行 apply 不会重复导入已迁移的数据。

Q: 为什么 v12 镜像没有迁移脚本和 mongodump 了?

v12 之后,迁移工具独立成 @mx-space/mongo-pg-cli 单独发布,与运行时镜像解耦。这样:

  • 镜像更小,启动更快
  • 迁移工具可以独立迭代修复,无需重发镜像
  • 一次性的迁移工具不应作为运行时依赖常驻

Q: 为什么从 MongoDB 换到 PostgreSQL?

PostgreSQL 是更成熟的关系型数据库,能更好地保证数据完整性,未来的功能扩展(如更复杂的查询、统计分析)也会更容易。对普通用户而言,日常体验不会有明显变化,但长期更稳定。

Q: 我需要改前端配置吗?

一般不需要。如果你用的是 Shiro / Kami / Yohaku 等官方主题,直接兼容。只有直接调用 API 的第三方工具可能需要更新 @mx-space/api-client 到 v12 版本。


相关资源