Immich 从 PostgreSQL 16 迁移到 PostgreSQL 18

作者:

适用版本

  • Immich v3.x
  • Unraid
  • PostgreSQL 16(pgvecto-rs)
  • PostgreSQL 18(官方 Vector + VChord)

本文记录了一条经过实际验证成功的迁移方案。整个过程采用官方 PostgreSQL 18 数据库,将旧版 pgvecto-rs 数据库迁移到新版 Vector + VChord 数据库,同时完整保留用户、照片、相册、标签等数据。(chatgpt 生成!!!)


前言

升级 Immich v3 后,很多用户都会遇到数据库无法启动的问题,例如:

Error: No vector extension found.
Available extensions: vchord, vector

或者:

Detected schema drift

产生这些问题的根本原因是:

Immich v3 已经放弃了 pgvecto-rs,改用了 pgvector + VChord

也就是说:

Immich 旧版本Immich v3
vectors(pgvecto-rs)vector(pgvector)
PostgreSQL 16PostgreSQL 18
tensorchord/pgvecto-rsghcr.io/immich-app/postgres

因此,直接升级容器通常无法正常启动,需要迁移数据库。

本文最终实现的效果

迁移完成后,可以保留:

  • 所有照片
  • 所有视频
  • 所有用户
  • 所有相册
  • 所有标签
  • 所有收藏
  • 所有分享
  • 所有 Memories
  • 数据库升级到 PostgreSQL 18

AI 数据(人脸识别、智能搜索)会重新建立索引,不影响照片数据。

恢复数据库到 PostgreSQL 18

完成数据库导出后,就可以开始恢复到新的 PostgreSQL 18 数据库。

整个恢复过程分为四个步骤:

  1. 创建新的 PostgreSQL 18 数据库
  2. 删除旧扩展信息
  3. 恢复数据库
  4. 验证恢复结果

创建 PostgreSQL 18

首先,在 Unraid 中安装新的 PostgreSQL 18 容器。

建议不要覆盖旧数据库,而是使用新的数据目录,例如:

/mnt/user/appdata/PostgreSQL_Immich18

数据库镜像:

ghcr.io/immich-app/postgres:18-vectorchord

容器名称:

Immich_PostgreSQL

启动后,进入数据库:

docker exec -it Immich_PostgreSQL psql -U postgres

查看数据库:

\l

应该可以看到:

 immich
 postgres
 template0
 template1

如果没有 immich,可以创建:

CREATE DATABASE immich;

退出:

\q

检查新版数据库扩展

进入新数据库:

docker exec -it Immich_PostgreSQL \
psql -U postgres -d immich

查看扩展:

\dx

正常应该包含:

cube
earthdistance
pg_trgm
uuid-ossp
vector
vchord

其中最重要的是:

vector
vchord

说明数据库已经满足 Immich v3 的要求。

退出:

\q

将备份复制到容器

恢复之前,将备份复制到 PostgreSQL 容器:

docker cp /mnt/user/immich_no_vectors.dump \
Immich_PostgreSQL:/tmp/

复制成功后,开始生成恢复列表。


生成恢复对象列表

执行:

docker exec PostgreSQL_Immich \
pg_restore -l /tmp/immich_no_vectors.dump \
> /mnt/user/immich.list

这里生成的是整个备份文件的目录。

不要直接恢复。

原因是里面仍然包含旧版 vectors 扩展。


删除 vectors 相关对象

复制一份恢复列表:

cp /mnt/user/immich.list \
/mnt/user/immich_filtered.list

删除所有 vectors 内容:

sed -i '/vectors/d' \
/mnt/user/immich_filtered.list

同时删除 AI 搜索表:

sed -i '/face_search/d' \
/mnt/user/immich_filtered.list

sed -i '/smart_search/d' \
/mnt/user/immich_filtered.list

检查是否已经删除:

grep -Ei "vectors|face_search|smart_search" \
/mnt/user/immich_filtered.list

如果没有任何输出:

(无输出)

说明过滤成功。


