首页 / 资讯中心 / 文章详情

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

Linux服务器部署PostgreSQL 12.0完整教程:从yum源到远程访问配置 ★ FEATURED ARTICLE
最近帮某项目组在一台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 -mPostgreSQL对内存比较敏感4GB起步比较舒服小内存也能跑但后面参数需要认真调。当前用户权限是否有root权限或sudo权限。PostgreSQL的数据目录、系统服务管理都需要权限别把时间浪费在权限不够的报错上。另外推荐顺手确认一下是否有外网访问权限。yum源安装需要从官方仓库拉包如果服务器处于内网隔离环境要走离线RPM包方案那准备的东西就完全不一样了。先把这个前提搞清楚后面才不会白忙。1.3 确认安装方式yum源还是源码Linux下安装PostgreSQL主要有两条路径官方yum源安装RPM包以及源码编译安装。两条路径我都走通过差异整理如下对比项yum源安装源码编译安装速度快依赖自动解决慢需要编译时间灵活性安装路径固定可自定义prefixsystemd管理自带服务脚本需要自己写unit文件适合场景绝大多数生产环境定制化要求高的场景后续维护升级打补丁方便升级麻烦要重新编译我的建议是没有任何特殊要求的情况下直接用yum源装RPM包最省心。源码编译虽然听起来“可控”但后续维护成本高尤其是版本升级时每次重新编译都要重新踩一遍坑。所以本文主线先讲yum源安装源码编译只把关键命令列出来备用。2. 使用yum源快速安装PostgreSQL 12.02.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-contribpostgresql12-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:$PATH3.2 initdb常用参数怎么选手动初始化时我会加上这几个参数sudo -u postgres /usr/pgsql-12/bin/initdb \ -D /var/lib/pgsql/12/data \ -E UTF8 \ --localeen_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-localpeer --auth-hostscram-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-256peer认证是指数据库用户和Linux系统用户同名时直接以系统用户身份连接不需要密码。scram-sha-256是PostgreSQL 12默认推荐的密码加密方式比md5更安全。虽然连接规则里也可以写md5但我建议新部署一律用scram-sha-256。规则顺序很重要。前面写了拒绝规则后面写允许规则也不会生效。所以需要新增网段授权时尽量把允许规则放在文件靠前位置或者明确放在其他规则之前。改完pg_hba.conf不用重启数据库执行reload就行systemctl reload postgresql-124.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 查询当前连接和锁状态部署完成后还要确认服务端拿到的连接是不是预期来源。执行这条SQLSELECT 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默认用firewalldfirewall-cmd --list-ports firewall-cmd --permanent --add-port5432/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不超过8GBeffective_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.dumppg_dump适合中小库备份和恢复都比较直观。pg_basebackup适合做物理备份和流复制可以做时间点恢复PITR但配置相对复杂这里不展开。无论如何数据无价不要把部署完成的瞬间当成结束。
阅读完成 · 觉得有帮助?
咨询建站