资讯动态

Linux下源码编译安装PostgreSQL 12.0实战指南

发布时间:2026/10/14 18:19:49 来源:尧图企业网站定制
我们聊聊怎么在Linux环境下把PostgreSQL 12.0老老实实装好、配好。写这篇是因为我最近刚好在一台CentOS 7.9的机器上从源码编译部署了一套PG 12.0整个过程踩了几个不大不小的坑网上很多教程都只讲“敲命令”不讲“为什么”导致出了问题根本不知道从哪里排查。这次我一次性把完整的部署思路、操作步骤、配置要点和排错记录整理出来希望能帮正在折腾PG 12.0的同学省点时间。这套部署方案适合这几类人打算从源码编译安装PostgreSQL的运维或DBA、正在搭建测试或生产环境的开发同学、以及对Linux操作有一定基础但没系统部署过数据库的人。如果你只是想yum install postgresql-server装个完事那这篇可能有点超纲但如果你想要掌控安装路径、编译参数、数据目录、运行参数这些细节那这篇正好是你要的。1. 方案选型为什么选择源码编译而不是包管理器安装很多人第一反应是装PostgreSQL直接用yum或者apt不就行了为什么非要源码编译这个问题的答案取决于你部署的环境是什么性质。1.1 包管理器安装的局限性如果你用的是发行版自带的PostgreSQL版本号通常不会太新。比如CentOS 7自带的PostgreSQL是9.2这已经是老古董了。即使通过第三方源装到12.x也会遇到另外一个问题安装路径和配置文件布局被发行版的打包规范锁死了。/var/lib/pgsql、/var/log/postgresql、systemd管理脚本这些都是发行版自己的约定虽然用着省心但你在一些特殊场景下会很难受数据目录需要放在独立的数据盘、SSD、或者挂载点特殊的存储上发行版的默认配置改起来麻烦。需要定制编译参数比如开启--with-openssl、--with-python、--with-pam或者调整一些默认的编译优化选项。需要在同一台机器上共存多个版本的PostgreSQL发行版打包的版本管理方式很难做到多版本自由切换。1.2 源码编译的真正优势源码编译安装最大的好处是路径完全自己掌控。你可以在编译时指定--prefix/opt/pgsql12把整个PostgreSQL“关”在一个独立的目录里后续卸载只需要删除这个目录完全不污染系统其他部分。升级的时候也可以直接编译新版本到新目录通过切换PATH和PGDATA环境变量来实现平滑切换。另外源码编译能让你更清楚PostgreSQL的依赖关系。装PG不只是装一个数据库它还涉及readline、zlib、openssl等一堆基础库编译时能知道哪些库找得到、哪些库缺失、影响哪些功能这对于后续的排错和维护都是底层的认知积累。我的建议是测试环境、学习目的优先源码编译能学到东西。快速搭建、非核心系统用包管理器更方便。生产环境取决于公司的运维规范但源码编译至少是一个可选项值得掌握。1.3 我选择的部署参数方案这次部署我用的方案给你一个明确的参考项目配置操作系统CentOS 7.9内核3.10.0PostgreSQL版本12.0源码包安装目录/usr/local/pgsql12数据目录/data/pgdata运行用户postgres系统用户端口5432编码UTF8编译选项--prefix/usr/local/pgsql12 --with-openssl --with-perl --with-python注意数据目录和生产安装目录分开这是生产环境的基本素养。安装目录可以随系统盘重装而丢失但数据目录必须放在独立的存储上。2. 安装前准备工作详解很多人安装失败一多半是挂在环境依赖上。顺手敲一敲./configure报个错说缺这个缺那个然后一个个补补完重新configure又报新的缺失来回折腾好几趟。所以先花10分钟把准备工作做完后面全程顺滑。2.1 操作系统环境和基础依赖包CentOS 7系列的默认源里没有PostgreSQL 12但这不要紧我们只需要装编译工具链和依赖库。先更新系统自带的源然后安装这些包yum update -y yum groupinstall -y Development Tools yum install -y readline-devel zlib-devel openssl-devel perl-ExtUtils-Embed python3-devel解释几个关键包的作用readline-devel这是命令行交互编辑功能的依赖。没有它psql虽然能启动但你在终端里敲SQL语句时不能用上下键翻历史、不能用左右键编辑体验极其痛苦。zlib-develPG的数据备份和恢复工具需要压缩功能这个库会用来处理pg_dump的压缩输出。openssl-devel如果你要启用SSL连接这个库是必须的生产环境必须要开。perl-ExtUtils-Embed和python3-devel分别用于支持PL/Perl和PL/Python过程语言。如果确定用不到可以不装但建议装齐免得后续要用时重新编译一遍。还有一个容易被忽略的细节你最好有一个非root账户来做这件事。虽然configure和make阶段可以用root但make install往/usr/local写入文件时用root没问题后面initdb和启动数据库进程官方和社区都强烈不建议用root跑。我的建议是提前创建好专用用户。useradd postgres mkdir -p /usr/local/pgsql12 mkdir -p /data/pgdata chown -R postgres:postgres /usr/local/pgsql12 /data/pgdata2.2 PostgreSQL 12.0源码包获取与校验PostgreSQL 12.0的源码包可以从官方下载页面获取文件名通常类似postgresql-12.0.tar.gz。下载完成后建议先校验SHA256值防止下载文件损坏或被篡改。这一步很多人会跳过但如果你经历过一次“源码包下了一半make的时候各种莫名其妙的报错”你就知道校验的重要性了。wget https://ftp.postgresql.org/pub/source/v12.0/postgresql-12.0.tar.gz sha256sum postgresql-12.0.tar.gz拿到官方发布页的SHA256值比对一下一致再解压。tar -xzf postgresql-12.0.tar.gz cd postgresql-12.0解压之后建议看一眼源码根目录下的INSTALL文件和README文件里面有一些编译和部署的基本说明比网上很多二手教程都准确。2.3 编译前的系统资源评估这一步是我自己的习惯装数据库之前先看一眼系统资源免得装到一半发现磁盘不够或者内存小得可怜导致初始化数据库失败。df -h free -m nproc编译PG 12.0需要大约300MB的临时磁盘空间主要是中间目标文件加上源码包和解压后的文件建议留出1GB以上的空闲空间。内存建议至少1GB空闲。如果机器内存很小initdb时指定较小的shared_buffers后面调大即可。CPU核心数决定make的并行编译效率。我一般用make -j$(nproc)直接跑满所有核心如果机器负载高就适当降级。3. 编译安装与初始化部署实操这部分是整个流程的核心步骤。我尽量把每个步骤的“为什么”也说清楚而不是单纯贴命令。3.1 configure配置与编译在源码根目录执行configure我这次用的参数是./configure --prefix/usr/local/pgsql12 --with-openssl --with-perl --with-python把这个命令拆开看--prefix/usr/local/pgsql12指定安装根目录。所有二进制文件、库文件、头文件都会装到这个目录下卸载就是删这个目录干净利落。--with-openssl启用SSL支持。虽然测试环境不一定用SSL但生产环境几乎必须而且前期不启用后期想加就得重新编译代价很大。--with-perl和--with-python启用PL/Perl和PL/Python。这两个不是必需项但我习惯装齐方便后续写存储过程时选择语言。如果configure这步出现“No package found”之类的错误那就是前面2.1节的依赖没装全。仔细看错误信息缺什么补什么再重新跑configure。configure成功之后会生成一个Makefile接着编译make -j$(nproc)这一步根据机器性能等待时间从几分钟到半小时不等。编译输出会刷屏不用担心只要最后没有Error字样就行。编译完成后执行安装make install到这里二进制文件已经装到/usr/local/pgsql12/bin目录下了但你还没法直接使用因为动态库路径还没配置。运行psql的时候系统会找不到PG自带的动态库。这里就需要设置环境变量echo export PATH/usr/local/pgsql12/bin:\$PATH /etc/profile.d/pgsql.sh echo export LD_LIBRARY_PATH/usr/local/pgsql12/lib:\$LD_LIBRARY_PATH /etc/profile.d/pgsql.sh source /etc/profile.d/pgsql.sh注意LD_LIBRARY_PATH这个变量在排错时的作用如果你忘记设置执行psql会报error while loading shared libraries: libpq.so.5看到这个错第一反应就应该是动态库路径没配好。另外如果你需要安装额外的扩展模块比如postgis之类的可以在contrib目录下再执行一次编译安装cd contrib make -j$(nproc) make installPG 12.0的源码包自带contrib模块包含一些常用工具和扩展比如pg_stat_statements这个对后续监控SQL性能非常重要建议顺手装掉。3.2 创建数据目录并初始化数据库实例安装好二进制文件之后接下来就是初始化数据库实例。这个步骤会把一个空的数据目录变成一套完整的、可直接启动的数据库集群。先用postgres用户操作。切换用户之前先确认/data/pgdata目录归属正确chown -R postgres:postgres /data/pgdata su - postgres mkdir -p /data/pgdata /usr/local/pgsql12/bin/initdb -D /data/pgdata -E UTF8 --localeen_US.UTF-8这里解释几个initdb的关键参数-D指定数据目录。这个目录会存放PG的所有数据文件、WAL日志、配置文件等。-E UTF8指定数据库集群的默认编码。现在新项目基本都用UTF8这一步能省掉后面建库时的编码麻烦。--localeen_US.UTF-8指定本地化规则。这里有个细节需要注意如果你的系统没有安装en_US.UTF-8这个localeinitdb会报错。可以用locale -a先查看系统支持的locale列表挑一个合适的填进去。initdb成功之后仔细观察输出信息里面有几条关键提示Success. You can now start the database server using:后面跟着启动命令。提示你需要设置pg_ctl的-w参数等待启动完成。提示默认生成了一个超级用户名字和当前操作系统用户同名这里是postgres。初始化完成之后数据目录下的文件结构很有必要了解一下PG_VERSION记录数据库主版本号12.0会写12。postgresql.conf主配置文件几乎所有运行参数都在这里。pg_hba.conf客户端认证配置文件决定哪些IP、哪些用户可以连接数据库。base/实际存储数据库数据的目录。pg_wal/WAL日志目录数据库崩溃恢复就靠它。3.3 启动数据库并验证基础连接初始化完成并不意味着可以马上使用PG 12.0的默认配置很保守监听地址默认只允许本地连接。先手动启动一次验证配置没问题/usr/local/pgsql12/bin/pg_ctl -D /data/pgdata -l /data/pgdata/logfile.log start这里的-l参数指定日志文件路径PG会把服务日志写到这个文件里。如果启动失败第一件事就是看这个日志文件。启动成功的标志是命令行没有任何错误提示。再用ps验证一下进程状态ps -ef | grep postgres正常情况下你能看到至少一个postgres主进程以及若干个辅助进程。主进程的父进程ID通常是1表示它已经守护化。接着用psql尝试连接psql -U postgres -d postgres如果连接成功你会进入psql交互界面输入select version();验证版本号应该返回PostgreSQL 12.0。到这里一套最基础的PG 12.0就算跑起来了。但离“可用的生产实例”还差得远下面进入配置调优环节。4. 核心配置与安全加固刚刚启动的PG还是一个“裸奔”状态很多参数都是保守默认值也完全没有网络访问控制。这一章要解决的是把PG配置成适合实际使用的状态。4.1 监听地址与连接认证配置默认情况下PG只监听localhost这意味着远程客户端无法连接。修改/data/pgdata/postgresql.conf中的配置listen_addresses * port 5432这里listen_addresses *代表监听本机所有网络接口。如果机器有多个网卡但只想监听内网IP也可以写成具体IP地址比如listen_addresses 192.168.1.10这样更安全。光改监听地址还不够PG还有第二道关卡pg_hba.conf认证配置。这个文件控制谁能连、从哪连、怎么认证。默认配置只允许本地trust认证这非常危险因为任何能登录你Linux机器的人都能无密码直接连数据库。我建议至少把配置改成这样# 本地Unix套接字连接使用scram-sha-256认证 local all all scram-sha-256 # 本机IPv4回环连接 host all all 127.0.0.1/32 scram-sha-256 # 内网网段连接按实际网段调整 host all all 192.168.1.0/24 scram-sha-256关于认证方式PG 12.0里推荐scram-sha-256。这个加密方式比旧的md5更安全PG 10以后就能用了PG 12里也是默认推荐的。具体原理不展开简单说就是密码不会明文传输而且加了随机盐暴力破解难度更高。改完配置后重启数据库或者用pg_ctl reload让配置生效/usr/local/pgsql12/bin/pg_ctl -D /data/pgdata reload注意reload和restart的区别reload只重新加载配置文件不断开正在运行的连接restart会终止所有连接再重新启动。修改监听地址和认证配置只需要reload但如果改了内核共享内存相关参数可能需要restart。修改了认证方式之后还需要给postgres用户设置一个密码否则无法用密码登录ALTER USER postgres PASSWORD 你的强密码;4.2 关键性能参数调优PostgreSQL 12.0的默认配置对生产负载来说完全不够看。但这不意味着你要照抄网上的“万能配置”—每个人机器的内存、CPU、磁盘都不一样盲目套用比用默认值更糟。我分享一下我的调优思路以及每个参数背后的权衡。先看几个最核心的内存参数在postgresql.conf中shared_buffers 1GB effective_cache_size 3GB work_mem 16MB maintenance_work_mem 256MB这几个参数的关系我用一个不严谨但很好懂的类比来解释shared_buffers数据库自己的“高速缓存池”所有进程共享的。一般建议设为机器物理内存的25%。比如8GB内存的机器设2GB比较合理。但不要超过32GB因为PG在多核扩展上对超大共享内存的支持有限。effective_cache_size操作系统文件缓存的大小。这个值是对优化器的“提示”让它知道系统里有多少可用缓存从而倾向选择索引扫描还是顺序扫描。一般设为物理内存的50%-75%。work_mem单个排序或哈希操作可用的内存。注意这是“每个操作”的配额不是全局的。如果同时有20个排序操作每个用16MB那就是320MB。设太大容易导致内存OOM。maintenance_work_memVACUUM、CREATE INDEX这类维护操作的内存可以设大一点毕竟这类操作通常不会并发执行。然后看检查点相关的参数checkpoint_completion_target 0.9 max_wal_size 2GB min_wal_size 1GBmax_wal_size决定了WAL文件能膨胀到多大才触发检查点。增大这个值能减少磁盘写压力但崩溃恢复时WAL重放的时间也会变长。2GB对中等负载的机器是个合理的起点。连接数相关参数也要根据业务评估max_connections 200默认值100通常不太够用但也不是越大越好。每个连接都会占用一定内存计算公式大致是shared_buffers加work_mem乘连接数。200个连接、每个分配16MB work_mem理论上限就是3.2GB扛不住的话就该考虑引入连接池了。我强烈建议把pg_stat_statements这个扩展装上它能帮你分析SQL性能瓶颈-- 在postgresql.conf中 shared_preload_libraries pg_stat_statements -- 重启数据库后执行 CREATE EXTENSION pg_stat_statements;装了之后你可以查询pg_stat_statements视图按执行时间和调用次数排序快速定位最消耗资源的SQL。4.3 开机自启服务配置最后一步是把PG配置成系统服务保证机器重启后数据库能自动拉起来。这里用systemd管理的方式创建一个服务单元文件vim /etc/systemd/system/postgresql-12.service内容如下[Unit] DescriptionPostgreSQL 12.0 database server Afternetwork.target [Service] Typeforking Userpostgres Grouppostgres EnvironmentPGDATA/data/pgdata ExecStart/usr/local/pgsql12/bin/pg_ctl -D /data/pgdata -l /data/pgdata/logfile.log start ExecStop/usr/local/pgsql12/bin/pg_ctl -D /data/pgdata stop ExecReload/usr/local/pgsql12/bin/pg_ctl -D /data/pgdata reload TimeoutSec60 [Install] WantedBymulti-user.target保存后执行systemctl daemon-reload systemctl enable postgresql-12 systemctl start postgresql-12这里有个坑需要注意Typeforking是告诉systemdPG启动后主进程会fork出子进程并后台化。pg_ctl的启动行为正好符合这种情况所以配置是匹配的。如果你把所有参数换成pg_ctl -w等待启动完成Type可以换成simple但原理不同千万别混用。5. 常见问题与深入排查技巧这部分是我觉得最值钱的。安装部署过程中遇到的错误网上搜解决方案往往一搜一大把但如果你能自己看一眼错误信息、判断出问题方向能省下大量无效搜索时间。5.1 initdb失败locale不存在错误特征initdb: error: invalid locale name: en_US.UTF-8原因分析系统中没有安装对应的locale包。CentOS 7 最小化安装经常缺。解决方案locale -a # 查看系统已安装的locale yum install -y glibc-langpack-en # 安装英文locale包装完之后再跑initdb。如果你不需要在意locale也可以用--localeC或者--no-locale跳过这个坑但这会影响字符串排序等行为不确定的话还是装locale包最稳妥。5.2 启动失败日志文件打不开或权限不足错误特征pg_ctl: could not open log file /data/pgdata/logfile.log: Permission denied原因分析日志文件对postgres用户没有写权限。这种问题通常是之前用root创建了日志文件或者多次切换用户导致属主混乱。解决方案chown -R postgres:postgres /data/pgdata这条命令我建议加到部署脚本里每次启动前执行一遍能避免大量低级问题。5.3 远程连接失败Connection refused错误特征psql: error: could not connect to server: Connection refused排查步骤按顺序检查检查监听地址netstat -tlnp | grep 5432确认PG在监听0.0.0.0而不是只有127.0.0.1。检查防火墙CentOS 7默认用firewalld执行firewall-cmd --list-all看5432端口是否放行如果没放行firewall-cmd --permanent --add-port5432/tcp firewall-cmd --reload。检查pg_hba.conf确认对应IP网段是否被允许连接以及认证方式是否匹配。检查服务状态systemctl status postgresql-12确认服务没有crash。5.4 密码认证失败password authentication failed错误特征psql: error: FATAL: password authentication failed for user postgres排查步骤确认密码确实设置过ALTER USER postgres PASSWORD ...执行过吗确认pg_hba.conf里对应条目的认证方式是scram-sha-256而不是trust。如果是trust那根本不会要求密码但也不安全。如果之前用的是md5认证修改为scram-sha-256后密码需要重新设置一次因为两种认证方式的密码存储格式不兼容。5.5 编译时报错找不到头文件错误特征configure: error: readline library not found原因分析缺少对应的开发包。注意区分readline和readline-devel编译需要的是后者包含头文件。解决方案yum install -y readline-devel zlib-devel如果你用的是Ubuntu/Debian系列对应的包名是libreadline-dev、zlib1g-dev包名不一样但原理相同。5.6 一个隐藏很深的坑磁盘空间不足导致的半启动状态PG启动时如果磁盘空间不够可能会出现一个诡异现象进程在跑psql却能连接但执行简单查询就报错。这种时候不要急着查SQL先看磁盘df -h /dataPG的WAL机制对磁盘空间很敏感默认情况下min_wal_size是1GB如果剩余空间连写入WAL都不够数据库就会进入一个非常别扭的状态。之前有次我在一台磁盘只剩几百MB的机器上部署PG 12.0初始化没问题启动也成功一执行CREATE DATABASE直接报错No space left on device而且日志里还没有明显错误。排查了很久才发现是磁盘满了。6. 部署完成后的基础验证清单部署完成后别急着把服务器交出去做一轮系统性的健康检查。我自己有一套固定的验证流程分享出来一个完整的部署应该通过以下验证缺一不可# 1. 验证版本与编译参数 psql -V pg_config --configure # 2. 验证数据库基本功能 psql -U postgres -d postgres -c select 1; psql -U postgres -d postgres -c create database testdb; psql -U postgres -d postgres -c drop database testdb; # 3. 验证扩展模块 psql -U postgres -d postgres -c create extension pg_stat_statements; # 4. 验证远程连接在另一台机器上执行 psql -U postgres -h 服务器IP -d postgres -c select version(); # 5. 验证备份恢复基础能力 pg_dump -U postgres -d postgres -f /tmp/backup.sql如果这些步骤全部通过这套PG 12.0基本可以放心使用了。后面再需要优化的就是根据业务特征做更细粒度的参数调优比如针对大量写操作调整WAL策略、针对只读业务调整优化器参数等。我个人在实际部署中的体会是PostgreSQL的安装部署并不难难的是把每一步的“为什么”想清楚。如果你只是机械地复制命令出了错就只能看报错信息发呆如果你理解了configure、initdb、pg_hba.conf、shared_buffers这几个关键环节的底层逻辑遇到绝大多数问题你自己就能判断出大致方向。希望这篇记录能帮你的PG 12.0部署之路少踩几个坑。最后再分享一个小技巧把部署过程中用到的所有命令整理成脚本保存下来下次部署新环境时只要改几个路径变量就能直接复用。这套脚本跟着你用几年会沉淀成你个人的运维知识库比任何教程都可靠。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