如何备份 Multica 自建实例的 PostgreSQL 数据(含 pg_dump 陷阱)
如果你的 Multica 是自建实例,在升级版本之前应该先对 PostgreSQL 做一次完整导出:官方文档明确指出迁移是 forward-only 的,因此备份是升级前唯一的回退依据。本文按 self-host-quickstart 中 “Back up Postgres first” 一节的写法,给出官方推荐的导出命令,并解释为什么不能把 pg_dump 直接管道给 gzip。
适用前提:
- 通过 Docker Compose 运行的自建实例(
docker-compose.selfhost.yml),postgres容器处于运行状态; - 执行机器上已安装 Docker 与 Compose v2(
docker compose形式,文档明确不支持 legacy 的docker-composev1)。
备份前确认数据位置与凭据
Multica 自建栈的 PostgreSQL 容器使用 pgvector/pgvector:pg17 镜像,需要 pgcrypto 与 pg_trgm 扩展(见 SELF_HOSTING.md 的 Architecture 一节)。数据存放在命名卷 multica_pgdata 中,映射到容器内 /var/lib/postgresql/data(见 docker-compose.selfhost.yml)。
有两点直接影响备份命令:
- 用户名和库名以
.env为准。 compose 文件中两者默认值都是multica(${POSTGRES_USER:-multica}、${POSTGRES_DB:-multica})。如果你改过.env中的POSTGRES_USER/POSTGRES_DB,命令中的-U multica multica要换成你自己的值——官方文档的原话是:改过默认值时,用.env里自己的POSTGRES_USER/POSTGRES_DB。 - 区分“停服务”和“删卷”。
docker compose down保留pgdata和backend_uploads两个卷,数据还在;加上-v会删除这些卷,数据库数据一并消失。文档警告:除非你本来就打算抹掉整个实例,否则不要执行docker compose down -v。
执行备份
在 multica 仓库目录(能访问 docker-compose.selfhost.yml 的目录)执行官方给出的命令:
docker compose -f docker-compose.selfhost.yml exec -T postgres \
pg_dump -U multica multica > multica-backup.sql && gzip multica-backup.sql
这条命令做的事:
exec -T postgres在运行中的postgres容器内执行pg_dump,不需要在宿主机安装 PostgreSQL 客户端;pg_dump -U multica multica以multica用户导出multica库,输出重定向到当前目录的multica-backup.sql;&&保证只有pg_dump自身成功(退出码为 0)时才执行gzip压缩。
命令正常走完后,当前目录下应有一份 multica-backup.sql.gz。
pg_dump 陷阱:为什么不能直接管道给 gzip
一个常见的“省事”写法是把导出直接压缩:
# 错误写法:导出失败时整条管道仍然以 0 退出
docker compose -f docker-compose.selfhost.yml exec -T postgres \
pg_dump -U multica multica | gzip > multica-backup.sql.gz
官方文档对这个陷阱的说明是:shell 报告的管道退出状态是最后一条命令(这里是 gzip)的退出码,所以即使 pg_dump 导出失败,整条管道照样以 0 退出——留下一个格式完全合法、但里面什么都没有的 20 字节压缩包(文档中给出的失败产物示例)。你以为备份成功,文件里实际没有任何数据。
先重定向到 .sql 文件再压缩的写法正是为了规避这一点:pg_dump 自己的退出码成为整条命令的判定依据,导出失败时 && 之后的 gzip 根本不会执行,也就不会产出一个看起来正常的空压缩包。
据此判断备份是否成功:按正确写法执行后,如果命令链未走到 gzip(出现非零退出码),说明导出失败,先检查 pg_dump 的报错(例如用户名/库名与 .env 不一致),修复后重新执行,不要归档任何“半成品”压缩包。
备份时机与边界
- 升级前先备份。 官方把这条备份命令放在升级流程(
docker compose pull+up -d)之前的位置,原因就是迁移 forward-only,没有回滚命令。 - Kubernetes 部署的对照边界。 如果你用的是 Helm 部署,数据在 PVC 中:
helm -n multica uninstall multica保留 PVC 与 Secret,而kubectl delete namespace multica会删除包括 PostgreSQL 数据和 uploads 在内的一切(见 SELF_HOSTING.md 的 Tearing down 一节)。本文的docker compose exec导出路径只覆盖 Docker Compose 部署,K8s 部署文档未给出对应的导出命令。 - 官方文档目前只给出备份命令,没有提供从 dump 文件恢复的操作流程;本文覆盖备份这一侧。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0634
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
jforgamejforgame是一个一站式游戏服务器开发框架。包含游戏服务器开发所需要的各种组件,比如网关,socket服务端与客户端,自定义高效消息编解码,游戏热更新,游戏通用工具等等。包含游戏服,跨服,匹配服,后台管理系统等实现,同时提供大量业务案例以供学习。亦可用于其他socket应用,例如及时聊天等。Java01
fizz-gateway-nodeAn Aggregation API Gateway in Java . FizzGate 是一个基于 Java开发的微服务聚合网关,是拥有自主知识产权的应用网关国产化替代方案,能够实现热服务编排聚合、自动授权选择、线上服务脚本编码、在线测试、高性能路由、API审核管理、回调管理等目的,拥有强大的自定义插件系统可以自行扩展,并且提供友好的图形化配置界面,能够快速帮助企业进行API服务治理、减少中间层胶水代码以及降低编码投入、提高 API 服务的稳定性和安全性。Java00
certd开源SSL证书管理工具;全自动证书申请、更新、续期;通配符证书,泛域名证书申请;证书自动化部署到阿里云、腾讯云、主机、群晖、宝塔;https证书,pfx证书,der证书,TLS证书,nginx证书自动续签自动部署JavaScript00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00