迁移指南
从 pgvector 迁移到 PGVecto.rs 的完整步骤与注意事项。
PGVecto.rs 迁移概览
从 pgvector 迁移
前置条件
从 pgvector 迁移到 PGVecto.rs 时,你通常已经有一张包含 vector 类型列的表。例如:
CREATE TABLE items ( id bigserial PRIMARY KEY , embedding vector ( 3 ));
并且表中已经插入了一些数据行:
INSERT INTO items ( embedding ) VALUES ( '[1,2,3]' ), ( '[4,5,6]' );
在大多数情况下,表上还会有一个或多个向量索引:
CREATE INDEX ON items USING hnsw ( embedding vector_l2_ops );
这是使用 pgvector 时的典型场景。如果满足以下条件,即可开始迁移:
请确认你的 pgvector 扩展并未安装在 vectors Schema 中。这意味着你可以在同一个数据库中同时安装 pgvector 和 PGVecto.rs。
迁移步骤
1. 安装 PGVecto.rs
请按照安装指南 安装 PGVecto.rs,并确保 PostgreSQL 已加载该扩展。
CREATE EXTENSION vectors ;
此时,pgvector 和 PGVecto.rs 两个扩展已同时安装在 PostgreSQL 中。
要验证安装结果,请在 psql 中运行 \dx。你会看到代表 pgvector 的 vector 扩展,以及代表 PGVecto.rs 的 vectors 扩展。
postgres = # \dx
List of installed extensions
Name | Version | Schema | Description
---------+---------+------------+----------------------------------------------------------------------------------------------
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
vector | 0.7.2 | public | vector data type and ivfflat and hnsw access methods
vectors | 0.3.0 | vectors | vectors: Vector database plugin for Postgres, written in Rust, specifically designed for LLM
请注意,这两个扩展中存在一些同名的类型和符号,这可能会在迁移过程中引起混淆。为了区分二者,请先确认当前的 search_path 中不包含 PGVecto.rs 的 vectors Schema:
SHOW search_path ;
-- 如果显示为:`"$user", public` -> 正常
-- 如果显示为:`"$user", public, vectors` -> 请通过以下命令移除 `vectors`:
SET search_path = "$user, public" ;
2. 检查现有索引
对于在向量列上创建的索引,请先查询其定义并记录下来,以便在后续阶段重建索引。
postgres =# SELECT indexdef FROM pg_indexes WHERE tablename = 'items' ;
indexdef
---------------------------------------------------------------------------------------
CREATE UNIQUE INDEX items_pkey ON public . items USING btree ( id )
CREATE INDEX items_embedding_idx ON public . items USING hnsw ( embedding vector_l2_ops )
( 2 rows )
3. 迁移向量列
要迁移 pgvector 的向量列,第一步是创建一个对应类型的 PGVecto.rs 向量列,第二步是将原列中的向量数据复制到新列中。
以下是 pgvector 各向量类型的转换路径:
vector(pgvector) -> real[] -> vector(PGVecto.rs)
halfvec -> vector(pgvector) -> real[] -> vector(PGVecto.rs) -> vecf16
bit -> text[] -> real[] -> vector(PGVecto.rs) -> bvector
目前暂不支持迁移以下向量类型:
方法一:先验证再替换
使用此方法,你可以在迁移过程中检查向量数据的正确性,而且无需担心原向量列上已创建的索引(在删除原列时索引会自动删除)。
但这种方法需要额外的存储空间来同时保存迁移前后的向量数据。
警告
此步骤会导致一定的停机时间,原因包括:
ALTER TABLE ADD COLUMN 会获取短暂的 ACCESS EXCLUSIVE 锁
UPDATE 会持有较长时间的 ROW EXCLUSIVE 锁
ALTER TABLE DROP COLUMN 会获取短暂的 ACCESS EXCLUSIVE 锁
-- 从 vector 类型转换
ALTER TABLE items ADD COLUMN migrate_embedding vectors . vector ( 3 );
UPDATE items SET migrate_embedding = embedding :: real []:: vectors . vector ;
-- 从 halfvec 类型转换
ALTER TABLE items ADD COLUMN migrate_embedding vectors . vecf16 ( 3 );
UPDATE items SET migrate_embedding = embedding :: vector :: real []:: vectors . vector :: vectors . vecf16 ;
-- 从 bit 类型转换
ALTER TABLE items ADD COLUMN migrate_embedding vectors . bvector ( 3 );
UPDATE items SET migrate_embedding = string_to_array ( embedding :: text , NULL ):: real []:: vectors . vector :: vectors . bvector ;
数据复制完成后,你可以通过 SELECT 检查数据,然后用新列替换旧列:
ALTER TABLE items DROP COLUMN embedding ;
ALTER TABLE items RENAME COLUMN migrate_embedding TO embedding ;
方法二:原地转换(无需额外存储空间)
使用此方法,可以在一条命令内完成列类型转换,无需占用额外的列存储空间。
但你需要提前手动删除该向量列上的索引。
警告
此步骤会导致一定的停机时间,原因包括:
ALTER TABLE ALTER COLUMN 会持有较长时间的 ACCESS EXCLUSIVE 锁
-- 索引名称来自第 2 步的查询结果
DROP INDEX IF EXISTS items_embedding_idx ;
-- 从 vector 类型转换
ALTER TABLE items ALTER COLUMN embedding TYPE vectors . vector ( 3 ) USING embedding :: real []:: vectors . vector ;
-- 从 halfvec 类型转换
ALTER TABLE items ALTER COLUMN embedding TYPE vectors . vecf16 ( 3 ) USING embedding :: vector :: real []:: vectors . vector :: vectors . vecf16 ;
-- 从 bit 类型转换
ALTER TABLE items ALTER COLUMN embedding TYPE vectors . bvector ( 3 ) USING string_to_array ( embedding :: text , NULL ):: real []:: vectors . vector :: vectors . bvector ;
4. 重建索引
要为 PGVecto.rs 的 vector 列重建索引,可以开启兼容模式 并直接执行之前的索引创建语句:
SET vectors . pgvector_compatibility = on ;
-- 执行第 2 步中记录的命令
CREATE INDEX items_embedding_idx ON public . items USING hnsw ( embedding vector_l2_ops );
对于其他向量类型(如 halfvec、sparsevec 和 bit),请参考索引指南 重新创建索引。目前 pgvector_compatibility 兼容模式暂不支持这些类型。
5. 清理环境
如果不再需要 pgvector 扩展,现在可以安全地将其卸载:
卸载 pgvector 扩展后,建议重新设置 search_path,以确保可以在全局直接访问 PGVecto.rs 中的符号:
SET search_path = "$user, public, vectors" ;
-- 或在全局级别设置
ALTER SYSTEM SET search_path = "$user, public, vectors" ;
验证结果
迁移任务执行完毕后,你可以通过 SELECT 语句验证新列的数据与类型:
SELECT embedding , pg_typeof ( "embedding" ) from items limit 3 ;
-- embedding | pg_typeof
-------------+----------------
-- [1, 2, 3] | vectors.vector
-- [4, 5, 6] | vectors.vector