PostgreSQL 14 离线安装实战:内网环境部署与配置全攻略
2026/9/18 14:55:02 网站建设 项目流程

在写这篇手记之前,先交代个背景:我去年在一家客户的机房部署了一套数据平台,机器在内网,未经审批不允许访问外网,我抱着笔记本在机房从下午待到晚上,全部依赖就是U盘里提前备好的安装包。当时用的就是 PostgreSQL 14,整个过程踩了不少坑,也把离线安装这套流程彻底理清了。今天把这些经验整理出来,希望能帮到正要在内网环境部署 PostgreSQL 14 的运维和开发朋友。

这套流程适合绝大多数 Linux 发行版(以 CentOS/RHEL 系为例)的离线场景,只要你有一台能联网的机器做“搬运工”,把安装包下载好拷进内网,剩下的事情其实很简单。全文会覆盖安装包下载、依赖处理、数据库初始化、远程连接配置、开机自启,以及我在实际部署中遇到的典型问题,全程跟着做基本能一次跑通。

1. 动手之前:离线安装的整体思路与准备

离线安装说到底就一句话:把网上安装时自动完成的事情,提前手动做完。在线用 yum 装 PostgreSQL 时,系统会自动匹配依赖、下载 RPM、再安装;离线环境里没有仓库,你必须自己把主程序包和所有依赖包找齐,拷进内网,再用本地安装的方式逐个装上。所以这个方案的核心不是“安装”动作本身,而是“依赖管理”。

1.1 为什么选择 PostgreSQL 14

很多人会问,现在 PostgreSQL 16、17 都有了,为什么非要用 14。我当时的判断很简单:客户的生产系统是基于某个国产化项目基线来的,应用开发商明确要求 14 版本,因为他们的驱动和 SQL 兼容性测试全是在 14 上跑的。如果你是给存量系统做替换升级,尽量跟随原环境的版本,别图新。如果你是从零开始搭建新系统,那选新版本问题不大,但 14 依然是一个相当稳定、生态成熟的选择——它支持了很长时间,各种文档、工具链、遇到的坑都能搜到现成答案,部署起来最稳。

1.2 离线安装的通用流程

整个离线安装过程可以拆成四个阶段:准备、传输、安装、配置。每个阶段我都单独展开讲,但先给大家一个整体框架:

  1. 在有网机器上下载 PostgreSQL 14 的 RPM 包及所有依赖包。
  2. 把 RPM 包(连同依赖)通过 U 盘、scp、内网共享等方式传到目标服务器。
  3. 在内网机器上用 yum localinstall 或 rpm -ivh 安装所有 RPM 包。
  4. 初始化数据库、启动服务,完成基础配置(密码、远程访问、开机自启等)。

这个流程看起来平淡无奇,实际操作时坑全藏在细节里。比如依赖包到底要下载哪些、pg_hba.conf 改完为什么连不上、为什么明明安装成功却启动不了……后面都会一一拆解。

1.3 环境确认与版本清单

在动手前,先确认目标机器的操作系统和架构。PostgreSQL 官方仓库针对不同系统提供了不同的安装源,命令也有差异。我以 CentOS 7 / RHEL 7 x86_64 为例演示,其他系统思路完全一致,只是包名和路径略有不同。

在目标机器上执行以下命令,先把系统信息摸清楚:

cat /etc/redhat-release uname -m

拿到结果后,再去下载对应系统的 RPM 包。如果你用的是 CentOS 8/9、Rocky Linux、Ubuntu,包管理器和路径会不一样,后面我会补充说明。

2. 安装包下载与依赖分析

下载安装包是整个离线安装最关键的一步,也是最容易翻车的一步。很多人以为下载一个 postgresql14-server 的 RPM 就完事了,装的时候才发现缺这个库缺那个依赖,卡在那里进退两难。

2.1 官方 RPM 仓库地址与包清单