将过滤后的文件复制到 PostgreSQL 18

复制:

docker cp /mnt/user/immich_filtered.list \
Immich_PostgreSQL:/tmp/

恢复文件如果尚未复制,也一起复制:

docker cp /mnt/user/immich_no_vectors.dump \
Immich_PostgreSQL:/tmp/

开始恢复数据库

执行:

docker exec Immich_PostgreSQL \
pg_restore \
-L /tmp/immich_filtered.list \
-U postgres \
-d immich \
/tmp/immich_no_vectors.dump

整个恢复过程中一般不会有输出。

恢复完成后返回:

root@Tower:~#

表示恢复成功。


验证数据库恢复

进入数据库:

docker exec -it Immich_PostgreSQL \
psql -U postgres -d immich

查看数据表:

\dt

应该看到六十多个表,例如:

asset
album
person
memory
library
workflow
user
tag
plugin
video_stream_session
...

说明业务数据已经恢复。

退出:

\q

验证数据数量

检查照片数量:

docker exec -it Immich_PostgreSQL \
psql -U postgres -d immich \
-c "SELECT count(*) FROM asset;"

例如:

 count
-------
23600

再检查用户:

docker exec -it Immich_PostgreSQL \
psql -U postgres -d immich \
-c "SELECT count(*) FROM \"user\";"

例如:

 count
-------
2

如果这些数量与旧数据库一致,就说明迁移成功。


启动 Immich

确认 Immich 连接的是新的 PostgreSQL:

docker exec immich env | grep DB_

例如:

DB_HOSTNAME=<IP地址>
DB_DATABASE_NAME=immich
DB_USERNAME=postgres
DB_PORT=5432

确认无误后,启动 Immich。

第一次启动时,很可能会出现:

Detected schema drift

以及:

face_search is missing
clip_index does not exist

不要紧张。

这是因为新版数据库没有旧版 AI 向量表。

属于正常现象。

下一部分将介绍如何使用 immich-admin schema-check 自动修复数据库结构,并重新创建 face_searchsmart_searchface_indexclip_index,最终使 Immich 正常启动。

修复数据库结构并完成迁移

完成数据库恢复后,Immich 已经能够读取数据库中的绝大部分业务数据,但第一次启动时通常仍然无法正常运行。

这是因为在导出数据库时,我们主动移除了旧版 AI 向量数据,因此新版数据库缺少了 AI 搜索相关的数据表。

这一步只需要重新创建这些数据表即可。


第一次启动 Immich

启动 Immich 后,可以查看日志:

docker logs -f immich

正常情况下会看到类似输出:

Running migrations
Finished running migrations
Checking for schema drift

随后可能出现:

Detected schema drift

并提示:

The table "face_search" is missing

The table "smart_search" is missing

The index "face_index" is missing

The index "clip_index" is missing

紧接着 Immich 会退出,并出现:

relation "clip_index" does not exist

这是迁移过程中最容易让人误以为失败的一步。

实际上,这是正常现象

因为我们恢复的是业务数据,而没有恢复旧版 AI 向量数据库。


使用 schema-check 检查数据库

Immich 已经提供了自动检查工具。

执行:

docker exec -it immich immich-admin schema-check

如果数据库正常,会看到:

Migrations are up to date

随后输出:

Detected schema drift

例如:

TableCreate:
face_search

IndexCreate:
face_index

TableCreate:
smart_search

IndexCreate:
clip_index

最下面还会自动生成 SQL。

例如:

CREATE TABLE "face_search" (
...
);

CREATE INDEX "face_index" ...

CREATE TABLE "smart_search" (
...
);

CREATE INDEX "clip_index" ...

这些 SQL 正是我们需要执行的内容。


执行 schema-check 生成的 SQL

进入 PostgreSQL:

docker exec -it Immich_PostgreSQL \
psql -U postgres -d immich

把 schema-check 输出的 SQL 完整复制进去执行

执行完成后会看到类似输出:

CREATE TABLE

CREATE INDEX

