1. 为什么我要从源码开始折腾PG15和pgvector?
大家好,我是老张,在AI和数据库这块摸爬滚打了十来年。今天想和大家聊聊一个非常具体,但很多朋友在实际部署时都会头疼的问题:从零开始,手动编译PostgreSQL 15,并给它装上强大的向量搜索插件pgvector。
你可能会问,现在云服务那么方便,Docker镜像一键部署,为啥还要自己折腾源码编译?这事儿我深有体会。去年我们团队接手一个项目,客户环境是内网隔离的国产化服务器,操作系统版本比较老,官方仓库里的PostgreSQL版本太低,根本用不了pgvector。那时候,从源码编译就成了唯一的选择。这个过程里,我踩了不少坑,也积累了一手实战经验。今天,我就把这些经验掰开了、揉碎了,分享给你。目标就一个:让你看完就能动手,动手就能成功,避开我当年遇到的那些“暗礁”。
简单来说,我们今天要干两件大事:
- 从源码编译安装PostgreSQL 15:就像自己组装一台电脑,从最基础的零件开始,完全掌控它的配置和性能。
- 编译并安装pgvector插件:给这台“电脑”装上最强大的“显卡”,让它具备处理AI向量数据的能力,能做相似性搜索、推荐这些酷炫的功能。
无论你是需要在特定Linux发行版(比如一些老版本或定制化系统)上部署,还是想深度定制PostgreSQL的参数,或者单纯想学习数据库的构建过程,这篇指南都会是你的得力助手。咱们不搞虚的,直接上命令、讲原理、说坑点。
2. 稳扎稳打:编译前的环境与依赖准备
编译软件,尤其是像PostgreSQL这样的大型数据库系统,第一步也是最关键的一步,就是把环境准备好。这就像盖房子前要打好地基、备齐建材。很多编译失败的问题,八成都是出在依赖没装全或者版本不对上。
2.1 系统环境检查与依赖全家桶
首先,咱们得知道自己站在什么“土地”上。打开终端,先看看系统信息:
cat /etc/os-release
uname -r
我这次演示的环境是一个KylinOS(类似CentOS)的服务器。记住你的系统版本,因为不同发行版的包管理命令和软件包名可能略有不同。
接下来,就是安装编译所需的“全家桶”依赖。这些工具和库,有的是编译器(比如gcc),有的是函数库(比如readline, zlib),少了谁,configure或make的时候都会报错。
对于基于RPM/YUM的系统(如CentOS, Rocky Linux, Fedora, KylinOS),执行下面这条命令:
sudo yum install -y gcc gcc-c++ make readline-devel zlib-devel perl-ExtUtils-Embed pam-devel libxml2-devel libxslt-devel openldap-devel python3-devel openssl-devel cmake
对于基于APT/DEB的系统(如Ubuntu, Debian),命令是这样的:
sudo apt-get update
sudo apt-get install -y gcc g++ make libreadline-dev zlib1g-dev libpam0g-dev libxml2-dev libxslt1-dev libldap2-dev python3-dev libssl-dev cmake
这里有几个坑点我特别提醒一下:
perl-ExtUtils-Embed:这个包在PostgreSQL编译某些PL/Perl功能时需要。在Debian系里,它可能叫libperl-dev。如果编译时提示Perl相关错误,记得检查这个。python3-devel:现在Python2基本淘汰了,一定要装Python3的开发包。PostgreSQL的PL/Python插件需要它。cmake:这个不是编译PostgreSQL本身必需的,但是编译pgvector插件时必须用到。所以咱们提前一并装上,免得后面手忙脚乱。
把这些依赖都装齐了,就相当于你的“施工队”和“建筑材料”全部到位,可以开工了。
2.2 获取PostgreSQL与pgvector源码
依赖搞定,接下来下载“图纸”——源码包。我强烈建议从官方渠道下载,安全、稳定。
下载PostgreSQL 15源码: 目前最新的稳定版是15.8,我们直接使用wget下载。如果服务器网络环境特殊,你可能需要先通过其他方式下载好,再上传到服务器。
wget https://ftp.postgresql.org/pub/source/v15.8/postgresql-15.8.tar.gz
下载完成后,验证一下文件的完整性(可选但推荐):
md5sum postgresql-15.8.tar.gz
# 或者
sha256sum postgresql-15.8.tar.gz
你可以去 PostgreSQL官网 核对公布的校验值。
下载pgvector插件源码: pgvector的源码托管在GitHub上。同样,我们下载其发布版本(tag),这样更稳定。
wget https://github.com/pgvector/pgvector/archive/refs/tags/v0.7.4.tar.gz -O pgvector-v0.7.4.tar.gz
这里我用了 -O 参数指定了下载后的文件名,更清晰。pgvector的版本迭代很快,写这篇文章时最新是v0.7.4,你可以去其 GitHub Releases页面 查看是否有更新版本。
两个源码包都下载好后,我们创建一个专门的工作目录,把它们都放进去,方便管理:
mkdir -p ~/pg_build
mv postgresql-15.8.tar.gz pgvector-v0.7.4.tar.gz ~/pg_build/
cd ~/pg_build
3. 庖丁解牛:PostgreSQL 15源码编译与安装
现在,我们进入核心环节——编译安装PostgreSQL。这个过程分为配置、编译、安装三步,每一步都有一些可以优化的细节。
3.1 解压、配置与编译优化
首先解压PostgreSQL源码包:
tar zxvf postgresql-15.8.tar.gz
cd postgresql-15.8
解压后,先别急着配置。我建议创建一个独立的目录来存放编译的中间文件(影子构建),这样保持源码目录的干净,也方便后续清理。但为了简单直观,我们这次直接在源码目录进行。
运行 ./configure 脚本。这是最关键的一步,它负责检查你的系统环境,并生成适合的Makefile。我们可以通过参数进行定制:
./configure --prefix=/opt/pgsql/15.8 \
--with-openssl \
--with-libxml \
--with-libxslt \
--with-pam \
--with-ldap \
--with-perl \
--with-python \
--enable-debug
我来解释一下这几个常用参数:
--prefix=/opt/pgsql/15.8:指定安装目录。我习惯把不同版本的PG装到/opt/pgsql/下的子目录,方便多版本共存和管理。这个目录你可以自由修改,但后面所有相关路径都要跟着变。--with-xxx:启用各种扩展功能。比如--with-openssl支持SSL连接,--with-python启用PL/Python过程语言。你可以根据需求增减。如果不需要,去掉对应参数可以加快编译速度。--enable-debug:这个参数请谨慎使用。它会在二进制文件中加入调试信息,方便开发人员排查问题,但会显著增大文件体积并影响性能。生产环境千万不要加。
配置过程会输出一大堆检查信息。只要最后没有出现明显的 error,看到 config.status: creating Makefile 之类的成功提示,就可以进行下一步。
接下来是编译,使用 make 命令。为了加快速度,我们可以使用 -j 参数指定并行编译的作业数,通常是你的CPU核心数:
make -j$(nproc)
$(nproc) 会自动获取你系统的CPU核心数。编译过程视机器性能而定,可能需要十几分钟到半小时。期间如果报错,大概率是前面依赖没装全,根据错误信息回头去补装即可。
3.2 安装、目录结构与用户权限
编译成功后,就可以安装了:
sudo make install
这里需要sudo权限,因为我们要向/opt/pgsql/15.8这个系统目录写入文件。安装完成后,进入安装目录看看:
ls -lh /opt/pgsql/15.8/
你会看到 bin, lib, share, include 等标准目录。bin目录下就是我们要用的psql、pg_ctl等可执行文件。
PostgreSQL为了安全,默认不允许用root身份运行。所以我们需要创建一个专用的系统用户和用户组:
sudo groupadd postgres
sudo useradd -r -g postgres -s /bin/bash -d /var/lib/pgsql postgres
-r:创建系统用户。-d /var/lib/pgsql:指定用户的家目录,这里我们用来放数据目录。
接着,创建数据目录并赋予权限。数据目录是存放所有数据库文件的地方,非常重要。
sudo mkdir -p /opt/pgsql/15.8/data
sudo chown -R postgres:postgres /opt/pgsql/15.8/data
sudo chmod 700 /opt/pgsql/15.8/data # 确保只有postgres用户能访问
最后,为了方便使用,我们把PostgreSQL的bin目录添加到系统的PATH环境变量中。编辑postgres用户的~/.bashrc文件(或者~/.bash_profile):
sudo su - postgres
echo 'export PATH=/opt/pgsql/15.8/bin:$PATH' >> ~/.bashrc
echo 'export PGDATA=/opt/pgsql/15.8/data' >> ~/.bashrc # 设置默认数据目录变量
source ~/.bashrc
exit # 退回到原来的用户
现在,基础软件就位了。
4. 首次启动:初始化数据库与基础配置
软件装好了,但数据库还是个“空壳”,我们需要初始化一个数据库集群(cluster)。
4.1 初始化数据库集群
切换到 postgres 用户,执行初始化命令:
sudo su - postgres
initdb -D $PGDATA --encoding=UTF8 --locale=C --data-checksums
-D $PGDATA:指定数据目录,就是我们之前设置的环境变量。--encoding=UTF8:设置默认数据库编码为UTF-8,兼容性好。--locale=C:将区域设置设为C,这能避免一些排序和大小写敏感性问题,对性能也有轻微提升。如果你需要特定语言排序规则,可以修改这个参数。--data-checksums:强烈建议开启。它会在数据页上启用校验和,有助于检测磁盘静默损坏,是数据安全的一道重要防线。
初始化成功后,你会看到类似“Success. You can now start the database server”的提示。用 ls -lh $PGDATA 看看,里面已经生成了配置文件(postgresql.conf, pg_hba.conf)和基础目录结构。
4.2 关键配置文件调整
在启动之前,我们通常需要调整两个核心配置文件,以允许远程连接(如果需要)并设置认证方式。
1. 修改 postgresql.conf: 这个文件主要控制数据库服务器的行为。
vi $PGDATA/postgresql.conf
找到 listen_addresses 这一行,默认可能是 localhost。如果你需要从其他服务器连接这个数据库,就改成 '*'(监听所有IP),如果只在本机使用,保持 localhost 即可。
listen_addresses = '*' # 允许所有IP连接,生产环境请结合防火墙谨慎设置
# listen_addresses = 'localhost' # 只允许本机连接
另外,可以顺便调整一下 port(默认5432)和 max_connections(默认100)等参数,根据你的服务器资源来定。
2. 修改 pg_hba.conf: 这个文件控制主机认证,即“谁”可以从“哪里”以“什么方式”访问“哪个数据库”。
vi $PGDATA/pg_hba.conf
在文件末尾,添加一行规则。例如,允许所有IP地址的所有用户通过密码访问所有数据库(仅用于测试或内网可信环境,生产环境务必严格限制):
# TYPE DATABASE USER ADDRESS METHOD
host all all 0.0.0.0/0 scram-sha-256
METHOD 推荐使用 scram-sha-256,这是目前最安全的密码认证方式。如果只是本机信任环境,也可以用 trust,但风险极高。
4.3 启动服务与验证
配置完成后,就可以启动数据库服务了。最简单的方式是使用 pg_ctl:
pg_ctl -D $PGDATA -l logfile start
-D $PGDATA:指定数据目录。-l logfile:将日志输出到指定文件。
检查服务是否正常运行:
pg_ctl -D $PGDATA status
或者通过 ps 命令查看进程:
ps aux | grep postgres
你应该能看到 postmaster(主进程)和几个 postgres 后台进程。
最后,用自带的客户端 psql 连接一下,验证安装成功:
psql -d postgres
如果成功,你会进入 psql 的命令行界面,提示符类似 postgres=#。输入 \q 可以退出。
为了让数据库服务在系统重启后能自动启动,我们可以配置一个systemd服务单元。创建一个文件 /etc/systemd/system/postgresql-15.service:
sudo vi /etc/systemd/system/postgresql-15.service
内容如下(根据你的实际路径修改):
[Unit]
Description=PostgreSQL 15.8 Database Server
After=network.target
[Service]
Type=forking
User=postgres
Group=postgres
Environment=PGDATA=/opt/pgsql/15.8/data
OOMScoreAdjust=-1000
ExecStart=/opt/pgsql/15.8/bin/pg_ctl -D ${PGDATA} start
ExecStop=/opt/pgsql/15.8/bin/pg_ctl -D ${PGDATA} stop
ExecReload=/opt/pgsql/15.8/bin/pg_ctl -D ${PGDATA} reload
TimeoutSec=300
[Install]
WantedBy=multi-user.target
然后启用并启动服务:
sudo systemctl daemon-reload
sudo systemctl enable postgresql-15
sudo systemctl start postgresql-15
sudo systemctl status postgresql-15
至此,一个完全由你从源码编译、配置的PostgreSQL 15数据库服务就稳稳地跑起来了。
5. 点睛之笔:编译安装pgvector向量插件
PostgreSQL本身是个强大的关系型数据库,而pgvector插件则赋予了它处理AI时代核心数据——向量(Embedding)的能力。有了它,你就能在数据库里直接做相似性搜索,比如“找到和这张图片最像的十张图”、“推荐和这篇文章内容相近的文章”。
5.1 解压与编译插件
回到我们之前存放源码的目录,开始处理pgvector:
cd ~/pg_build
tar zxvf pgvector-v0.7.4.tar.gz
cd pgvector-0.7.4
pgvector的编译安装非常简单,因为它就是一个标准的PostgreSQL扩展。它需要用到我们之前安装的cmake。直接运行:
make
sudo make install
make 命令会调用 pg_config(PostgreSQL安装时提供的工具)来获取头文件和库文件路径,所以它能自动找到我们刚编译安装的PG15。make install 会将编译好的动态库文件(vector.so)和SQL控制文件复制到PostgreSQL的扩展目录(/opt/pgsql/15.8/share/extension/ 和 /opt/pgsql/15.8/lib/)。
这里有个我踩过的坑: 如果你的系统上同时存在多个版本的PostgreSQL(比如系统自带的旧版和刚编译的新版),一定要确保 PATH 环境变量里,新版本的 bin 目录在最前面。否则,make 可能会链接到旧版本的 pg_config,导致插件安装到错误的位置,或者编译失败。你可以用 which pg_config 命令来确认当前使用的是哪个版本的 pg_config。
5.2 在数据库中启用插件
插件已经安装到数据库软件层面了,接下来需要在具体的数据库中启用它。首先,用 psql 连接到你的数据库(比如默认的 postgres 库):
sudo su - postgres
psql -d postgres
在psql命令行中,执行以下SQL命令:
CREATE EXTENSION vector;
就这么简单!这条命令会在当前数据库中创建vector扩展所需的数据类型、函数和操作符。你可以验证一下是否安装成功:
\dx
在扩展列表里,你应该能看到 vector。或者,也可以创建一个包含向量类型的表试试:
CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3));
INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]');
SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;
最后这个查询,就是pgvector的核心功能:根据向量之间的余弦距离(<-> 操作符)进行相似性排序。如果它能正确执行并返回结果,恭喜你,pgvector插件已经完美安装并可以工作了!
6. 避坑指南与性能调优心得
走完整个流程,你可能觉得还算顺利。但根据我的经验,在实际生产环境中,总会遇到一些意想不到的问题。这里我分享几个常见的“坑”和对应的解决办法。
1. 编译PostgreSQL时提示“找不到-lperl”或类似错误。 这通常是Perl开发包没装对。在CentOS/RHEL系,确保安装了perl-ExtUtils-Embed;在Debian/Ubuntu系,安装libperl-dev。如果还不行,可以在configure时加上--without-perl先跳过Perl支持,但如果你需要PL/Perl功能,就得把依赖解决。
2. make 或 make install 过程中报错,提示权限不足。 编译阶段(make)一般不需要sudo。但安装阶段(sudo make install)需要向系统目录写文件,必须用sudo。如果编译阶段就报权限错,检查一下源码目录的所有者,确保当前用户有读写执行权限。
3. 启动PostgreSQL失败,日志显示“could not create lock file”。 这通常是数据目录($PGDATA)的权限问题。务必确保整个数据目录及其所有父目录的所有者是postgres用户,并且权限是700(drwx------)。用 ls -ld /opt/pgsql/15.8/data 和 ls -la /opt/pgsql/15.8/data/ 仔细检查。
4. pgvector插件编译失败,提示找不到postgres.h。 这就是典型的pg_config路径问题。确保你的PATH环境变量正确设置了新编译PG的bin目录。可以尝试在编译pgvector时显式指定PG_CONFIG路径:make PG_CONFIG=/opt/pgsql/15.8/bin/pg_config。
5. 创建vector扩展时提示“无法打开扩展控制文件”。 这说明插件文件没有安装到正确位置。检查/opt/pgsql/15.8/share/extension/目录下是否有vector.control等文件。没有的话,说明make install安装到了其他PG版本目录下。解决pg_config路径问题是关键。
关于性能调优的一点心得:
- 编译参数:生产环境编译时,可以去掉
--enable-debug,并考虑使用--with-llvm来启用JIT编译,对复杂查询可能有性能提升,但会显著增加编译时间和依赖。 - 向量索引:pgvector支持
ivfflat和hnsw两种索引。对于海量向量搜索,创建索引是必须的。ivfflat创建快、占用空间小,但召回率可能略低;hnsw召回率高、查询快,但创建慢、占用空间大。你需要根据数据量、精度要求和硬件资源来权衡。 - 数据库参数:处理向量数据时,可能需要调整
shared_buffers、work_mem、maintenance_work_mem等参数,以适应更大的内存消耗。特别是构建向量索引时,增大maintenance_work_mem可以加快创建速度。
整个从源码到可用的向量数据库的旅程,虽然步骤不少,但每一步都清晰可控。自己编译的最大好处,就是你对整个系统有完全的控制力,能针对特定硬件和环境进行优化。当你看到自己亲手构建的数据库,稳定地运行着最前沿的向量搜索功能时,那种成就感,是直接用现成镜像无法比拟的。希望这篇超详细的指南能帮你少走弯路,顺利搭建起属于自己的AI-ready数据库环境。如果在操作中遇到新问题,不妨多看看官方文档和编译输出的错误日志,那里面通常藏着答案。

2437

被折叠的 条评论
为什么被折叠?



