news 2026/10/19 13:13:37

Linux服务器部署PostgreSQL 12.0完整教程:从yum源到远程访问配置

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux服务器部署PostgreSQL 12.0完整教程:从yum源到远程访问配置

最近帮某项目组在一台Linux服务器上部署PostgreSQL 12.0,从环境准备到正式接入业务花了大半天。整个过程不算复杂,但因为细节比较多,坑也不少,所以整理一版详细步骤出来。如果你是第一次在Linux上部署PostgreSQL,照着这篇走完,基本能避掉大部分常见问题。文章会覆盖环境选型、yum源安装与源码编译两个方案、数据目录初始化、远程认证配置、基础验证以及我在实际部署中踩到的几个典型坑。安装版本以12.0为例,方法对后续12.x小版本同样适用;系统方面以CentOS 7为主,Ubuntu等发行版我会在差异处单独说明。

1. 选环境与版本:先想清楚再动手

1.1 为什么选12.0而不是追新版本?

很多生产环境跑的还是12或13,原因很简单:经过几年打磨,稳定性和周边生态都验证过了。对于大多数业务系统,12.0的并行查询、分区表增强、索引改进已经完全够用。选版本时我通常看两条:一是业务依赖的第三方扩展是否兼容,二是团队过往运维经验集中在哪个版本。如果没人用过某个太新的版本,上线后遇到问题只能现学,风险反而高。

这篇文章拿12.0当例子,不是说非要装12.0不可。如果你们团队已经在用12.x的小版本,比如12.9、12.15,部署步骤和本文完全一样。版本号后面几位通常只是补丁修复,不会改变initdb、systemd、pg_hba.conf这些核心操作。所以看到“12.0”不要紧张,按后面步骤来就好。

1.2 确认操作系统与基础资源

这次用的是CentOS 7.9,这也是目前比较常见的生产系统。如果你用的是Ubuntu 20.04,部署步骤大同小异,只是包管理工具和init脚本略有差别。动手之前先确认几件事:

  • 系统版本:cat /etc/redhat-release或uname -a,确认是64位系统。
  • 磁盘空间:df -h,建议数据目录所在分区剩余空间至少在10GB以上,具体按业务量预留。
  • 内存情况:free -m,PostgreSQL对内存比较敏感,4GB起步比较舒服;小内存也能跑,但后面参数需要认真调。
  • 当前用户权限:是否有root权限或sudo权限。PostgreSQL的数据目录、系统服务管理都需要权限,别把时间浪费在权限不够的报错上。

另外推荐顺手确认一下是否有外网访问权限。yum源安装需要从官方仓库拉包,如果服务器处于内网隔离环境,要走离线RPM包方案,那准备的东西就完全不一样了。先把这个前提搞清楚,后面才不会白忙。

1.3 确认安装方式:yum源还是源码

Linux下安装PostgreSQL主要有两条路径:官方yum源安装RPM包,以及源码编译安装。两条路径我都走通过,差异整理如下:

对比项yum源安装源码编译
安装速度快,依赖自动解决慢,需要编译时间
灵活性安装路径固定可自定义prefix
systemd管理自带服务脚本需要自己写unit文件
适合场景绝大多数生产环境定制化要求高的场景
后续维护升级打补丁方便升级麻烦,要重新编译

我的建议是:没有任何特殊要求的情况下,直接用yum源装RPM包最省心。源码编译虽然听起来“可控”,但后续维护成本高,尤其是版本升级时,每次重新编译都要重新踩一遍坑。所以本文主线先讲yum源安装,源码编译只把关键命令列出来备用。

2. 使用yum源快速安装PostgreSQL 12.0

2.1 配置官方YUM源

以CentOS 7为例,PostgreSQL官方提供了一个统一的repo安装包,一行命令就能把源配置好。执行前确认当前是root或者有sudo权限。

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

这条命令执行后,系统里会多出几个以pgdg开头的repo文件,里面包含了PostgreSQL各个版本、各个组件的软件包来源。如果你用的是CentOS 8或RHEL 8,还要额外执行一条命令,把系统自带的PostgreSQL模块禁用掉,否则安装时容易出现包冲突:

yum -q module disable postgresql

然后刷新缓存:

yum makecache

这里有个经验之谈:repo包安装后,尽量先看一眼/etc/yum.repos.d/pgdg-redhat-all.repo,确认里面的enabled状态符合预期。默认通常没问题,但有些安全加固的服务器会调整repo文件全局配置,导致后面的包搜不到。排查时先从这里开始。

