数据库与备份
postgres 里存了什么
Immich 的 postgres 数据库是整套系统里体积不大但价值密度最高的部分。照片文件丢了,你可以从备份盘、旧手机、云相册找回来;数据库一旦损坏,所有照片还在,但人脸分组、相册结构、修复历史、分享链接会一起消失——你得到一屋子照片和一个空白目录。
数据库里大致是这些东西:照片的元数据(拍摄时间、地点、设备型号)、人脸向量与人物分组、用户信息与账号设置、相册与分享记录。体量上,几万张照片的数据库通常在数百 MB 到 GB 级别,和照片本体相比微不足道。正因为它小,备份成本极低;也正因为它小,丢失的代价极高。
一个粗略的数字感:一万张照片对应的数据库体积大致在几十到上百 MB,两万张翻一倍也仍在可以轻松塞进网盘的量级。这决定了数据库备份可以每天做、甚至每天做几次都不心疼——和照片目录的备份频率完全不是一个概念。
| 数据类型 | 体积 | 丢失后果 | 可否从照片恢复 |
|---|---|---|---|
| 照片文件 | 大 | 全部没了 | 看备份情况 |
| 元数据索引 | 小 | 时间线混乱 | 可重建 |
| 人脸分组 | 小 | 人物分组归零 | 可重新识别 |
| 相册结构 | 小 | 整理白费 | 不可恢复 |
| 账号设置 | 小 | 需重新配置 | 不可恢复 |
备份的三个层次
备份不是复制一份那么简单。一个靠谱的方案要覆盖三个层次:文件级、快照级、异地级。文件级是把照片目录和数据库一起复制到另一块盘;快照级是定时对整个容器数据卷拍快照,能在出问题时整体回滚;异地级是把至少一份关键数据放到另一个物理位置。三个层次依次递进,预算有限时先保证前两个。
| 层次 | 防什么 | 成本 | 做法示例 |
|---|---|---|---|
| 文件级 | 误删、误改 | 一块盘 | 定时同步照片目录 |
| 快照级 | 升级翻车 | 存储空间 | 每周卷快照 |
| 异地级 | 灾难性事件 | 网盘或硬盘 | 数据库每日上传异地 |
备份方案的设计原则
设计备份方案时,有三条原则比具体工具更重要。第一是自动化:任何依赖你记得手动执行的备份,三个月后都会变成薛定谔的备份。第二是分层:照片目录和数据库的备份频率、保留策略都不一样,混在一起做肯定有一边吃亏。第三是可验证:备份完能恢复才算数,不能验证的备份和没备份只有一个错误的区别。三条原则听起来朴素,真正坚持的家用系统不多,区别就是出事的那一天。
一个常见的弯路是把云相册当成备份。云相册是备份的一种形态,但它同时是另一个厂商管理的服务——本书第一章讨论过它的风险。对自建用户而言更合理的结构是:NAS 本地是主存储,外置硬盘或另一台机器是近备份,核心数据再有一份异地。这个结构给得起,也不贵。
具体的工具组合可以很简单:系统自带的定时任务跑数据库导出,文件同步工具处理照片目录,每份脚本都把结果和上次对比,发现异常给自己发消息。工具不重要,流程能自己跑起来才重要。

| 原则 | 一句话 | 检验方法 |
|---|---|---|
| 自动化 | 不依赖记忆 | 关掉人肉提醒看它跑多久 |
| 分层 | 不同数据不同频率 | 每类数据单独一条定时任务 |
| 可验证 | 恢复成功才算数 | 季度演练 |
数据库备份的具体做法
postgres 的备份推荐用官方自带的导出工具而不是直接复制数据文件。直接复制文件在服务运行时有风险,写一半复制出来的数据文件未必能用。导出工具会保证一致性,而且导出的是文本格式的 SQL 语句,文件小、可读、跨版本兼容。
一个最低限度的方案长这样:每天凌晨自动导出数据库,保留最近七份;照片目录每周增量同步到备份盘,保留一两个月。两者都可以用系统自带的定时任务加几行脚本完成。关键不是脚本多精巧,而是它能不能在你忘记存在的时候自己跑起来。脚本第一次运行时在日志里确认一次输出,之后每个月扫一眼执行结果,这套流程就算落地了。
一个客观规律改不了:照片会一直长,备份也要一直跟着长。给备份盘留出和照片盘同量级的余量,是比脚本本身更前置的规划。

