1. 为什么选择源码安装PostgreSQL 14.0?
很多朋友第一次接触PostgreSQL,可能都是从系统包管理器开始的,比如在CentOS上用 yum install postgresql-server,或者在Ubuntu上用 apt install postgresql-14。这种方式确实快,点几下鼠标或者敲一行命令就装好了。但我自己折腾数据库这么多年,但凡是在生产环境或者需要深度定制的场景,我几乎无一例外都会选择源码编译安装。你可能会问,这不是自找麻烦吗?其实不然,源码安装给你带来的灵活性和掌控感,是二进制包无法比拟的。
首先,源码安装能让你“量体裁衣”。你的服务器是高性能的NVMe SSD?那你可以调整数据块的尺寸(--with-blocksize),让I/O效率更高。你的应用需要极强的加密通信?那就在编译时加入OpenSSL支持(--with-openssl)。甚至,你可以精确地指定安装路径,把软件、数据、日志、备份目录规划得清清楚楚,这对于后期运维和故障排查至关重要。其次,你能获得最新的性能优化和补丁。虽然官方也提供二进制包,但源码编译允许你使用最新版本的编译器(比如GCC 11/12)和优化选项,有时候性能提升能有好几个百分点,对于高负载数据库来说,这可不是小数目。最后,这是一个绝佳的学习过程。通过编译,你能更深入地理解PostgreSQL的组件构成和依赖关系,以后出了问题,你心里更有底,知道该从哪里入手排查。
所以,如果你正准备搭建一个要长期运行、可能承载核心业务的PostgreSQL数据库,花点时间走一遍源码编译的流程,绝对是值得的投资。接下来,我就手把手带你从零开始,在Linux上把PostgreSQL 14.0“锻造”出来。
2. 战前准备:环境与依赖梳理
兵马未动,粮草先行。编译安装前,把环境和依赖理顺,能避免后面一大堆令人头疼的错误。我建议你准备一台干净的CentOS 7.x或者Rocky Linux 8+的机器,内存至少2GB,磁盘空间有个20GB以上会比较从容。别用root用户直接操作,咱们遵循最小权限原则。
2.1 创建专属用户和目录结构
第一步,为PostgreSQL创建一个独立的系统用户和用户组。这不仅是安全最佳实践,也能避免和系统其他服务产生冲突。
# 创建postgres用户组,指定一个固定的GID,方便集群管理
groupadd -g 66666 postgres
# 创建postgres用户,加入同名组,并指定UID
useradd -u 66666 -g postgres -m postgres
# 为用户设置一个强密码,这里示例为'YourStrongPassword123!',请务必修改
echo "YourStrongPassword123!" | passwd --stdin postgres
接下来,规划你的目录。我习惯把软件、数据、归档、备份、脚本分门别类放好,结构清晰,一目了然。
# 创建主目录及子目录
mkdir -p /data/postgresql14/{pgdata,archive,scripts,backup,pg14,soft}
# 将源码包拷贝到soft目录(假设你已经下载了postgresql-14.0.tar.gz)
cp /path/to/your/download/postgresql-14.0.tar.gz /data/postgresql14/soft/
# 将整个目录树的所有权赋予postgres用户
chown -R postgres:postgres /data/postgresql14
# 设置合适的权限
chmod -R 775 /data/postgresql14
2.2 安装编译依赖包
这是最容易出错的环节。PostgreSQL编译需要一堆开发库,缺哪个都会导致configure阶段失败。根据我的经验,下面这个命令能覆盖绝大多数情况(针对CentOS/RHEL系列):
yum install -y epel-release
yum install -y gcc make perl-ExtUtils-Embed readline-devel zlib-devel \
pam-devel libxml2-devel libxslt-devel openldap-devel \
python3-devel gcc-c++ openssl-devel cmake bison flex \
systemd-devel
简单解释几个关键包:readline-devel和zlib-devel是最常缺的,没有它们configure会直接报错退出。libxml2-devel和libxslt-devel是为了支持XML数据类型和相关函数。openssl-devel用于加密连接。python3-devel如果你想用PL/Python写存储过程的话是必须的。systemd-devel则是为了后面方便地配置系统服务。
如果你用的是Ubuntu/Debian系列,对应的命令大概是apt install build-essential libreadline-dev zlib1g-dev ...,思路是一样的,就是包名略有不同。安装完后,可以跑一下 gcc --version 和 make --version 确认基础编译工具就绪。
3. 编译三部曲:配置、编译与安装
好了,基础打牢,现在轮到主角登场。咱们切换到postgres用户来操作,避免权限问题。
su - postgres
cd /data/postgresql14/soft
3.1 解压与配置
解压源码包,并进入解压后的目录。
tar zxvf postgresql-14.0.tar.gz
cd postgresql-14.0
接下来是最关键的./configure步骤。这里就是体现“定制化”的地方。我给出一个兼顾性能和常用功能的配置示例:
./configure --prefix=/data/postgresql14/pg14 \
--with-pgport=1952 \
--with-openssl \
--with-libxml \
--with-libxslt \
--with-python \
--with-perl \
--with-blocksize=8 \
--with-wal-blocksize=8
我来拆解一下这些选项:
--prefix=/data/postgresql14/pg14:指定安装目录,所有二进制文件、库文件都会装到这里。--with-pgport=1952:设置默认监听端口。我习惯不用默认的5432,可以减少冲突的可能。--with-openssl:启用SSL加密连接支持,对生产环境安全很重要。--with-libxml和--with-libxslt:启用XML支持。--with-python和--with-perl:启用PL/Python和PL/Perl过程语言支持,按需选择。--with-blocksize和--with-wal-blocksize:设置数据块和WAL日志块大小为8KB,这是经过验证的通用优化值。
执行configure后,仔细查看输出,确保没有“not found”之类的警告。如果一切顺利,会生成Makefile文件。
3.2 编译与安装
现在开始编译,-j参数指定并行编译的作业数,通常设为CPU核心数,能大幅加快速度。
make -j $(nproc)
编译过程可能需要几分钟到十几分钟,取决于你的机器性能。完成后,你会看到“All of PostgreSQL successfully made. Ready to install.”的提示。
接着进行安装:
make install
这会把编译好的文件复制到--prefix指定的目录(/data/postgresql14/pg14)下。如果你想一次性安装所有东西,包括额外的贡献模块(contrib)和文档,可以在编译时使用 make world 和 make install-world。contrib模块里有很多宝,比如监控常用的pg_stat_statements,建议安装。
4. 让数据库跑起来:初始化与配置
软件装好了,但数据库实例还没创建。这就好比房子盖好了,里面还是毛坯,需要装修和布置家具。
4.1 配置环境变量
首先,为postgres用户设置环境变量,这样以后使用psql、pg_ctl等命令会非常方便。
cat >> ~/.bash_profile << "EOF"
# PostgreSQL Environment
export PGPORT=1952
export PGDATA=/data/postgresql14/pgdata
export PGHOME=/data/postgresql14/pg14
export LD_LIBRARY_PATH=$PGHOME/lib:$LD_LIBRARY_PATH
export PATH=$PGHOME/bin:$PATH:.
export MANPATH=$PGHOME/share/man:$MANPATH
export PGHOST=/tmp # 或者指向你的PGDATA,用于Unix socket连接
export PGUSER=postgres
export PGDATABASE=postgres
# 提示符设置,可选
export PS1="[\u@\h \W]\$ "
EOF
# 使配置立即生效
source ~/.bash_profile
4.2 初始化数据库集群
PGDATA目录就是我们规划的数据目录。现在用initdb命令初始化一个数据库集群。
initdb -D $PGDATA -E UTF8 --locale=en_US.utf8 -U postgres --auth-host=scram-sha-256 --auth-local=peer
参数说明:
-D:指定数据库集群目录。-E:设置默认数据库编码为UTF-8,兼容性好。--locale:设置区域,影响排序规则等。确保系统生成了en_US.utf8locale(可通过locale -a查看)。-U:指定初始超级用户名。--auth-host和--auth-local:设置认证方式。这里对本地连接使用peer(系统用户认证),对主机socket连接使用更安全的scram-sha-256密码认证。
初始化成功会输出一系列信息,并提示你可以用 pg_ctl -D /data/postgresql14/pgdata -l logfile start 来启动了。
4.3 调整核心配置文件
默认配置比较保守,我们需要调整两个关键文件:postgresql.conf和pg_hba.conf。
首先修改postgresql.conf,启用远程连接并设置一些基本参数:
cat >> $PGDATA/postgresql.conf << "EOF"
# 连接与监听
listen_addresses = '*' # 监听所有IP,生产环境建议指定具体IP
port = 1952
# 资源与内存
shared_buffers = 128MB # 起步设置,建议为系统内存的25%
work_mem = 4MB # 每个排序/哈希操作可用内存
maintenance_work_mem = 64MB # 维护操作(如VACUUM)可用内存
# 日志
logging_collector = on
log_directory = 'pg_log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_truncate_on_rotation = on
log_rotation_age = 1d
log_rotation_size = 0
# 时区
timezone = 'Asia/Shanghai'
EOF
然后配置pg_hba.conf,这是控制客户端访问认证的核心文件,一定要小心设置:
cat > $PGDATA/pg_hba.conf << "EOF"
# TYPE DATABASE USER ADDRESS METHOD
# 本地Unix socket连接,使用peer认证(操作系统用户)
local all all peer
# IPv4本地主机连接,使用scram-sha-256密码认证
host all all 127.0.0.1/32 scram-sha-256
# IPv6本地主机连接
host all all ::1/128 scram-sha-256
# 允许所有远程IP通过密码访问(生产环境应缩小范围)
host all all 0.0.0.0/0 scram-sha-256
# 复制权限
host replication all 0.0.0.0/0 scram-sha-256
EOF
注意:上面示例中
host all all 0.0.0.0/0允许了所有IP,这在实验环境可以,但生产环境必须根据实际情况,将0.0.0.0/0替换为具体的、受信任的客户端IP或网段,例如192.168.1.0/24。
5. 启动、验证与基本管理
配置妥当,现在可以启动数据库服务了。
5.1 启动与状态检查
使用pg_ctl工具来管理数据库实例:
# 启动数据库
pg_ctl start
# 查看运行状态
pg_ctl status
# 如果启动失败,查看日志文件 $PGDATA/pg_log/ 下的最新日志
如果看到“server is running”的提示,说明启动成功。第一次启动可能会稍慢一些。
5.2 连接测试与修改密码
现在连接数据库,并修改默认超级用户postgres的密码。
# 使用psql连接本地数据库
psql -U postgres -d postgres
连接成功后,你会进入psql的命令行界面,提示符类似 postgres=#。在这里执行SQL修改密码:
ALTER USER postgres WITH PASSWORD 'YourNewStrongPassword456!';
\q -- 退出psql
修改后,你可以用新密码从本地或远程(如果配置了)重新连接测试:
psql -U postgres -h 127.0.0.1 -p 1952 -d postgres -W
# 会提示输入密码,输入你刚设置的
5.3 便捷的系统服务配置
手动启动毕竟不方便,我们把它配置成systemd服务,实现开机自启和便捷的服务管理。
以root用户身份创建服务文件:
cat > /etc/systemd/system/postgresql-14.service << "EOF"
[Unit]
Description=PostgreSQL 14 Database Server
Documentation=https://www.postgresql.org/docs/14/
After=network.target
[Service]
Type=forking
User=postgres
Group=postgres
Environment=PGDATA=/data/postgresql14/pgdata
Environment=PGPORT=1952
OOMScoreAdjust=-1000
ExecStart=/data/postgresql14/pg14/bin/pg_ctl start -D ${PGDATA} -s -o "-p ${PGPORT}" -w -t 300
ExecStop=/data/postgresql14/pg14/bin/pg_ctl stop -D ${PGDATA} -s -m fast
ExecReload=/data/postgresql14/pg14/bin/pg_ctl reload -D ${PGDATA} -s
TimeoutSec=0
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target
EOF
然后重新加载systemd配置,并启用服务:
systemctl daemon-reload
systemctl enable postgresql-14
systemctl start postgresql-14
systemctl status postgresql-14
现在你就可以用 systemctl start/stop/restart postgresql-14 来管理数据库服务了,非常方便。
6. 进阶调优与故障排查指引
数据库跑起来只是第一步,要让它跑得稳、跑得快,还需要一些调优。这里分享几个我实战中觉得立竿见影的点。
内核参数优化:在/etc/sysctl.conf中添加或修改以下参数,然后执行sysctl -p生效。这些参数主要影响共享内存和信号量,是PostgreSQL高效运行的基础。
# 共享内存大小,建议为物理内存的一半或更多(例如16GB内存可设为8GB)
kernel.shmmax = 8589934592
kernel.shmall = 2097152
# 信号量设置
kernel.sem = 50100 64128000 50100 1280
# 网络和文件描述符
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048576
fs.file-max = 6815744
数据库参数微调:根据你的机器配置,回头再细调postgresql.conf里的几个内存相关参数:
shared_buffers:可以逐步增加到内存的1/4。effective_cache_size:设置为系统内存的50%-75%,帮助查询规划器做出正确判断。max_connections:根据应用连接数设置,避免设得过高浪费内存。
常见故障排查:
- 启动失败:首先检查
$PGDATA/pg_log下的日志文件,错误信息通常很明确。常见原因有:端口被占用、PGDATA目录权限不对、共享内存不足。 - 连接被拒绝:检查
pg_hba.conf文件,确认你的客户端IP和认证方法被正确配置。检查postgresql.conf中的listen_addresses是否包含客户端地址。 - 性能问题:打开慢查询日志(设置
log_min_duration_statement),分析耗时长的SQL。使用pg_stat_statements模块(需在postgresql.conf中设置shared_preload_libraries并创建扩展)来找出高频或高消耗的查询。
踩过几次坑之后,我最大的体会是:日志是你最好的朋友。无论遇到什么问题,养成第一时间查看数据库日志的习惯,十有八九都能找到线索。源码安装虽然前期步骤多一些,但这份对系统更深层次的理解和控制力,会在后续漫长的运维周期里持续带来回报。

353

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