2.2 安装服务端组件与验证

源配好之后,安装命令很简单:

yum install -y postgresql12-server postgresql12-contrib

postgresql12-server是数据库服务端,必装;postgresql12-contrib是扩展组件集,里面包含了pg_stat_statements、postgres_fdw等常用工具,建议一起装上。如果后续要用PostgreSQL地理信息扩展PostGIS,还可以再装postgresql12-postgis,但本文先不展开。

安装完成后,可执行文件被放在/usr/pgsql-12/bin目录下,数据目录默认是/var/lib/pgsql/12/data。注意:RPM安装过程会自动创建系统用户postgres,并且数据目录的属主也会被设置成postgres:postgres。这一刻起,默认就不要用root身份去操作数据库了。

确认版本:

/usr/pgsql-12/bin/postgres --version

正常情况下输出postgres (PostgreSQL) 12.x。如果提示找不到命令,检查一下是否安装了postgresql12-server,或者看看/usr/pgsql-12/bin是否在PATH里。这台机器可能同时装了其他PostgreSQL版本,一定要带上路径执行,避免用错二进制。

2.3 如果必须走源码编译:关键命令与区别

少数场景下必须从源码编译,比如需要指定安装路径、静态编译、或者定制某些编译参数。基本流程如下:

# 下载源码包并解压 tar -xjf postgresql-12.0.tar.bz2 cd postgresql-12.0 # 配置、编译、安装 ./configure --prefix=/opt/pgsql12 --with-openssl make -j4 make install

--prefix指定安装目录,--with-openssl是为了支持SSL连接。编译完成后,还需要手动创建postgres操作系统用户,把/opt/pgsql12/bin加入PATH,再执行initdb初始化数据目录。如果想让systemd管理,还得自己写一个postgresql-12.service文件。

我在刚开始接触PostgreSQL时也试过源码编译,当时的感受是:不是说这条路多难,而是编译出来的版本没有官方RPM那种“开箱即用”的稳定性,很多默认配置和目录结构都要自己维护,出问题后网上查到的资料大多基于RPM安装,对不上路径,排查效率很低。所以文章后面都以yum源安装的路径为准。

3. 初始化数据目录:从环境变量到initdb参数

3.1 使用官方初始化脚本

RPM安装完成后,数据目录还是空的,必须先初始化。官方提供了一个简化脚本:

/usr/pgsql-12/bin/postgresql-12-setup initdb

这个脚本本质上是以postgres用户身份执行initdb -D /var/lib/pgsql/12/data,同时把数据目录权限和属主都设置好。执行完会看到类似这样的输出:

Initializing database ... OK

如果看到OK,说明数据目录已经生成。此时/var/lib/pgsql/12/data下面会出现base、global、pg_wal、postgresql.conf、pg_hba.conf等目录和文件。pg_wal就是WAL日志目录,在PostgreSQL 12里已经改了这个名字,对应旧版本的pg_xlog,做目录规划时要记清楚。

如果你不喜欢官方脚本,也可以手动初始化:

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

手动执行时建议先导出环境变量,避免后续操作时路径混乱:

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

3.2 initdb常用参数怎么选

手动初始化时,我会加上这几个参数:

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

各参数作用如下:

参数作用说明
-D指定数据目录必须和启动服务时保持一致
-E默认编码生产环境建议UTF8,避免中文乱码
--locale排序规则需要确认系统已安装对应locale
-U超级用户名默认postgres,不建议改名
-W提示设置密码初始化时顺手把超级用户密码设好

如果服务器系统语言不是英文环境,比如是zh_CN.UTF-8,--locale也可以写成对应值。需要提前用locale -a查看系统已支持的locale列表。有一个常见问题:系统本身没安装en_US.UTF-8locale,强行指定会在initdb阶段直接报错,这时候要么换一个已存在的locale,要么先安装对应的语言包。

另外,命令最后还可以追加--auth-local=peer --auth-host=scram-sha-256,这样初始化出来的认证配置更安全。不过我们后面还会集中改认证规则,这里先不纠结。

3.3 启动服务并设置开机自启

初始化完成后,用systemd启动:

systemctl start postgresql-12 systemctl enable postgresql-12 systemctl status postgresql-12

正常状态会显示active (running)。如果启动失败,第一件事不是反复尝试,而是看日志:

journalctl -u postgresql-12 -n 50

