[PG] 从源码安装开始

前言
最近开始写 PG 了,刚好最近 PG18 出来了,源码安装一下,玩一下 PG18 的新功能
下载
从 https://www.postgresql.org/ftp/source/ 下载需要的。
我这里下一个最新版的 18.1
wget https://ftp.postgresql.org/pub/source/v18.1/postgresql-18.1.tar.gz
tar -zxf postgresql-18.1.tar.gz
如果下载不动可以参考国内的镜像源:https://developer.aliyun.com/mirror/postgresql
安装 OPENSSL 1.1.1
我的 Linux 版本是 Centos7 的,一直用这个也懒得再装了,但它默认提供的 openssl 版本是 1.0.2 的,不符合 PG18 要求的 OpenSSL 1.1.1
[postgres@postgresql1 ~]$ openssl version
OpenSSL 1.0.2k-fips 26 Jan 2017
要升级 openssl 版本就需要手动进行编译了
-
下载 openssl
cd /usr/local/src/
wget https://www.openssl.org/source/openssl-1.1.1d.tar.gz
tar xf openssl-1.1.1d.tar.gz -
编译 openssl
cd openssl-1.1.1d
./config
make && make install -
配置
默认编译后,并没有替换 openssl 的版本,所以要配置一下
echo "/usr/local/lib64/" >> /etc/ld.so.conf
ldconfig
mv /usr/bin/openssl /usr/bin/openssl.old
ln -sv /usr/local/bin/openssl /usr/bin/openssl -
验证
[root@postgresql1 openssl-1.1.1d]# openssl version
OpenSSL 1.1.1d 10 Sep 2019 -
配置环境变量,以便 pg 找到新版 openssl ,使用它来编译
export LDFLAGS="-L/usr/local/lib64"
export CPPFLAGS="-I/usr/local/include"
export LD_LIBRARY_PATH="/usr/local/lib64:$LD_LIBRARY_PATH"结果示例:
[root@postgresql1 postgresql-18.1]# pkg-config --cflags --libs openssl
-I/usr/local/include -L/usr/local/lib64 -lssl -lcrypto
[root@postgresql1 postgresql-18.1]# pkg-config --modversion openssl
1.1.1d
编译安装 PG18
添加用户和组
pg 需要运行在单独的用户下,不能运行在 root 下。
添加一个组
groupadd -g 1001 postgres
添加一个用户,由于我这里还有一个 PG16 用了 postgres 所以用户名用 postgres18 命名
useradd -g 1001 -m postgres18
设置密码
echo "123456" | passwd --stdin postgres18
configure 选项
解压出来的目录下就是源码了
[root@postgresql1 postgresql-18.1]# ll
总用量 836
-rw-rw-r--. 1 root root 365 11月 11 05:52 aclocal.m4
drwxrwxr-x. 2 root root 4096 11月 11 05:52 config
-rwxrwxr-x. 1 root root 590013 11月 11 05:52 configure
-rw-rw-r--. 1 root root 89274 11月 11 05:52 configure.ac
drwxrwxr-x. 61 root root 4096 11月 11 05:52 contrib
-rw-rw-r--. 1 root root 1198 11月 11 05:52 COPYRIGHT
drwxrwxr-x. 3 root root 87 11月 11 05:52 doc
-rw-rw-r--. 1 root root 4176 11月 11 05:52 GNUmakefile.in
-rw-rw-r--. 1 root root 277 11月 11 05:52 HISTORY
-rw-rw-r--. 1 root root 1822 11月 11 05:52 Makefile
-rw-rw-r--. 1 root root 121352 11月 11 05:52 meson.build
-rw-rw-r--. 1 root root 6641 11月 11 05:52 meson_options.txt
-rw-rw-r--. 1 root root 983 11月 11 05:52 README.md
drwxrwxr-x. 16 root root 4096 11月 11 05:52 src
可以先查看下 configure –help 的选项,这里可以配置目录和一些功能
[root@postgresql1 server]# cd postgresql-18.1
[root@postgresql1 postgresql-18.1]# ./configure --help
下面写出一些对应的描述
定义安装位置:
-
--prefix=PREFIX将所有文件安装在
PREFIX目录而不是/usr/local/pgsql下。实际文件将安装在各种子目录中;任何文件都不会直接安装在PREFIX目录中。 -
--exec-prefix=EXEC-PREFIX可以将依赖于体系结构的文件的安装目录放在与
PREFIX不同的前缀EXEC-PREFIX下。这对于在主机之间共享依赖于体系结构的独立文件很有用。如果省略此项,则EXEC-PREFIX将等于PREFIX,并且依赖于体系结构和独立的文件都将安装在同一个树下 -
--bindir=DIRECTORY指定可执行程序的目录。默认值为
EXEC-PREFIX/bin,通常表示/usr/local/pgsql/bin。 -
--sysconfdir=DIRECTORY设置各种配置文件所在的目录,默认值为
PREFIX/etc。 -
--libdir=DIRECTORY设置安装库和动态加载模块的位置。默认值为
EXEC-PREFIX/lib。 -
--includedir=DIRECTORY设置安装 C 和 C++ 头文件的目录。默认值为
PREFIX/include。 -
--datarootdir=DIRECTORY设置各种只读数据文件的根目录。这仅设置以下一些选项的默认值。默认值为
PREFIX/share。 -
--datadir=DIRECTORY设置已安装程序使用的只读数据文件的目录。默认值为
DATAROOTDIR。请注意,这与数据库文件将放置的位置无关。 -
--localedir=DIRECTORY设置安装区域数据(特别是消息翻译目录文件)的目录。默认值为
DATAROOTDIR/locale。 -
--mandir=DIRECTORY随 PostgreSQL 一起提供的 man 页将安装在此目录下的相应
manx子目录中。默认值为DATAROOTDIR/man。 -
--docdir=DIRECTORY设置安装文档文件(man 页除外)的根目录。这仅设置以下选项的默认值。此选项的默认值是
DATAROOTDIR/doc/postgresql。 -
--htmldir=DIRECTORYPostgreSQL 的 HTML 格式文档将安装在此目录下。默认值为
DATAROOTDIR。
定义安装的功能:
-
--enable-nls[=LANGUAGES]启用本地语言支持(NLS),即能够以非英语语言显示程序的邮件。
LANGUAGES是可选的空格分隔列表,包含您想要支持的语言代码,例如--enable-nls='de fr'。(您的列表与实际提供的翻译集之间的交集将自动计算。)如果您不指定列表,则安装所有可用的翻译。要使用此选项,您需要 Gettext API 的实现。
-
--with-perl构建 PL/Perl 服务器端语言。
-
--with-python构建 PL/Python 服务器端语言。
-
--with-tcl构建 PL/Tcl 服务器端语言。
-
--with-tclconfig=DIRECTORYTcl 安装
tclConfig.sh文件,其中包含构建与 Tcl 接口的模块所需的配置信息。此文件通常在已知位置自动找到,但如果您想使用不同版本的 Tcl,则可以指定要查找tclConfig.sh的目录。 -
--with-llvm构建时支持基于 LLVM 的 JIT 编译。这需要安装 LLVM 库。当前所需的最低 LLVM 版本是 14。
llvm-config将用于查找所需的编译选项。llvm-config将在您的PATH中搜索。如果找不到所需的程序,请使用LLVM_CONFIG指定正确llvm-config的路径。例如:./configure ... --with-llvm LLVM_CONFIG='/path/to/llvm/bin/llvm-config'LLVM 支持需要兼容的
clang编译器(如果需要,通过CLANG环境变量指定),以及一个工作的 C++ 编译器(如果需要,通过CXX环境变量指定)。 -
--with-lz4构建时支持 LZ4 压缩。
-
--with-zstd构建时支持 Zstandard 压缩。
-
--with-ssl=LIBRARY构建时支持 SSL(加密)连接。唯一支持的
LIBRARY是openssl,它同时用于 OpenSSL 和 LibreSSL。这需要安装 OpenSSL 包。configure将检查所需的头文件和库,以确保您的 OpenSSL 安装足够,然后再继续。 -
--with-openssl过时的
--with-ssl=openssl等效项。 -
--with-gssapi构建时支持 GSSAPI 身份验证。GSSAPI 需要安装 MIT Kerberos。在许多系统上,GSSAPI 系统(MIT Kerberos 安装的一部分)未安装在默认搜索的目录中(例如
/usr/include、/usr/lib),因此除了此选项外,您还必须使用--with-includes和--with-libraries选项。configure将检查所需的头文件和库,以确保您的 GSSAPI 安装足够,然后再继续。 -
--with-ldap构建时支持 LDAP 身份验证和连接参数查找。在 Unix 上,这需要安装 OpenLDAP 包。在 Windows 上,使用默认的 WinLDAP 库。
configure将检查所需的头文件和库,以确保您的 OpenLDAP 安装足够,然后再继续。 -
--with-pam构建时支持 PAM(可插拔认证模块)支持。
-
--with-bsd-auth构建时支持 BSD 身份验证。(BSD 身份验证框架目前仅在 OpenBSD 上可用。)
-
--with-systemd构建时支持 systemd 服务通知。这会改善与 systemd 启动服务器的集成,但否则没有影响。使用此选项需要安装 libsystemd 和相关的头文件。
-
--with-bonjour构建时支持 Bonjour 自动服务发现。这需要在您的操作系统中具有 Bonjour 支持。在 macOS 上推荐。
-
--with-uuid=LIBRARY构建 uuid-ossp 模块(提供生成 UUID 的函数),使用指定的 UUID 库。
LIBRARY必须是以下之一: -
bsd使用 FreeBSD 和其他一些 BSD 派生系统中找到的 UUID 函数 -
e2fs使用e2fsprogs项目创建的 UUID 库;此库存在于大多数 Linux 系统和 macOS 中,并且也可以在其他平台上获得 -
ossp使用 OSSP UUID 库 -
--with-ossp-uuid过时的
--with-uuid=ossp等效项。 -
--with-libcurl构建时支持 libcurl 以实现 OAuth 2.0 客户端流程。此功能需要 libcurl 版本 7.61.0 或更高版本。使用此选项构建将检查所需的头文件和库,以确保您的 curl 安装足够,然后再继续。
-
--with-libnuma构建时支持 libnuma 以实现基本的 NUMA 支持。仅在实现了 libnuma 库的平台上受支持。
-
--with-liburing构建时支持 liburing,启用 io_uring 支持以实现异步 I/O。
为了检测所需的编译器和链接器选项,PostgreSQL 将查询
pkg-config。要使用位于非标准位置的 liburing 安装,您可以设置与
pkg-config相关的环境变量(请参阅其文档)。 -
--with-libxml构建时支持 libxml2,启用 SQL/XML 支持。此功能需要 libxml2 版本 2.6.23 或更高版本。
为了检测所需的编译器和链接器选项,PostgreSQL 将查询
pkg-config(如果已安装并知道 libxml2)。否则,如果找到,将使用 libxml2 安装的程序xml2-config。首选使用pkg-config,因为它能更好地处理多架构安装。要使用位于非标准位置的 libxml2 安装,您可以设置与
pkg-config相关的环境变量(请参阅其文档),或者将环境变量XML2_CONFIG设置为指向 libxml2 安装附带的xml2-config程序,或者设置变量XML2_CFLAGS和XML2_LIBS。(如果安装了pkg-config,那么要覆盖其对 libxml2 位置的理解,您必须设置XML2_CONFIG或将XML2_CFLAGS和XML2_LIBS都设置为非空字符串。) -
--with-libxslt构建时支持 libxslt,启用 xml2 模块来执行 XML 的 XSL 转换。还必须指定
--with-libxml。 -
--with-selinux构建时支持 SElinux,启用 sepgsql 扩展。
-
--without-icu构建时不支持 ICU 库,禁用 ICU 排序规则功能的使用。
-
--without-readline阻止使用 Readline 库(以及 libedit)。此选项在 psql 中禁用命令行编辑和历史记录。
-
--with-libedit-preferred优先使用 BSD 许可的 libedit 库而不是 GPL 许可的 Readline。此选项仅在您同时安装了这两个库时才重要;在这种情况下,默认使用 Readline。
-
--without-zlib阻止使用 Zlib 库。这会禁用 pg_dump 和 pg_restore 中对压缩存档的支持。
-
--with-pgport=NUMBER将
NUMBER设置为服务器和客户端的默认端口号。默认值为 5432。端口可以随时更改,但如果在此处指定,则服务器和客户端都将具有相同的默认编译值,这可能非常方便。通常,选择非默认值的唯一好理由是您打算在同一台机器上运行多个 PostgreSQL 服务器。 -
--with-krb-srvnam=NAMEGSSAPI 使用的 Kerberos 服务主体的默认名称。
postgres是默认值。 通常没有理由更改它,除非您是为 Windows 环境构建的,在这种情况下,它必须设置为大写POSTGRES。 -
--with-segsize=SEGSIZE设置 segment size,以千兆字节为单位。大表被分成多个操作系统文件,每个文件的大小等于段的大小。 这避免了许多平台上存在的文件大小限制问题。默认段大小 1 GB 在所有支持的平台上都是安全的。 如果您的操作系统支持 “largefile”(现在大多数都支持),您可以使用更大的段大小。 这有助于减少处理非常大的表时消耗的文件描述符的数量。但请注意不要选择大于您的平台和您打算使用的文件系统支持的值。 您可能希望使用的其他工具,例如 tar,也可以设置可用文件大小的限制。 建议(虽然不是绝对要求)此值是 2 的幂。 请注意,更改此值会破坏磁盘数据库兼容性,这意味着您不能使用
pg_upgrade升级到具有不同段大小。 -
--with-blocksize=BLOCKSIZE设置 block size,以千字节为单位。这是表中的存储和 I/O 默认值为 8 KB,适用于大多数情况; 但其他值在特殊情况下可能有用。 该值必须是 1 到 32(千字节)之间的 2 的幂。 请注意,更改此值会破坏磁盘数据库兼容性,这意味着您不能使用
pg_upgrade升级到具有不同块大小的构建。 -
--with-wal-blocksize=BLOCKSIZE设置 WAL block size,以千字节为单位。这是 WAL 日志中的存储和 I/O 单元。 默认值为 8 KB,适用于大多数情况; 但其他值在特殊情况下可能有用。该值必须是 1 到 64(千字节)之间的 2 的幂。 请注意,更改此值会破坏磁盘数据库兼容性,这意味着您不能使用
pg_upgrade升级到具有不同 WAL 块大小的构建。
构建
我这里已经弄好了 openssl ,所以不加上 openssl-devel
安装依赖:
yum install lz4-devel zlib-devel readline-devel pam-devel openldap-devel bison flex libxml2-devel tcl-devel systemd-devel libxslt-devel perl-devel perl-IPC-Run perl-Test-Simple perl-ExtUtils-Embed python-devel gcc-c++ libicu-devel python3 python3-devel
大家按需添加选项即可,我这里使用的选项为:
./configure --enable-rpath --prefix=/pgsql18.1 --with-tcl --with-lz4 --with-perl --with-python --with-pam --with-openssl --with-libxml --with-libxslt --enable-nls --enable-tap-tests --with-uuid=e2fs --with-system-tzdata=/usr/share/zoneinfo --with-systemd --with-selinux --with-gssapi --with-ldap
生成可执行二进制文件
make
将可执行二进制文件 copy 到 –prefix 指定的安装目录下
make install
*
注意:
如果遇到缺少库安装对应的
-devel包即可(比如yum install xxx-devel),如 PAM 库缺失的报错如下checking for pam_start in -lpam... no
configure: error: library 'pam' is required for PAM安装 PAM 开发包:
yum install pam-devel然后重新运行 configure。
rm -f config.cache config.log
./configure --enable-rpath --prefix=/pgsql18.1 --with-tcl --with-lz4 --with-perl --with-python --with-pam --with-openssl --with-libxml --with-libxslt --enable-nls --enable-tap-tests --with-uuid=e2fs --with-system-tzdata=/usr/share/zoneinfo --with-systemd --with-selinux --with-gssapi --with-ldap”
编译完成会产生这些
[root@postgresql1 postgresql-18.1]# ll /pgsql18.1/
总用量 16
drwxr-xr-x. 2 root root 4096 2月 3 15:39 bin
drwxr-xr-x. 6 root root 4096 2月 3 15:39 include
drwxr-xr-x. 4 root root 4096 2月 3 15:39 lib
drwxr-xr-x. 6 root root 4096 2月 3 15:39 share
创建数据目录并授权
创建数据目录并授权,顺便把 PG 软件目录也授权一下
mkdir /pg_data18
chown -R postgres18:postgres /pg_data18/
chown -R postgres18:postgres /pgsql18.1/
到这里基本完成
数据库初始化
初始化:
[postgres18@postgresql1 ~]$ /pgsql18.1/bin/initdb -D /pg_data18/ -E UTF8 --locale "C" -W
属于此数据库系统的文件宿主为用户 "postgres18".
此用户也必须为服务器进程的宿主.
数据库集簇将以区域环境设置 "C" 进行初始化.
默认的文本搜索配置将被设为 "english".
允许生成数据页校验和.
输入新的超级用户密码:
再输入一遍:
正在修复已存在目录 /pg_data18 的权限 ... 成功
正在创建子目录 ... 成功
正在选择动态共享内存实现 ... posix
正在选择默认最大连接数 (max_connections) ... 100
正在选择默认共享缓冲区 (shared_buffers) ... 128MB
正在选择默认时区 ... Asia/Shanghai
正在创建配置文件 ... 成功
正在运行启动脚本 ... 成功
正在执行启动脚本后续初始化 ... 成功
正在同步数据到磁盘 ... 成功
initdb: 警告: 为本地连接启用 "trust" 身份验证
initdb: 提示: 你可以通过编辑 pg_hba.conf 或下次运行 initdb 时使用 -A 或者 --auth-local 和 --auth-host 选项进行更改.
成功。你现在可以用下面的命令开启数据库服务器:
/pgsql18.1/bin/pg_ctl -D /pg_data18/ -l logfile start
-
-D
此选项指定数据库集群的存储目录。
-
-E
选择模板数据库的编码。
-
–locale=
设置数据库集群的默认区域设置。
-
-W
使
initdb提示输入引导超级用户的密码。
启动 PG
建 log 目录:
[postgres18@postgresql1 ~]$ cd /pg_data18/
[postgres18@postgresql1 pg_data18]$ ll
总用量 56
drwx------. 5 postgres18 postgres 33 2月 3 23:40 base
drwx------. 2 postgres18 postgres 4096 2月 3 23:40 global
drwx------. 2 postgres18 postgres 6 2月 3 23:40 pg_commit_ts
drwx------. 2 postgres18 postgres 6 2月 3 23:40 pg_dynshmem
-rw-------. 1 postgres18 postgres 5721 2月 3 23:40 pg_hba.conf
-rw-------. 1 postgres18 postgres 2681 2月 3 23:40 pg_ident.conf
drwx------. 4 postgres18 postgres 68 2月 3 23:40 pg_logical
drwx------. 4 postgres18 postgres 36 2月 3 23:40 pg_multixact
drwx------. 2 postgres18 postgres 6 2月 3 23:40 pg_notify
drwx------. 2 postgres18 postgres 6 2月 3 23:40 pg_replslot
drwx------. 2 postgres18 postgres 6 2月 3 23:40 pg_serial
drwx------. 2 postgres18 postgres 6 2月 3 23:40 pg_snapshots
drwx------. 2 postgres18 postgres 25 2月 3 23:40 pg_stat
drwx------. 2 postgres18 postgres 6 2月 3 23:40 pg_stat_tmp
drwx------. 2 postgres18 postgres 18 2月 3 23:40 pg_subtrans
drwx------. 2 postgres18 postgres 6 2月 3 23:40 pg_tblspc
drwx------. 2 postgres18 postgres 6 2月 3 23:40 pg_twophase
-rw-------. 1 postgres18 postgres 3 2月 3 23:40 PG_VERSION
drwx------. 4 postgres18 postgres 77 2月 3 23:40 pg_wal
drwx------. 2 postgres18 postgres 18 2月 3 23:40 pg_xact
-rw-------. 1 postgres18 postgres 88 2月 3 23:40 postgresql.auto.conf
-rw-------. 1 postgres18 postgres 32325 2月 3 23:40 postgresql.conf
[postgres18@postgresql1 pg_data18]$ mkdir pg_log
配置 postgresql.conf 配置文件把日志打到 pg_log 里面
# These are only used if logging_collector is on:
log_directory = 'pg_log' # directory where log files are written,
# can be absolute or relative to PGDATA
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern,
# can include strftime() escapes
logging_collector = on # Enable capturing of stderr, jsonlog,
# and csvlog into log files. Required
# to be on for csvlogs and jsonlogs.
# (change requires restart)
我这里因为还有一个 PG16 占用了 port = 5432 所以需要修改端口号
port = 5433
配置 socket
unix_socket_directories = '/pg_data18' # comma-separated list of directories
# (change requires restart)
unix_socket_group = '' # (change requires restart)
unix_socket_permissions = 0777 # begin with 0 to use octal notation
配置环境变量
[postgres18@postgresql1 ~]$ vi .bashrc
# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=
# User specific aliases and functions
export PATH=/pgsql18.1/bin:$PATH
export LD_LIBRARY_PATH=/pgsql18.1/lib
export PGDATA=/pg_data18
加载
source .bashrc
确认环境变量为 /pgsql18.1 下的 psql
[postgres18@postgresql1 ~]$ which psql
/pgsql18.1/bin/psql
启动数据库
[postgres18@postgresql1 pg_data18]$ pg_ctl start
等待服务器进程启动 ....2026-02-0400:11:25.981 CST [98780] LOG: redirecting logoutputtologging collector process
2026-02-0400:11:25.981 CST [98780] HINT: Future logoutput will appear indirectory"pg_log".
完成
服务器进程已经启动
查看日志
[postgres18@postgresql1 pg_data18]$ cd pg_log
[postgres18@postgresql1 pg_log]$ ll
总用量 4
-rw-------. 1 postgres18 mysqL 607 2月 4 00:11 postgresql-2026-02-04_001125.log
[postgres18@postgresql1 pg_log]$ cat postgresql-2026-02-04_001915.log
2026-02-04 00:19:15.089 CST [98971] LOG: starting PostgreSQL 18.1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), 64-bit
2026-02-04 00:19:15.091 CST [98971] LOG: listening on IPv6 address "::1", port 5433
2026-02-04 00:19:15.091 CST [98971] LOG: listening on IPv4 address "127.0.0.1", port 5433
2026-02-04 00:19:15.098 CST [98971] LOG: listening on Unix socket "/pg_data18/.s.PGSQL.5433"
2026-02-04 00:19:15.130 CST [98978] LOG: database system was shut down at 2026-02-04 00:18:53 CST
2026-02-04 00:19:15.140 CST [98971] LOG: database system is ready to accept connections
OK 启动了
登录
[postgres18@postgresql1 pg_data18]$ psql -h /pg_data18 -p 5433 -d postgres
psql (18.1)
输入 "help" 来获取帮助信息.
postgres=#
-
-h 指定刚才的配置的 socket -
-p 指定端口,要不然就会找到 /pg_data18/.s.PGSQL.5432 ,但是我们这里是 5433 -
-d 指定 database
结语
PG18 是最新版本,生产不应该使用最新版,应该去使用 PG16 或者 PG14,这些版本的 extend 都有相应的支持,PG18 版本太新很多扩展的版本都没支持,尝鲜使用即可。
没有扩展支持的 PG 还是 PG 吗。
夜雨聆风