CREATE TABLE

ALTER TABLE

CREATE INDEX

说明数据库已经修复完成。

退出:

\q

再次启动 Immich

重新启动 Immich:

docker restart immich

查看日志:

docker logs -f immich

正常情况下可以看到:

Running migrations

Finished running migrations

Checking for schema drift

随后:

Nest application successfully started

最后:

Immich Server is listening on http://127.0.0.1:8080

说明服务器已经正常启动。

如果同时看到:

Application startup complete

以及:

Starting microservices worker

则说明整个 Immich 服务已经恢复正常。


登录 Immich

浏览器访问:

http://服务器IP:2283

登录后建议首先检查:

  • 是否能够正常登录
  • 用户是否存在
  • 相册是否存在
  • Memories 是否正常
  • 标签是否正常
  • 收藏是否正常
  • 分享链接是否正常

如果这些都正常,说明数据库迁移已经成功。


重新建立 AI 搜索索引

由于旧版 vectors 数据没有迁移,因此:

  • 人脸识别
  • 智能搜索(CLIP)
  • 人物搜索

都会重新建立索引。

进入:

Administration

打开:

Jobs

依次运行:

Generate Thumbnails

Generate CLIP Embeddings

Facial Recognition

Smart Search

根据照片数量不同,整个过程可能需要数小时。

等待任务全部完成即可。


清理旧数据库

确认新数据库已经稳定运行几天后,就可以删除旧数据库。

停止旧 PostgreSQL:

docker stop PostgreSQL_Immich

删除容器:

docker rm PostgreSQL_Immich

如果确认不会再回退,可以删除旧数据库目录:

/mnt/user/appdata/PostgreSQL_Immich

建议至少保留一周备份后再删除。


建议重新备份 PostgreSQL 18

迁移完成后,建议立即备份新的数据库。

执行:

docker exec Immich_PostgreSQL \
pg_dump \
-U postgres \
-Fc \
immich \
> /mnt/user/immich_pg18_backup.dump

以后恢复时,直接使用这个备份即可,无需再次处理 vectors 扩展。


常见问题

1. No vector extension found

原因:

旧数据库仍然使用 vectors 扩展。

解决:

迁移到 PostgreSQL 18,并恢复到 vector + vchord 数据库。


2. extension “vectors” is not available

原因:

恢复了旧数据库中的 CREATE EXTENSION vectors

解决:

使用 pg_restore -l 生成恢复列表,并删除所有包含 vectors 的条目。


3. relation “clip_index” does not exist

原因:

AI 搜索数据表未创建。

解决:

运行:

docker exec -it immich immich-admin schema-check

执行其自动生成的 SQL。


4. Detected schema drift

原因:

数据库结构与当前 Immich 版本不一致。

解决:

按照 schema-check 提供的 SQL 修复即可。


迁移总结

本次迁移最终采用了以下路线:

PostgreSQL 16
        │
        ▼
导出数据库(排除 AI 向量表)
        │
        ▼
删除 vectors 扩展信息
        │
        ▼
恢复到 PostgreSQL 18
        │
        ▼
schema-check 修复数据库结构
        │
        ▼
Immich 正常启动
        │
        ▼
重新建立 AI 搜索索引

整个过程中,照片、视频、用户、相册、标签等业务数据全部保留,仅重新生成了 AI 向量索引。

实践证明,这是一条稳定、可靠且易于复现的迁移方案。


后记

这次迁移过程中,一个重要的经验是:

数据库迁移最重要的不是尝试很多方案,而是确定一条正确的路线,并坚持执行到底。

中途频繁切换方案,容易引入新的问题,也会浪费大量时间。

最终采用的方案——导出业务数据 → 删除旧版 vectors 扩展对象 → 恢复到 PostgreSQL 18 → 使用 schema-check 修复数据库结构——顺利完成了整个迁移过程,也为今后的升级提供了一条清晰、可复用的路径。

希望本文能够帮助遇到同样问题的用户少走弯路,顺利完成 Immich 数据库升级。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注