日志通常会直接告诉你原因:数据目录没初始化、端口被占用、权限不对、PGDATA路径不对等等。我在实际部署中遇到过几次启动失败,基本都是数据目录权限被之前的解压或复制操作搞乱了,重新用chown -R postgres:postgres /var/lib/pgsql/12修正后就能起来。

3.4 数据目录权限问题小记

PostgreSQL对数据目录权限很敏感,目录属主必须是非root用户,通常是postgres。如果目录权限变成777,或者属主是root,服务会直接拒绝启动。很多人喜欢用root解压包、复制数据目录,这一步最容易埋雷。

正确做法是,数据目录创建和初始化全程都通过sudo -u postgres来执行,不要直接切到root下去初始化。如果已经出了问题,修复命令也很简单:

chown -R postgres:postgres /var/lib/pgsql/12 chmod 700 /var/lib/pgsql/12/data

然后再启动服务。这个细节看着不起眼,但生产环境处理过不止一次,值得单独记一笔。

4. 认证配置与远程访问:pg_hba.conf和postgresql.conf是重头戏

4.1 先备份配置文件再动手

PostgreSQL的两个核心配置文件都在数据目录下:

  • /var/lib/pgsql/12/data/postgresql.conf
  • /var/lib/pgsql/12/data/pg_hba.conf

改任何配置之前,先备份是一个好习惯。哪怕只是加一行,也要让你能随时回滚:

sudo cp /var/lib/pgsql/12/data/postgresql.conf /var/lib/pgsql/12/data/postgresql.conf.bak sudo cp /var/lib/pgsql/12/data/pg_hba.conf /var/lib/pgsql/12/data/pg_hba.conf.bak

这个习惯在服务器交接、多人协作时特别重要。我见过不少环境,配置被人改乱了,只知道某个时间点之前还是好的,但手里没有备份,只能靠记忆和文档逐步恢复,非常被动。

4.2 修改postgresql.conf的监听与端口

数据库默认只监听localhost,外部无法访问。要允许远程连接,需要修改postgresql.conf中的监听地址。用文本编辑器打开配置文件,找到这一行:

#listen_addresses = 'localhost'

改成:

listen_addresses = '*' port = 5432

*表示监听所有网络接口,最简单。如果只想监听特定内网IP,也可以写逗号分隔的地址列表,比如:

listen_addresses = '127.0.0.1,192.168.1.100'

改完postgresql.conf后需要重启数据库才能生效:

systemctl restart postgresql-12

重启前建议先执行postgres -C listen_addresses或者用pg_ctl检查配置是否有语法错误。PostgreSQL对配置文件的语法要求不算严格,但写错了可能会导致服务起不来,重启前检查能省一轮折腾。

4.3 用pg_hba.conf控制谁能连

pg_hba.conf是访问控制的核心文件,它决定哪个IP、哪个用户、用哪种认证方式可以连哪个数据库。规则是“从上到下匹配,匹配后立即停止”。每一行格式如下:

连接类型 数据库 用户名 客户端地址 认证方法

常用规则举例:

# 本地socket连接,用peer认证 local all postgres peer # 允许内网192.168.1.0/24网段用密码认证 host all all 192.168.1.0/24 scram-sha-256 # 允许指定IP连接指定库 host appdb app_login 10.0.0.5/32 scram-sha-256

peer认证是指数据库用户和Linux系统用户同名时,直接以系统用户身份连接,不需要密码。scram-sha-256是PostgreSQL 12默认推荐的密码加密方式,比md5更安全。虽然连接规则里也可以写md5,但我建议新部署一律用scram-sha-256。

规则顺序很重要。前面写了拒绝规则,后面写允许规则也不会生效。所以需要新增网段授权时,尽量把允许规则放在文件靠前位置,或者明确放在其他规则之前。改完pg_hba.conf不用重启数据库,执行reload就行:

systemctl reload postgresql-12

4.4 给超级用户设置密码并创建业务账号

本地连接时,postgres用户可以靠peer认证直接登录,不需要密码。但远程连接用scram-sha-256认证时,必须有密码。所以初始化完一定要设置密码:

sudo -u postgres psql

进入psql后执行:

ALTER USER postgres PASSWORD '这里填强密码';

强烈建议不要直接用超级用户跑业务。创建专用账号和数据库更合理:

CREATE ROLE app_login LOGIN PASSWORD 'app_password'; CREATE DATABASE appdb OWNER app_login;