备份做完要验证。每个季度挑一份备份,在隔离环境里恢复一遍,能打开才算数。只备份不验证的方案,本质上是薛定谔的备份——出事前你永远不知道它能不能用。这一步请务必排进日历,别指望灵感。
恢复演练听起来隆重,做起来很轻:找一台不重要的机器或者容器,导入一份最近的备份,打开看一眼能不能正常登录、照片列表是否完整。五分钟能做完的事情,每个季度做一次,换来的底气是任何宣传都给不了你的。演练时顺手记录一下恢复耗时,出事你能立刻估算出要多久才能恢复正常。
还有一个细节容易被忘:备份的保留周期。每天都覆盖同一个备份文件,等于把鸡蛋放在昨天的篮子里——如果故障是昨天发生的,备份也跟着坏了。推荐七份轮转(保留最近七天)加每月一份留档,磁盘空间几乎不增加,却把误操作的发现窗口拉长到了一个月。轮转脚本随便找一个顺手的工具都行,核心逻辑就是备份新文件、删掉超期文件,几行搞定。
| 备份对象 | 频率 | 保留份数 | 位置 |
|---|---|---|---|
| 数据库 | 每天 | 七份轮转 | 本地与异地各一 |
| 照片目录 | 每周增量 | 一两个月 | 备份盘 |
| 配置文件 | 每次改动 | 最近三份 | 随数据库备份 |
备份放在哪里也是设计的一部分。本地份保证恢复速度快,异地份保证灾难下还有底。两份都在同一块盘上等于只有一份,两份都在同一个机房等于只有一份——这个朴素的道理套在家里就是:另一块盘一份、外置硬盘或网盘一份,双保险。
对多数家庭而言最现实的组合是:本地备份盘放每周的照片增量,网盘放每天的数据库导出。数据库体积小、上传快;照片体积大、上传慢,降低频率正合适。两者都在后台静默运行,你需要做的只是季度验证。
升级前的强制备份
Immich 版本迭代频繁,小版本可以随手追,大版本必须按流程来。官方文档对每个版本间的破坏性变更都有标注,升级前花五分钟读一遍发行说明,远比升级失败后哭着恢复数据库体面。
| 版本类型 | 备份要求 | 建议节奏 |
|---|---|---|
| 小版本 | 常规备份即可 | 随手更新 |
| 大版本 | 必须完整备份 | 延后两周追 |
| 数据库迁移版本 | 提前测试 | 等社区反馈 |
数据库迁移版本要单独强调一次。这类升级涉及 postgres 的结构变更,一旦失败回滚很麻烦,社区通常会在一两天内冒出大量反馈。观望两周再动手不是胆小,是效率最高的选择——别人踩过的坑,你不必再踩一遍。

数据损坏的急救
万一真的遇到数据库起不来,先做一件事:不要重启整个机器,第一时间把现有数据库文件复制到安全位置。容器自动重启机制在你捣鼓的时候可能反复覆盖,第一时间冷冻现场比任何修复技巧都重要。
拿到现场副本之后,再去看日志、查社区。Immich 的数据库故障绝大多数能通过日志里的关键信息对照社区方案解决,最坏情况是重建数据库——照片还在、重新识别一遍,一天时间而已,不算灾难。重建数据库听着吓人,其实只是一次漫长的重新扫描,你的照片文件始终不动,这是自建架构给的底气。真正灾难性的操作是上来就删容器、删数据目录以为能重装解决,那才是把可救变成不可救。
一个 postgres 故障的案例值得分享。某用户大版本升级后数据库无法启动,慌乱之下直接删除容器和数据目录尝试重新部署,结果连旧的现场副本都失去了——一次本来可以恢复的事故变成了不可逆的数据丢失。正确的做法是第一时间停掉容器、把数据目录完整复制一份到安全位置,然后才动手操作。现场一旦被改动,修复的选项就只剩恢复和重建两种,而没有冷冻副本时,连恢复这条路也堵死了。
类似的还有一类故障来自存储而非数据库本身:盘位异常导致数据文件不完整、文件系统只读。启动日志里的信号是数据库报无法写入。这类故障先修存储层,别在应用层反复重启。
把这条流程写成一张卡片贴在机器边上并不夸张。出事的时刻通常是深夜或者升级到一半,人在慌乱中的第一反应恰恰是最危险的那几个操作。有一张写着顺序的卡片在眼前,比你当时在论坛里翻帖子快得多。

小结
数据库是 Immich 里体积最小、价值密度最高的部分:人脸分组、相册结构、修复历史都在这里,备份成本极低而丢失代价极高。三个层次的备份(文件、快照、异地)按预算推进;备份要定期验证;升级前按流程走完整备份。照片在硬盘上,安全感来自流程。
延伸阅读
- 上一章《存储规划:图库与原始文件》:备份的对象由存储规划决定。
- 《自建 NAS 完全指南》:快照工具与定时任务的系统讲法。
- 《软路由从入门到精通》:异地备份走网络时的带宽规划参考。
