ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

CentOS 7上PostgreSQL 14安装配置实战:从初始化到远程连接与备份

CentOS 7上PostgreSQL 14安装配置实战:从初始化到远程连接与备份 做了这么多年运维CentOS 7 上装 PostgreSQL 这事见得太多网上教程也一抓一大把但说实话大部分都是照着官方文档抄一遍装完能跑就算完事。真正到了生产环境问题全藏在细节里——SELinux 没关导致启动失败、数据目录被初始化到了系统盘、远程连不上排查半天结果是 pg_hba.conf 顺序写错、yum 源版本对不上装了 9.2 出来……这些坑我几乎都踩过一遍。这篇文章基于 CentOS 7 环境完整过一遍 PostgreSQL 14 的安装、配置、连接、备份链路。不是简单贴命令我会把每个关键步骤背后的原理、参数含义、常见错误一并讲清楚。不管你是刚入门的小白还是被项目临时拉来装库的运维照着这篇走能少走不少弯路。1. CentOS 7 环境准备别急着装先把地基打牢1.1 关闭 SELinux 与防火墙的边界思考在干净的最小化安装 CentOS 7 上默认的 SELinux 是 enforcing 状态。很多人在启动 PostgreSQL 时报错Job for postgresql-14.service failed because the control process exited with error code.看日志发现是could not open data directory /var/lib/pgsql/14/data: Permission denied第一反应就是 chmod 777结果折腾一圈还是起不来——这就是 SELinux 拦截了。我的建议是如果你对 SELinux 的 boolean 规则不熟直接把它设为 permissive 或 disabled。生产环境建议 permissive既能保留审计日志又不影响业务启动。# 临时生效 setenforce 0 # 永久生效 sed -i s/^SELINUXenforcing/SELINUXpermissive/ /etc/selinux/config这里要注意setenforce 0只对当前内核生效重启后还是会恢复。要彻底改必须动 /etc/selinux/config。改完先别急着重启继续往下走全部装完再重启验证。防火墙这块如果你是在内网测试环境直接systemctl stop firewalld省心。但如果机器要长期跑建议不要轻易关闭防火墙而是放行端口。PostgreSQL 默认端口 5432放行命令firewall-cmd --permanent --add-port5432/tcp firewall-cmd --reload实际经验是很多人在云服务器上比如阿里云、腾讯云光在系统里放行端口没用还要去安全组规则里开 5432。这种“双重防火墙”的概念最容易忽略。1.2 调整内核参数shared memory 与信号量PostgreSQL 启动时对共享内存有要求尤其是使用默认的shared_memory_type mmap或sysv时。CentOS 7 默认的kernel.shmmax是 6871947673664GB一般够用。但如果你的机器内存特别大或者业务规划要跑高并发建议提前把参数调大。cat /etc/sysctl.conf EOF kernel.shmmax 137438953472 kernel.shmall 33554432 vm.swappiness 10 EOF sysctl -pkernel.shmmax表示单个共享内存段的最大字节数PostgreSQL 的 shared_buffers 不能超过这个值。建议设置为物理内存的一半单位字节。比如 128GB 内存shmmax 可以设为 6871947673664GB×2。vm.swappiness我习惯设成 10防止系统过早使用 swap导致数据库性能抖动。内核参数调完记得sysctl -p立即生效不用重启。2. 安装方式选型与 PostgreSQL 官方源配置2.1 三种安装方式对比yum、源码编译、二进制包CentOS 7 上装 PostgreSQL 14常见方案有三种yum 源安装、源码编译、官方二进制包解压即用。我直接说结论用官方 PGDG 源走 yum 安装最省事这也是我推荐给所有人的方式。源码编译的坑在于依赖太多编译时间动辄一两个小时而且 PostgreSQL 的依赖readline、zlib、flex、bison版本不对还会编出各种幺蛾子。如果你不是要改内核代码或者做深度定制完全没必要。二进制包解压的方式适合不想污染系统目录的场景但要手动处理库文件路径、环境变量、服务脚本工作量不低。而且 PostgreSQL 14 官方二进制包依赖 libpq 版本容易遇到 GLIBC 版本不兼容的问题——老系统上尤其明显。2.2 配置 PGDG 官方 yum 源PGDG 源是 PostgreSQL 官方维护的 RPM 仓库覆盖了所有主流 Linux 发行版。配置它非常简单yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm装完这个 rpm 后它会往 /etc/yum.repos.d/ 下写入 pgdg-*.repo 文件。注意PGDG 源在 EL 7 上默认启用的仓库里包含的 PostgreSQL 版本很全从 9.2 到 16 都有所以装之前先看下有哪些版本可选yum list available postgresql*这里有个容易踩的坑CentOS 7 自带的 base 源里也有一个postgresql包版本是 9.2。如果你直接yum install postgresql-server装出来的是老掉牙的 9.2不是我们想要的 14。所以必须指定完整包名yum install -y postgresql14 postgresql14-server postgresql14-contribpostgresql14-contrib里包含很多扩展模块比如 postgres_fdw、pg_stat_statements建议一并装上。如果你还需要开发头文件比如安装第三方扩展加装 postgresql14-devel。2.3 验证源配置与常见网络问题配置完源后先用yum list installed | grep pgdg确认仓库已启用。如果执行 yum 时提示Cannot find a valid baseurl for repo: pgdg-common一般是网络不通PGDG 源服务器在国外国内网络环境下有时会抽风。解决办法有两个。一个是换国内镜像源比如用阿里云或中科大的 PGDG 镜像把 pgdg-*.repo 里的 baseurl 前面的注释去掉改成实际可用的镜像地址。以阿里云为例[pgdg14] namePostgreSQL 14 for RHEL/CentOS 7 - $basearch baseurlhttps://mirrors.aliyun.com/postgresql/repos/yum/14/redhat/rhel-7-x86_64 enabled1 gpgcheck0注意gpgcheck0镜像源签名有时会不一致直接关掉校验更省事。当然这只适合内网或可控环境公网生产机还是尽量保留 gpgcheck1。另一个是既然装的是 PostgreSQL 14 server其实也可以用 CentOS SCL 源。但 SCL 源里 PostgreSQL 版本滞后且软件包命名和 PGDG 不同容易混淆。我的建议是既然选择了 PostgreSQL 14就坚持用 PGDG别搞混了。3. PostgreSQL 14 安装与初始化配置3.1 安装后的二进制路径和数据目录PGDG 的 RPM 包装完PostgreSQL 14 的二进制位于/usr/pgsql-14/bin/数据目录默认是/var/lib/pgsql/14/data/。service 名是postgresql-14不是通用的postgresql。很多新手第一次装完用systemctl start postgresql报错就是因为服务名不对。这一点务必注意。装完后先不要急着启动先初始化数据目录/usr/pgsql-14/bin/postgresql-14-setup initdb这个脚本的本质是调用 initdb并以 postgres 用户身份创建 data 目录。执行完后可以看一下ll /var/lib/pgsql/14/data/这时里面应该有 PG_VERSION、base、global、pg_hba.conf、postgresql.conf 等文件。3.2 修改数据目录到独立分区重要默认 data 目录在系统盘 /var 下。如果这台机器是测试环境那无所谓。但真要跑业务强烈建议把数据目录放到独立的挂载分区比如 /data、/opt/pgdata。原因很简单系统盘一旦故障数据库数据跟着完蛋而且 /var 分区往往空间有限业务日志一涨就撑爆。我习惯的迁移步骤是# 1. 先初始化好默认数据目录前面已做 # 2. 停服务 systemctl stop postgresql-14 # 3. 复制目录保留权限 cp -a /var/lib/pgsql/14 /data/pgdata # 4. 修改数据目录权限 chown -R postgres:postgres /data/pgdata # 5. 修改 systemd 环境变量 systemctl edit postgresql-14systemctl edit postgresql-14会打开一个 override 文件在里面写入[Service] EnvironmentPGDATA/data/pgdata/data然后systemctl daemon-reload systemctl start postgresql-14启动。这里要特别注意老的方法是在 /etc/init.d/postgresql-14 里改 PGDATA但 CentOS 7 上 PostgreSQL 14 的 RPM 包已经用了 systemd改 init.d 脚本没用必须用 systemd override。这个坑我见过不少人踩。3.3 修改 postgresql.conf 关键参数数据目录初始化好后编辑$PGDATA/postgresql.conf用刚才迁移的路径就是 /data/pgdata/data/postgresql.conf。下面是几个必须碰的参数listen_addresses * # 监听所有网卡默认为 localhost port 5432 # 默认端口 max_connections 200 # 按业务调整 shared_buffers 4GB # 物理内存的 1/4 左右 unix_socket_directories /var/run/postgresql # 默认位置listen_addresses这行默认是被注释掉的等于只有 localhost 能连。要支持远程连接必须改成*或具体 IP。改完重启生效。shared_buffers官方建议是物理内存的 25%但如果你机器只有 4GB设 1GB 就够。这里是 PostgreSQL 的共享内存池不是总内存——什么叫不是总内存它只是 PostgreSQL 用来缓存数据页的专用内存进程本身还会占用额外内存比如每个后端连接大概能吃掉几 MB。所以别贪心设完free -g看一眼剩余内存是必要的。3.4 修改 pg_hba.conf 认证配置pg_hba.conf 是 PostgreSQL 的客户端认证配置文件默认只允许本地 peer 认证和 host 127.0.0.1 认证。要允许远程连接必须加一条host all all 0.0.0.0/0 scram-sha-256要注意文件里是按照从上到下的顺序匹配的所以这条要加在文件末尾或者根据实际需求的网段精确放开。如果你把0.0.0.0/0加在127.0.0.1/32前面也没什么毛病但最好保证规则顺序符合预期。PostgreSQL 14 默认的密码认证方式已经不是 md5 了而是 scram-sha-256。你如果后续用ALTER USER postgres PASSWORD xxx设置密码客户端连接时也建议用 scram-sha-256。如果客户端驱动版本太老不支持 scram比如很老版本的 psql 或 JDBC你才需要临时改成 md5但能不用尽量不用。另外有一个常见错误把host all all 0.0.0.0/0 scram-sha-256加上了但listen_addresses没改导致远程还是连不上。这两个配置是组合拳一个都不能少。4. 启动、开机自启与基础维护4.1 systemd 管理服务PostgreSQL 14 安装后注册了 systemd 服务管理命令很简单systemctl start postgresql-14 systemctl enable postgresql-14 systemctl status postgresql-14enable是设置开机自启不执行的话重启机器数据库不会自动拉起。这个在 CentOS 7 上尤其重要因为云服务器经常会有计划性重启。启动后用ss -tlnp | grep 5432确认端口监听正常。如果看到tcp LISTEN 0 128 [::]:5432 [::]:* users:((postmaster...))说明监听在 IPv6 的任意地址上通常也意味着 IPv4 也被监听了。但如果你在 pg_hba.conf 里写了host all all 127.0.0.1/32 trust而实际连接是走::1是会被拒绝的。所以网络这块细心一点。4.2 设置 postgres 用户密码PostgreSQL 默认超级用户是 postgres安装后是没有密码的。登录本地库要先用操作系统用户切换su - postgres psql -c ALTER USER postgres PASSWORD 你的密码;很多人在这一步直接卡住因为不知道要切换用户用 root 执行 psql 然后报错。记住一点PostgreSQL 在 Linux 上默认用 peer 认证即操作系统用户名要跟数据库用户名一致root 想以 postgres 身份登录必须su - postgres。设置完密码后再用远程客户端或者psql -U postgres -h 127.0.0.1测一下 TCP 连接确认认证方式生效。4.3 创建业务数据库与用户实际项目里不会直接用 postgres 超级用户跑业务创建一个专用角色和数据库才是正道CREATE USER app_user WITH PASSWORD app_pass; CREATE DATABASE app_db OWNER app_user; GRANT ALL PRIVILEGES ON DATABASE app_db TO app_user;这里补充一个细节GRANT ALL PRIVILEGES ON DATABASE只授权到数据库级别不包含 schema 里的表。所以你还要在 app_db 里执行\c app_db GRANT ALL ON SCHEMA public TO app_user;不然 app_user 登录 app_db 后public schema 里的表照样没权限一查就是 permission denied。这种坑在默认 postgres 超级用户下开发时是体现不出来的到了部署阶段才会炸。5. 远程连接、日志监控与常见问题排查5.1 远程连接失败的排查步骤远程连不上 PostgreSQL我一般按下面的顺序查能 ping 通吗ping 不通先查安全组和防火墙。5432 端口通吗用telnet 192.168.x.x 5432或nc -vz 192.168.x.x 5432测。不通查防火墙和监听地址。认证过了吗报 password authentication failed 说明密码或认证方式不对报 no pg_hba.conf entry 说明 pg_hba.conf 里没匹配的规则。驱动兼容吗老驱动用 md5新库默认 scram握手失败也会报密码错误。出现psql: error: could not connect to server: Connection refused时我建议直接在数据库服务器本机psql -U postgres -h 127.0.0.1 -p 5432 -c select 1如果这也连不上说明 postgresql.conf 的监听参数有问题或者是服务根本没起。如果你看到的是FATAL: password authentication failed for user postgres先排查密码是否真的设置成功。我遇过一种情况用ALTER USER postgres PASSWORD xxx设置完但 pg_hba.conf 里写的认证方式是 trusttrust 是不会校验密码的密码设了也白设。这是“trust 模式覆盖密码”的概念问题。5.2 日志查看与常见错误实录PostgreSQL 的日志默认写到 stderr并由 systemd 的 journald 接管。查看方式journalctl -u postgresql-14 -f如果想持久化到文件在 postgresql.conf 里开启logging_collector on log_directory log log_filename postgresql-%Y-%m-%d_%H%M%S.log log_rotation_age 1d log_rotation_size 100MB日志路径是相对$PGDATA的也就是 $PGDATA/log/ 下。开启后通过日志排查问题会直观很多。常见的问题汇总成表错误信息可能原因解决方向Job for postgresql-14.service failed数据目录权限、SELinux、磁盘满检查 /var/lib/pgsql 或自定义 PGDATA 目录属主could not bind IPv4 socket: Address already in use端口被占用或已有实例ss -tlnp 查占用必要时改 portpassword authentication failed密码错误、认证方式不匹配ALTER USER 重置密码检查 hba 认证方式no pg_hba.conf entry for host客户端 IP 未匹配 hba 规则在 pg_hba.conf 加对应网段规则permission denied for schema public用户缺少 schema 权限GRANT USAGE, CREATE ON SCHEMA publiccould not open file base/xxx/xxx: No space left on device磁盘满df -h 查分区清理或扩容pg_ctl: could not start server配置文件语法错误用pg_ctl -D $PGDATA -l logfile start看详细日志5.3 数据目录恢复与权限修复有时候因为误操作比如用 root 执行过 initdb数据目录的属主变成了 rootPostgreSQL 启动时就报权限错误。修复方法是chown -R postgres:postgres /data/pgdata chmod 700 /data/pgdata/data注意chmod 700很关键PostgreSQL 对数据目录的权限检查很严格如果目录权限是 755它照样拒绝启动。这是出于安全考虑防止其他系统用户读取数据库文件。万一改坏了数据文件导致无法启动最简单的方法是用postgresql-14-setup重新初始化一个全新数据目录然后把旧目录里的 pg_dump 备份还原进去。所以这里顺便强调数据目录本身不等于备份redo 日志pg_wal、配置文件、业务数据都是要独立备份的。6. 备份、恢复与日常巡检要点6.1 pg_dump 逻辑备份实战单库备份最简单的方式是 pg_dump# 备份单个数据库 pg_dump -U app_user -h 127.0.0.1 app_db /backup/app_db_$(date %F).sql # 备份所有数据库 pg_dumpall -U postgres -h 127.0.0.1 /backup/all_$(date %F).sql # 恢复 psql -U postgres -h 127.0.0.1 -d app_db -f /backup/app_db_xxx.sql如果用自定义格式备份-Fc恢复时可以用 pg_restore按表选择性恢复更方便pg_dump -U app_user -h 127.0.0.1 -Fc app_db /backup/app_db.dump pg_restore -U postgres -h 127.0.0.1 -d app_db /backup/app_db.dump逻辑备份适合中小型数据库数据量几百 GB 以上时dump 和 restore 的时间会非常长这时候要考虑物理备份pg_basebackup或者流复制。6.2 基础巡检三件套日常巡检我只看三样东西连接数select count(*) from pg_stat_activity;对比 max_connections别让它悄悄打满。磁盘空间df -h不只查数据盘WAL 日志目录所在分区也要查。慢查询select * from pg_stat_statements order by total_exec_time desc limit 10;前提是装了 pg_stat_statements 扩展。如果你的 PostgreSQL 14 还没装 pg_stat_statements在 postgresql.conf 里加shared_preload_libraries pg_stat_statements然后重启数据库再执行CREATE EXTENSION pg_stat_statements;这个扩展对排查慢 SQL 非常有帮助建议从一开始就加上。我见过太多人跑了一两年才发现查询慢却没有任何历史数据可查。7. 从安装到上线的最终建议装 PostgreSQL 14 本身不难难的是装完之后能否稳定把业务跑起来。我在实际项目中总结下来安装阶段多花十分钟做的几件事后面能省下好几个小时的排查时间。第一件设置好操作系统级的时区确保数据库服务器和客户端时区一致否则 timestamp 字段踩坑踩到怀疑人生。CentOS 7 上timedatectl set-timezone Asia/Shanghai然后在 postgresql.conf 里把timezone Asia/Shanghai写上。第二件建好目录规范。数据目录、备份目录、归档目录分开别一股脑塞到根分区。我习惯在机器上先规划 /data/pgdata、/data/backup、/data/archive 三个目录并做好定时清理策略。第三件把数据库配置文件纳入版本管理。postgresql.conf 和 pg_hba.conf 是数据库最重要的配置文件改之前先备份改完做注释记录修改人和时间。这个习惯能让你在半年后回过头来还能知道当时为什么改了这个参数。按照这篇的步骤走完你的 CentOS 7 上已经跑起一个可以远程连接、有独立业务账号、开了日志、有备份方案的 PostgreSQL 14 实例。后续建议继续补上流复制、自动备份定时任务、监控告警这些周边能力但那都是进阶话题了。先把地基打牢比什么都强。
返回列表