这样应用连接时只用app_login连接appdb,权限控制更清晰。以后即使应用密码泄露,影响范围也被限制在单个库里。如果同一台机器上要跑多个应用,就建多个角色、多个库,互不干扰。

5. 部署完成后的验证:从命令行到几个常用检查

5.1 本地连接与版本确认

服务启动后,第一步是从本地连进去,确认基本功能正常:

sudo -u postgres psql

如果看到postgres=#提示符,就说明服务正常、socket连接没问题。执行几个基础命令确认环境信息:

SELECT version(); SHOW server_version; SHOW port; SHOW max_connections;

max_connections默认通常是100,小应用够用;高并发场景要结合内存调大,但不能无限调,后面会提到内存估算。SHOW port能看到当前监听端口,如果这里显示的跟postgresql.conf里设置的不一致,就要检查是否有多个配置来源。

5.2 建表读写验证

为了确认数据文件、WAL写入、查询器都能正常工作,快速建一张测试表做闭环验证:

CREATE TABLE test( id serial primary key, name text, created_at timestamp default now() ); INSERT INTO test(name) VALUES ('hello'); SELECT * FROM test;

能正常插入和查询,基本说明这套部署是可用的。如果建表时提示权限不足,多半是当前角色不是数据库owner,或者没有schema权限。用app_login连接时,默认在publicschema下建表通常没问题;但生产库建议在初始化数据库后把public权限收一收,只给业务账号必要的权限。

5.3 查询当前连接和锁状态

部署完成后,还要确认服务端拿到的连接是不是预期来源。执行这条SQL:

SELECT datname, usename, client_addr, state FROM pg_stat_activity WHERE datname = 'appdb';

可以看到当前哪些客户端IP在连接,连接状态是active还是idle。如果出现大量idle in transaction连接,后面就要关注应用是否有长事务。这个命令在运维排查时很常用,建议记下来,不要每次都翻文档。

5.4 快速保存一份基线配置

第一次把配置调稳之后,建议导出一份配置基线存到/etc或者运维平台上:

sudo cp /var/lib/pgsql/12/data/postgresql.conf /etc/postgresql-12.conf.bak sudo cp /var/lib/pgsql/12/data/pg_hba.conf /etc/pg_hba-12.conf.bak

这样做的好处是,以后只要发现线上配置被人改乱,可以直接用这份基线对比,快速定位哪些参数偏离了默认值。我在多个环境里都遇到过配置漂移:管理员调过一两行参数,后来没人记得,半年后排查性能问题才发现某个参数设置得不合理。有基线存档,这个坑就能轻松绕开。

6. 部署过程中最容易踩的坑与排查思路

6.1 systemctl start postgresql-12一直失败

这个坑出现频率最高。现象是:

Job for postgresql-12.service failed because the control process exited with error code.

原因通常有三个。第一,数据目录没有初始化,解决办法是回到第3章执行postgresql-12-setup initdb。第二,数据目录权限不对,解决办法是chown -R postgres:postgres /var/lib/pgsql/12,再chmod 700数据目录。第三,端口5432被占用,用ss -lntp | grep 5432看一下。

排查这类问题,最高效的手段是日志:

journalctl -u postgresql-12 -n 50

日志会直接给出根因,不需要猜。有些朋友遇到服务起不来,第一反应是反复systemctl restart,其实每次重启只会打印同样的错误,问题根本没有解决。先看日志,再动手,是运维最基本的工作习惯。

6.2 远程连接失败的四种原因与排查链路

远程连PostgreSQL失败,常见表现和原因可以按顺序排查:

现象可能原因检查位置
连接被拒绝服务未监听或者防火墙拦截ss -lntp、postgresql.conf
连接超时网络不通或云安全组未放行ping、telnet、安全组规则
要求密码但密码正确也不对认证方式或密码不一致pg_hba.conf、password_encryption
提示no pg_hba.conf entry缺少匹配规则或顺序不对pg_hba.conf

如果是Connection refused,优先看服务监听:

ss -lntp | grep 5432

再看防火墙。CentOS 7默认用firewalld:

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

如果服务器在云平台,还需要去控制台确认安全组是否放行了5432入方向。很多远程连不上的问题,不是PostgreSQL本身配置错了,而是安全组或者防火墙把端口挡了。按“客户端到服务端链路”一层层查,比盲目改配置文件快得多。

6.3 别用trust,认证方式要和网络环境匹配