PostgreSQL 官方提供了 yum 仓库,地址是https://download.postgresql.org/pub/repos/yum/,里面按系统版本和 PostgreSQL 主版本分目录存放。以 PostgreSQL 14 + CentOS 7 为例,核心的安装包通常在:

https://download.postgresql.org/pub/repos/yum/14/redhat/rhel-7-x86_64/

目录下常见的包有:

RPM 包名作用说明
postgresql14-14.13-1PGDG.rhel7.x86_64.rpm客户端工具和基础库(psql、libpq 等)
postgresql14-server-14.13-1PGDG.rhel7.x86_64.rpm数据库服务端(必须)
postgresql14-contrib-14.13-1PGDG.rhel7.x86_64.rpm扩展模块(可选但有价值)
postgresql14-libs-14.13-1PGDG.rhel7.x86_64.rpm共享运行库(依赖项)

注意,这只是主包,实际安装时还需要依赖系统的基础库。因为每个系统基础库的版本不同,所以最稳妥的方式是直接配置官方 yum 源,在有网的机器上让 yum 自己计算依赖并下载全部 RPM 包,而不是手动一个个抓取。

2.2 在有网机器上用 yum 一键下载所有依赖

如果你先去有网的机器上装一个 PostgreSQL 14,然后rpm -qa去查都有哪些包,这种方法太笨了。正确做法是用yumdownloaderrepotrack工具,把主程序和所有依赖一次性拉下来。

先安装工具:

yum install -y yum-utils

然后配置 PostgreSQL 14 的官方 yum 源(在有网机器上):

yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

接着禁用系统自带的 PostgreSQL 模块(如果有),下载全部 RPM:

yumdownloader --resolve postgresql14-server postgresql14-contrib

不加--resolve的话,yumdownloader 只下载指定的包,不会带依赖;加上之后,它会自动分析依赖树,把所有需要的 RPM 包都下载到当前目录。这条命令其实是离线安装里最核心的一步,依赖能不能一次凑齐就看它了。

如果你用的 Ubuntu 系统,思路一样但命令变成了apt-get download配合apt-cache depends,或者直接装apt-rdepends。不过我在生产环境碰到的离线部署需求,十有八九是 CentOS/RHEL 系列,所以下面还是围绕 RPM 包展开。

2.3 依赖不足时的替代方案

有时候目标系统太老或太精简,yumdownloader 拉下来的依赖还是不够,安装时报各种缺库错误,比如缺libiculibselinux等。遇到这种情况,最简单粗暴的办法是找一套和目标机器操作系统版本一致、能联网的“影子机器”,把 RPM 包放在同一个目录下执行:

yum localinstall -y /tmp/pgsql_rpms/*.rpm

如果它提示缺少依赖,就把缺失的包名记下来,再用yumdownloader单独下载,比如:

yumdownloader --resolve libicu

然后继续拷到内网。这种“缺啥补啥”的方法虽然土,但很有效。为了避免反复往返,建议你在有网机器上先完整跑一遍安装,确认所有依赖都齐了,再拷到内网去执行。

提示:下载完成后最好用ls -l看下 RPM 包大小,如果主程序包只有几十 KB,多半是下载出错或源有问题。完整的 postgresql14-server 包应该在 10MB 以上。

3. 离线安装实操过程

安装包准备好了,接下来就是进入内网机器,把 RPM 包用 U 盘或 scp 传上去。传输这一步没什么好说的,但有一点值得提醒:尽量用 scp 而不是直接拖拽 FTP,因为 scp 基于 SSH 加密传输,不容易出现文件损坏。传完之后可以先校验一下包完整性:

md5sum /tmp/pgsql_rpms/*.rpm

和有网机器上md5sum的结果比对一致,再开始安装。虽然多了一步,但从根源上避免“装到一半报包损坏”的尴尬。

3.1 使用 yum localinstall 安装 RPM 包

在内网机器上进到存放 RPM 包的目录,执行:

cd /tmp/pgsql_rpms yum localinstall -y *.rpm

这里我推荐用yum localinstall而不是rpm -ivh。原因很简单:localinstall 会自动做依赖关系检查,如果本地目录里有能解决依赖的 RPM,它会一起装上;如果缺依赖,它会明确告诉缺什么。而rpm -ivh是一锤子买卖,只要有一个依赖不满足就直接报错,且不会自动从本地目录补装其他包。既然你把依赖包全都下载好了,用 localinstall 是最省心的。

安装成功的标志是最后几行显示Complete!,或者执行rpm -qa | grep postgresql能看到:

postgresql14-14.13-1PGDG.rhel7.x86_64 postgresql14-libs-14.13-1PGDG.rhel7.x86_64 postgresql14-server-14.13-1PGDG.rhel7.x86_64 postgresql14-contrib-14.13-1PGDG.rhel7.x86_64

3.2 安装后的文件布局

装完之后,PostgreSQL 14 的目录结构和系统自带版本有区别,很多第一次用的人容易搞混。它的可执行文件在/usr/pgsql-14/bin/,数据目录默认在/var/lib/pgsql/14/data/,服务脚本是/usr/lib/systemd/system/postgresql-14.service

简单记法:

  • 命令路径:/usr/pgsql-14/bin/下的psqlinitdbpg_ctl等。
  • 数据目录:/var/lib/pgsql/14/data/,包括postgresql.confpg_hba.confPG_VERSION
  • 日志位置:默认通过 systemd 管理,看日志用journalctl -u postgresql-14

由于psql等命令默认不在 PATH 里,建议把 PG 的 bin 目录加进用户环境变量,后面操作会方便很多。这个后面配置小节再细说。

3.3 分别安装 Ubuntu/Debian 系的注意事项

如果你是 Ubuntu 20.04/22.04 的环境,离线安装步骤会变成:

dpkg -i postgresql-14_14.13-1.pgdg22.04+1_amd64.deb

Debian 系对依赖要求更严格,dpkg 不会自动解决依赖关系,装的时候经常报“依赖关系不满足”。此时需要用apt-get install -f来修复,或者提前用apt-get download把所有依赖 deb 包下载齐全后,再统一执行dpkg -i *.deb

由于不同系统差异较大,这篇以 CentOS/RHEL 为主展开,其他系统在原理上是一样的:先解析依赖,再本地安装,最后初始化配置。

4. 数据库初始化与服务启动

装完 RPM 包,数据库还只是一个“空的骨架”,需要初始化数据目录才能使用。这一步不少新手会漏掉,直接去连数据库,结果报错 “could not connect to server”。下面我带大家一步步走完整流程。

4.1 初始化数据目录

PostgreSQL 安装完成后不会自动创建数据目录,必须手动执行 initdb。服务端包会创建一个名为postgres的系统用户,初始化必须以这个用户的身份运行,不能直接用 root,否则后面启动会有权限问题。

正确的初始化命令是:

sudo -u postgres /usr/pgsql-14/bin/initdb -D /var/lib/pgsql/14/data

如果你想自定义数据目录,比如放在专门的磁盘分区/data/pgsql,则先创建目录并赋予 postgres 用户权限:

mkdir -p /data/pgsql chown postgres:postgres /data/pgsql sudo -u postgres /usr/pgsql-14/bin/initdb -D /data/pgsql

初始化参数里,-E UTF8指定编码,--locale=C或者--locale=en_US.UTF-8指定排序规则,如果业务涉及中文,建议直接用-E UTF8 --locale=en_US.UTF-8,避免后面建库时出现编码不匹配的问题。完整的命令可以写成:

sudo -u postgres /usr/pgsql-14/bin/initdb -D /var/lib/pgsql/14/data -E UTF8 --locale=en_US.UTF-8

初始化成功后,终端会显示Success. You can now start the database server using:这样的提示。看到这句话说明数据目录已经没问题了。

4.2 使用 systemd 启动服务并设置开机自启

初始化完成,接下来就是把服务拉起来。用 systemd 管理的好处是可以自动处理用户切换、日志收集等细节,省心很多:

systemctl start postgresql-14 systemctl enable postgresql-14

启动之后检查一下状态:

systemctl status postgresql-14

看到active (running)就说明服务正常。如果状态是failed,不要慌,先看日志定位问题,日志命令是:

journalctl -u postgresql-14 -n 50

常见的失败原因之一是数据目录权限不对,PostgreSQL 要求数据目录属主必须是 postgres 用户,而且是 700 权限。可以用ls -ld /var/lib/pgsql/14/data检查一下。

4.3 设置 postgres 超级用户密码

初始化完成后,数据库内默认有一个超级用户postgres,但这个用户在认证上默认走的 peer 认证——也就是只有操作系统里的 postgres 用户才能免密登录数据库。为了后续能用密码连接,需要先把密码设好。

先切换到 postgres 用户进入 psql:

sudo -u postgres /usr/pgsql-14/bin/psql

进入 psql 命令行后执行:

ALTER USER postgres WITH PASSWORD '你的强密码'; \q

设置密码后,后面配置远程连接和客户端连接时,就可以通过密码认证来登录了。这个密码建议使用至少 12 位、包含大小写字母和数字的强密码,因为 postgres 是超级用户,一旦泄露整库数据都不安全。

5. 核心配置详解:远程访问与连接调优

很多人在本地初始化完数据库后,以为就能直接用客户端连上了。真实情况是,默认配置下 PostgreSQL 只监听本机地址,默认只允许本地连接。要做远程访问,必须改两个文件:postgresql.confpg_hba.conf。这两个文件都在数据目录下。

5.1 修改监听地址与端口

先改postgresql.conf。如果用的是默认数据目录,执行:

vi /var/lib/pgsql/14/data/postgresql.conf

找到下面这行:

#listen_addresses = 'localhost'

把它改成:

listen_addresses = '*'

这里的*表示监听所有网卡地址。其实值也可以写成具体的 IP 列表,比如'192.168.1.10,127.0.0.1',但内网场景一般直接放开。

端口默认是 5432,如果没特殊要求就不用动。如果改了端口,记得客户端连接时也要加-p参数指定端口,云服务器安全组和防火墙规则也要同步放行。

5.2 配置 pg_hba.conf 的认证规则

再改pg_hba.conf,这个文件控制哪些 IP 能连、用什么方式认证。默认只允许本地连接,远程一般会添加一行:

host all all 0.0.0.0/0 scram-sha-256

这一行的意思是:允许所有 IP 通过 TCP 连接所有数据库,认证方式为scram-sha-256。PostgreSQL 14 默认密码加密方式就是scram-sha-256,比之前的md5更安全,所以这里就直接用它。

如果你只想让某个网段连接,比如192.168.1.0/24,就把0.0.0.0/0换成具体网段:

host all all 192.168.1.0/24 scram-sha-256

改完文件后,必须重启服务或者重新加载配置才能生效:

systemctl restart postgresql-14

或者用更温和的 reload 方式(不会断开现有连接):

systemctl reload postgresql-14

我在客户那边遇到过一种很迷惑的情况:pg_hba.conf 改完了,也 reload 了,远程还是连不上。最后发现是防火墙没放行 5432 端口。所以配置完一定要检查防火墙。

5.3 防火墙与 SELinux 检查

CentOS 7/RHEL 7 默认开启 firewalld 和 SELinux,这两兄弟经常成为数据库远程连接的“隐形杀手”。先放行端口:

firewall-cmd --permanent --add-port=5432/tcp firewall-cmd --reload

确认端口已经放行:

firewall-cmd --list-all | grep 5432

然后是 SELinux,如果没关闭,单独放行端口还不够,还要设置数据库端口上下文:

semanage port -a -t postgresql_port_t -p tcp 5432

如果系统没装 semanage,可以用yum install policycoreutils-python安装。当然,内网测试环境图省事的话,临时把 SELinux 设为 permissive 也行,但生产环境还是建议做精细放行,别为了省事直接关掉安全策略。

5.4 验证远程连接

配置完成且服务重启后,在另一台机器上用 psql 验证连接:

psql -h 192.168.1.100 -p 5432 -U postgres -d postgres

如果能正常输入密码并进入 psql 提示符,说明远程连接已经打通。如果这一步报错,通常会出现在密码认证失败、超时、连接拒绝三种情况,排查思路放在下面的问题速查表里。

6. 常用配置与性能调优建议

数据库能连上只是第一步,真正把它调成适合生产使用的状态,还需要做几项基础配置。这些配置不一定都适合所有场景,但适用于绝大多数通用业务。

6.1 设置环境变量

为了让psqlpg_dump等命令直接在终端可用,把 PG 的 bin 目录加入 PATH。在/etc/profile.d/pgsql.sh里写入:

export PATH=/usr/pgsql-14/bin:$PATH export PGDATA=/var/lib/pgsql/14/data

然后执行source /etc/profile让它立即生效。这样后续做备份恢复、日常查询时,命令直接敲psql就行,不用带一长串路径。

6.2 调整内存与连接数

MySQL 和 PostgreSQL 的配置风格不太一样,PG 的默认配置偏保守,内存参数通常需要按机器实际情况调整。常见的核心参数是shared_bufferswork_memeffective_cache_size

postgresql.conf中找到这些参数,按下面的建议调整:

shared_buffers = 256MB # 建议设为物理内存的 25% work_mem = 8MB # 排序、hash 等操作的内存,不宜过大,防止并发时内存爆掉 effective_cache_size = 1GB # 操作系统缓存大小,建议设为物理内存的 50%

比如物理内存是 4GB,那么shared_buffers=1GBeffective_cache_size=2GB是比较合理的起点。work_mem不建议盲目调大,因为它不是总内存上限,而是每个排序操作的内存上限,多个并发会话同时跑大批量排序时,内存消耗是成倍增长的。

注意:这些参数至少需要 reload 才生效,部分参数需要 restart 才生效。修改前建议先看注释说明,并留意postgresql.conf默认配置中已经有一组基础值,改动时不要偏离物理内存的合理范围太多。

6.3 开启日志与慢查询记录

生产环境排查问题离不开日志。建议把日志参数设置成:

logging_collector = on log_directory = 'log' log_filename = 'postgresql-%Y-%m-%d.log' log_min_duration_statement = 1000

log_min_duration_statement = 1000表示执行超过 1000 毫秒(1秒)的 SQL 会被记录到日志里,这能帮你快速定位慢查询。这套设置在应对业务方“数据库好慢”的投诉时非常有用,看一眼日志就知道是哪条 SQL 在拖后腿。

7. 常见问题与排查技巧实录

最后这部分是我真正想分享的重头戏。离线安装的坑,在网上教程里很难一次性看到这么全。下面这些问题是过去一年里我在不同客户现场真实遇到过的,按频率从高到低排列。

7.1 安装时报依赖错误

现象yum localinstall执行后提示缺libpq.so.5()(64bit)libicu等依赖。

原因:依赖包下载不完整,或者目标系统的软件源里没有这些库。

解决:在有网机器上把缺失的包名记下来,用yumdownloader --resolve单独下载对应依赖,拷贝到内网后重新 localinstall。如果系统太老导致某些库版本过低,可以考虑使用官方提供的“软件集合”仓库,或者下载指定版本的基础依赖包。

7.2 初始化失败:权限错误或目录报错

现象:执行initdb -D时提示could not change directory to "/var/lib/pgsql/14/data": Permission denied,或者initdb: error: cannot be run as root

原因:没有切换到 postgres 用户,或者数据目录属主不对。

解决:确保数据目录属主为 postgres 用户(chown -R postgres:postgres数据目录),且以sudo -u postgres方式执行 initdb。千万不要图方便用 root 初始化,即使成功了,后面启动也会有一堆权限问题。

7.3 服务启动失败

现象systemctl start postgresql-14报失败,journalctl显示data directory has invalid permissionscould not open file ... Permission denied

原因:数据目录权限不对。PostgreSQL 要求数据目录权限为 700,且属主是 postgres。

解决

chmod 700 /var/lib/pgsql/14/data chown -R postgres:postgres /var/lib/pgsql/14/data systemctl start postgresql-14

7.4 远程连接报错:Connection refused 或 time out

现象:客户端连接时报Connection refused(连接被拒绝)或Connection timed out(连接超时)。

原因:前者通常是服务没监听对应 IP,或者 pg_hba.conf 没放行;后者通常是网络不通或防火墙拦截。

解决:先在数据库服务器本机检查监听情况:

ss -tlnp | grep 5432

如果看到0.0.0.0:5432,说明服务正常监听所有地址,问题在防火墙或网络层。如果只看到127.0.0.1:5432,说明listen_addresses配置没有生效,检查 postgresql.conf 中是否写对并确认服务重启了。

7.5 认证失败:password authentication failed for user "postgres"

现象:客户端连接提示密码认证失败。

原因:设置密码时没有成功,或者 pg_hba.conf 中认证方式与当前密码类型不匹配。比如默认密码加密方式是 scram-sha-256,但 pg_hba.conf 里写的还是 md5。

解决:重新设置密码,并确认 pg_hba.conf 里使用的是scram-sha-256。如果因为历史原因数据库里已有 md5 密码,可以在 postgresql.conf 里将password_encryption设为scram-sha-256,再重设一次密码。

7.6 客户端连不上:FATAL: no pg_hba.conf entry

现象:远程连接时报错FATAL: no pg_hba.conf entry for host "192.168.1.66", user "postgres", database "postgres", no encryption

原因:pg_hba.conf 中没有匹配的 host 条目,请求被拒绝了。

解决:检查 pg_hba.conf 里是否加了对应网段的 host 规则。注意规则是自上而下匹配的,如果前面有一条更严格的规则(比如host all all 0.0.0.0/0 reject),后面的放行规则不会生效。保持简单、只保留必要规则是最稳妥的做法。

7.7 常用问题速查表

问题现象首选排查命令大概率原因
安装缺依赖yum localinstall 报错信息依赖包没下载全
服务启动失败journalctl -u postgresql-14 -n 50数据目录权限/属主错误
本机能连远程不行ss -tlnp | grep 5432防火墙未放行/SELinux 拦截
连接超时ping 服务器IP网络不通或安全组未放行
密码认证失败\du 查看用户密码未设置或认证方式不一致
修改配置不生效show listen_addresses;没重启服务或配置文件错了

8. 写在最后:离线安装的实操体会

折腾完这一整套流程,我自己最大的感受是:离线安装本身并不难,难的是把所有意外提前想清楚。比如依赖下载不完整、防火墙忘放行、pg_hba.conf 规则写错位置,每一个看起来都是小问题,但组合在一起就能耗掉你半天时间。

我个人的建议是:如果你有条件,先在测试环境(和正式环境相同 OS 版本)完整跑一遍这套流程,把用到的 RPM 包、依赖清单、配置文件都记录下来,再进正式环境操作。这样到了现场基本就是复制粘贴,既快又稳。另外,装完之后一定记得做一次基础备份验证,确认pg_dump能正常导出数据,这也是我一直以来的习惯——不怕一万,就怕万一。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询