accounts/docs/pg-vector-db-init.md

353 lines
11 KiB
Markdown
Raw Normal View History

# PostgreSQL + pgvector 初始化指南
本文档介绍在 macOS 上初始化 PostgreSQL 并启用 [pgvector](https://github.com/pgvector/pgvector) 扩展,以便项目的向量检索功能正常运行。
## 3. 安装并启用 pg 扩展
1. 安装 pgvector zhparser
brew install make cmake scws pgvector postgresql
export PATH="/opt/homebrew/opt/postgresql@14/bin:$PATH"
git clone https://github.com/amutu/zhparser.git
cd zhparser
# 确保使用的是你刚才设置的 pg_config 所在版本
make clean
make SCWS_HOME=/opt/homebrew \
PG_CONFIG=/opt/homebrew/opt/postgresql@14/bin/pg_config
sudo make install SCWS_HOME=/opt/homebrew \
PG_CONFIG=/opt/homebrew/opt/postgresql@14/bin/pg_config
2025-08-13 14:53:32 +08:00
2. (重新)启动 PostgreSQL 以加载扩展:
```bash
2025-08-13 14:53:32 +08:00
brew services restart postgresql
## 初始化数据库集群
## macOS vs Ubuntu 22.04 初始化对比
**安装好 `postgresql-14-pgvector` 与 `zhparser`** 之后,数据库内部的操作基本一致。区别主要在环境与服务管理方式。下面分为 **差异部分****公共部分**
---
### 🟡 差异部分(环境相关)
这些仅影响数据库服务启动和工具链SQL 操作不变。
| 项目 | macOS | Ubuntu 22.04 |
|------|-------|--------------|
| **服务管理** | `brew services start/stop/restart postgresql` | `sudo systemctl start/stop/restart postgresql` |
| **数据目录** | 常见为 `/opt/homebrew/var/postgres`,需手动 `initdb` 初始化 | 安装包自动初始化,默认 `/var/lib/postgresql/14/main` |
| **pg_config 路径**(编译 zhparser 用) | `/opt/homebrew/opt/postgresql@14/bin/pg_config` | `/usr/lib/postgresql/14/bin/pg_config` |
| **环境变量** | 需手动 `export PATH="/opt/homebrew/opt/postgresql@14/bin:$PATH"` | 通常无需设置APT 安装自动在 PATH 中 |
---
### 🟢 公共部分(数据库操作相同)
无论 macOS / Ubuntu只要 PostgreSQL 与扩展安装完成,以下数据库操作完全一致。
1. **切换到 postgres 管理员账号**
```bash
sudo -u postgres psql
创建业务用户和数据库
sql
复制
编辑
-- 创建用户(若已存在可跳过)
CREATE USER shenlan WITH PASSWORD '你的密码';
-- 创建业务数据库,并指定所有者
CREATE DATABASE shenlan OWNER shenlan;
-- 给用户赋权限(可选)
GRANT ALL PRIVILEGES ON DATABASE shenlan TO shenlan;
在业务数据库中启用扩展
sql
复制
编辑
\c shenlan -- 切换到业务库
-- 启用向量扩展
CREATE EXTENSION IF NOT EXISTS vector;
-- 启用中文分词扩展(可选)
CREATE EXTENSION IF NOT EXISTS zhparser;
导入初始化 SQL例如 rag-server/sql/schema.sql psql -h 127.0.0.1 -U shenlan -d shenlan -f rag-server/sql/schema.sql
验证扩展与表结构
psql -h 127.0.0.1 -U shenlan -d shenlan -c "\d+ documents"
若能看到字段:
nginx
复制
编辑
embedding | vector(1024)
说明 pgvector 已成功启用。
2025-08-13 14:53:32 +08:00
1. 停止可能运行的 PostgreSQL 服务,避免与初始化过程冲突:
brew services stop postgresql
```
2. 初始化数据目录并创建超级用户,这里以 `shenlan` 为例:
```bash
initdb /opt/homebrew/var/postgres -U shenlan -W
2025-08-13 14:53:32 +08:00
- `-U` 指定初始化时创建的超级用户名称,可根据需要替换为其它名字(如 `postgres`)。
- `-W` 会提示输入该用户的密码。
## 2. 启动服务并创建业务数据库
2025-08-13 14:53:32 +08:00
1. 启动 PostgreSQL 服务:
```bash
brew services start postgresql
```
2025-08-13 14:53:32 +08:00
2. 使用初始化时创建的用户连接到默认的 `postgres` 数据库(用一个有权限的用户登录 Linux通常是 postgres 管理员)
psql -h 127.0.0.1 -U shenlan -d postgres
```
3.`psql` 中创建业务数据库(例如 `mydb`
2025-08-13 14:53:32 +08:00
CREATE DATABASE mydb;
```
2025-08-13 14:53:32 +08:00
4. 创建数据库和用户(如果还没有)
2025-08-13 14:53:32 +08:00
-- 创建用户(如果已存在可跳过)
CREATE USER shenlan WITH PASSWORD '你的密码';
-- 创建数据库并指定所有者
CREATE DATABASE shenlan OWNER shenlan;
-- 给用户赋权限(可选)
GRANT ALL PRIVILEGES ON DATABASE shenlan TO shenlan;
5. 在目标数据库中启用扩展:
启用 pgvector 扩展psql -h 127.0.0.1 -U shenlan -d shenlan -c "CREATE EXTENSION IF NOT EXISTS vector;"
启用 zhparser 扩展psql -h 127.0.0.1 -U shenlan -d shenlan -c "CREATE EXTENSION zhparser;"
```
2025-08-13 14:53:32 +08:00
6. 导入项目提供的初始化脚本
项目在 `rag-server/sql/schema.sql` 中提供了建表及索引脚本,可通过 `psql` 导入:
```bash
2025-08-13 14:53:32 +08:00
退出再用 shenlan 用户运行 init.sql
psql -h 127.0.0.1 -U shenlan -d shenlan -f rag-server/sql/schema.sql
```
该脚本会:
2025-08-13 14:00:57 +08:00
- 创建 `vector``zhparser` 扩展(如未启用)。
- 定义混合中文/英文的全文搜索配置 `zhcn_search`
- 创建 `documents` 表,并包含:
- 预计算 `doc_key` 生成列repo:path:chunk_id
- `content_tsv` 生成列支持中文/英文全文检索。
- `embedding` VECTOR(1024) 字段适配 BGE-M3。
- 建立 `HNSW` 向量索引、`GIN` 全文索引以及 `(repo, path)` 复合索引。
### 示例UPSERT 与 Hybrid 检索
插入或更新文档:
```sql
INSERT INTO public.documents (
repo, path, chunk_id, content, embedding, metadata, content_sha
) VALUES (
'docs', 'README.md', 1, '内容...', '[...]', '{}', 'abc123'
)
ON CONFLICT (doc_key) DO UPDATE
SET
content = EXCLUDED.content,
embedding = EXCLUDED.embedding,
metadata = EXCLUDED.metadata,
content_sha = EXCLUDED.content_sha,
updated_at = now();
```
Hybrid 检索:
```sql
SELECT *
FROM public.documents
WHERE content_tsv @@ to_tsquery('zhcn_search', '大模型 & 应用')
AND embedding IS NOT NULL
ORDER BY embedding <#> '[...]'
LIMIT 5;
```
## 5. 测试连接
确认数据库与扩展均正常工作:
```bash
psql postgres://shenlan:<密码>@127.0.0.1:5432/mydb -c "\d+ documents"
```
若能看到 `embedding | vector(1024)` 字段,说明 pgvector 已成功启用。
完成以上步骤后,应用即可通过连接串 `postgres://shenlan:<密码>@127.0.0.1:5432/mydb` 使用数据库。
2025-08-10 10:30:06 +08:00
## 6. 配置嵌入服务
`rag-server/config/server.yaml` 中新增 `embedding` 配置,使服务端能够对问题进行向量化检索:
2025-08-10 10:30:06 +08:00
```yaml
global:
embedding:
base_url: http://127.0.0.1:11434
token: ""
dimension: 1536
```
其中 `dimension` 需与所使用的嵌入模型返回的向量维度一致。
# 常用检查命令
- 查看总条数: SELECT COUNT(*) FROM documents;
- 查看前几条数据 SELECT * FROM documents LIMIT 5;
- 只看主要字段 SELECT id, repo, path, chunk_id FROM documents LIMIT 10;
- 查看嵌入向量的维度 SELECT id, vector_dims(embedding) AS dims FROM documents LIMIT 5;
- 确认带向量的记录 SELECT COUNT(*) FROM public.documents WHERE embedding IS NOT NULL;
- 查看向量维度
SELECT id, vector_dims(embedding) AS dims
FROM public.documents
WHERE embedding IS NOT NULL
LIMIT 5;
vector_dims() 是 pgvector 提供的函数
查看全部(注意可能很长)
SELECT content
FROM public.documents;
2. 只看前几条
SELECT id, content
FROM public.documents
LIMIT 5;
3. 只看前 80 个字符(避免太长)
SELECT id, LEFT(content, 80) AS preview
FROM public.documents
LIMIT 5;
这样会输出 content 的前 80 个字符,方便快速浏览。
4. 随机抽查几条
SELECT id, LEFT(content, 80) AS preview
FROM public.documents
ORDER BY random()
LIMIT 5;
5. 同时查看 embedding 维度和 content
SELECT id,
vector_dims(embedding) AS dims,
LEFT(content, 80) AS preview
FROM public.documents
ORDER BY random()
LIMIT 5;
这样能一次确认:
向量维度(是不是 1024
文本内容大致是什么
2) 本地导出(建议用自定义格式,便于并行恢复)
自定义格式(.dump
# 生成压缩备份文件(包含结构+数据)
pg_dump -h 127.0.0.1 -U shenlan -d shenlan \
-Fc -Z 6 \
-f shenlan_$(date +%F).dump
大库可用目录格式 + 并行导出:
pg_dump -h 127.0.0.1 -U shenlan -d shenlan \
-Fd -j 4 -Z 0 \
-f shenlan_dumpdir/
3) 传输到远端
scp shenlan_2025-08-16.dump user@REMOTE_HOST:/tmp/
# 或scp -r shenlan_dumpdir/ user@REMOTE_HOST:/tmp/
4) 远端恢复
# 清理并恢复(避免 owner/privileges 冲突,按需去掉 --clean
pg_restore -h REMOTE_HOST -U shenlan -d shenlan \
--clean --if-exists --no-owner --no-privileges \
/tmp/shenlan_2025-08-16.dump
目录格式可并行恢复:
pg_restore -h REMOTE_HOST -U shenlan -d shenlan \
--clean --if-exists --no-owner --no-privileges \
-j 4 /tmp/shenlan_dumpdir/
5) 验证
psql -h REMOTE_HOST -U shenlan -d shenlan -c "\d+ public.documents"
psql -h REMOTE_HOST -U shenlan -d shenlan -c "SELECT COUNT(*) FROM public.documents;"
psql -h REMOTE_HOST -U shenlan -d shenlan -c "SELECT vector_dims(embedding) FROM public.documents WHERE embedding IS NOT NULL LIMIT 1;"
方案 B不落地文件的「管道直传」
边导出边导入,省去中间文件;网络稳定时很好用。
自定义格式 + 远端 pg_restore
pg_dump -h 127.0.0.1 -U shenlan -d shenlan -Fc \
| ssh user@REMOTE_HOST "pg_restore -U shenlan -d shenlan --clean --if-exists --no-owner --no-privileges"
SQL 文本直灌(更通用,但不可并行):
pg_dump -h 127.0.0.1 -U shenlan -d shenlan -x -O \
| psql -h REMOTE_HOST -U shenlan -d shenlan
-x 去掉权限语句;-O 去掉 OWNER 语句,避免远端角色不一致时报错。
(可选)角色/权限全局对象同步
如果你需要把角色、默认权限一起迁过去(不仅仅是库内容),先在本地导出「全局对象」,再在远端导入:
# 本地导出全局(角色等),需要有 postgres 超级用户
pg_dumpall -h 127.0.0.1 -U postgres --globals-only > globals.sql
# 远端导入(同样需要超级用户)
psql -h REMOTE_HOST -U postgres -f globals.sql
若仅用同一个业务用户(如 shenlan且远端已手动创建并授权这步可以省略。
小贴士 / 排障
扩展要先装:远端必须已安装 pgvector、zhparser 包且能 CREATE EXTENSION否则恢复视图/索引会失败。
版本兼容pg_dump → pg_restore 支持跨小版本恢复;主版本跨越(如 PG13 → PG14通常没问题但推荐目标版本 ≥ 源版本。
性能优化(恢复时):
临时关闭同步提交ALTER SYSTEM SET synchronous_commit = off;(或会话级)
增大维护内存SET maintenance_work_mem='1GB';
并行恢复pg_restore -j N -Fd
恢复后 ANALYZE; REINDEX 以优化查询
连接/网络:
远端 pg_hba.conf 放行你的 IPhost … md5/scram
防火墙开放 5432ufw allow 5432/tcp
最省事:如果只是「把本地覆盖到远端」且不在乎中间文件:
pg_dump -h 127.0.0.1 -U shenlan -d shenlan -Fc \
| ssh user@REMOTE_HOST "dropdb -U shenlan --if-exists shenlan && createdb -U shenlan shenlan && \
psql -U shenlan -d shenlan -c \"CREATE EXTENSION IF NOT EXISTS vector; CREATE EXTENSION IF NOT EXISTS zhparser;\" && \
pg_restore -U shenlan -d shenlan --no-owner --no-privileges"
需要的话我可以根据你的远端连接串(域名/端口/用户名)和数据规模,帮你生成一键脚本(含并行度和恢复优化参数)。