PostgreSQL支持trust认证,意思是“只要网络能到这个端口,不需要密码就能连”。这个选项在单机本地的开发环境可能觉得很方便,但一旦暴露到网络,风险非常大。不要因为测试环境赶时间就用trust,后面忘了改,线上被扫描到就麻烦了。

我这里遇到过一个印象很深的案例:某开发环境把pg_hba.conf里一行改成了trust,结果当天就被内网扫描工具连上,把整张表都清空了。虽然数据有备份,但恢复过程折腾了大半天。所以在任何环境里,认证方式都建议至少用scram-sha-256,密码也要设强一点。

6.4 内存参数随手调:从默认值到可运行

部署完如果发现查询慢,不一定先加硬件。先看几个常用内存参数:

参数默认值建议值
shared_buffers128MB物理内存的1/4,不超过8GB
effective_cache_size4GB接近操作系统可用缓存
work_mem4MB排序运算可适当调高,考虑并发
maintenance_work_mem64MB建索引、vacuum时使用

shared_buffers不是越大越好,太大反而增加维护成本;work_mem乘以最大并发数可能爆内存,要整体估算。我曾在2G内存的云主机上把shared_buffers调到512MB,结果触发OOM,后来调回256MB才稳定。调参一定要结合free -m看总内存,特别是小内存机器,先保守再调高。

6.5 备份策略至少要有一个

部署完成到最后一步,备份策略不能落下。最简单的是逻辑备份:

/usr/pgsql-12/bin/pg_dump -h 127.0.0.1 -U app_login -d appdb -F c -f appdb.dump

恢复时用:

/usr/pgsql-12/bin/pg_restore -d appdb appdb.dump

pg_dump适合中小库,备份和恢复都比较直观。pg_basebackup适合做物理备份和流复制,可以做时间点恢复(PITR),但配置相对复杂,这里不展开。无论如何,数据无价,不要把部署完成的瞬间当成结束。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 13:12:47

open-code-review:可插拔多语言代码审查协议

1. 项目概述:这不是又一个代码审查工具,而是一套可插拔、可演进的开源代码审查协议“open-code-review”这个标题乍看像某个GitHub仓库名,但真正值得深挖的,是它背后隐含的一整套范式迁移——它不是在“做一个更好的Code Review U…

作者头像 李华
网站建设 2026/10/19 13:09:53

云设计SaaS公司9个月营收5.5亿,IPO备案背后的技术护城河

关注ToB软件和设计工具赛道的人,最近应该都刷到过同一条消息:一家做云原生3D设计软件的公司,正式拿到了IPO备案,过去9个月交出5.5亿元营收的成绩单,还成为当地创业圈里最早走到敲钟关口的那批独角兽之一。我把这条新闻…

作者头像 李华
网站建设 2026/10/19 13:09:33

代码审查流于形式?open-code-review 教你搭建自动化质量防线

先聊点直接的:代码审查这玩意,在很多团队里就是个摆设。PR 挂着三天没人理,临上线前被催着点个 Approve,甚至有人直接闭眼通过——代码质量全靠测试同学拿命去顶。我做过几年一线开发,也带过小团队,深知这不…

作者头像 李华
网站建设 2026/10/19 13:09:22

WebDeveloper靶机全流程复盘:从WordPress弱口令到sudo提权

最近在本地镜像库里把 WebDeveloper 靶机重新打了一遍,这台机器算是入门级渗透测试里非常有代表性的一个。很多朋友在群里问这条攻击链路,要么卡在 WordPress 那一步不知道怎么往下走,要么拿到了 Web Shell 却提不了权,最后只能看…

作者头像 李华
网站建设 2026/10/19 13:06:13

TensorFlow分布式FFT:原理、方案与踩坑实战

在TensorFlow里正儿八经写过频域代码的开发者,大概率都撞过同一堵墙:单卡上FFT跑得飞快,batch一放大、设备一多,分布式一开,要么内存直接爆掉,要么算出来的频谱对不上号。原因其实很本质——FFT不是局部算子…

作者头像 李华
网站建设 2026/10/19 13:06:10

Open Code Review:基于CLI+Git+LLM的轻量级代码评审范式

1. “open-code-review”不是工具名,而是正在发生的开发范式迁移“open-code-review”这个词最近在技术社区里频繁出现,但它既不是某个已发布的开源项目名称,也不是某家公司的商业产品代号。我第一次在 Slack 频道里看到它,是同事…

作者头像 李华