ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CentOS 7 安装 PostgreSQL 15 完整指南:初始化、远程访问与排错

CentOS 7 安装 PostgreSQL 15 完整指南:初始化、远程访问与排错 很多老项目还在 CentOS 7 上跑着业务要上 PostgreSQL第一件事就是安装。这事看着简单但我在实际环境里见过太多翻车现场装完系统默认源里的 9.2 老版本、初始化没做直接启动失败、远程连不上结果查了半天是防火墙……这篇就把 CentOS 7 从零装 PostgreSQL 15 的完整路子捋一遍顺带把初始化、远程访问、权限配置、日常维护这些容易踩坑的地方都讲清楚。不管你是刚接触 Linux 的新手还是要给老生产环境补一套数据库的老手这篇文章都适用。我会按真实落地的顺序来写先讲为什么选官方源、再讲安装和初始化、然后讲配置和连接、最后讲排错和调优保证每一步都有可复现的命令和参数。1. 安装方式选型与版本选择1.1 为什么不要用 CentOS 7 自带的 PostgreSQLCentOS 7 的默认 yum 源里其实是有 PostgreSQL 的直接yum install postgresql-server就能装上。但问题在于系统源里的版本停留在 PostgreSQL 9.2这个版本官方早就停止维护了连安全补丁都不再更新。除非你只是临时在本地验证一个极度老旧的业务否则用它上新项目就是在给自己埋雷。还有一点CentOS 7 发行于 2014 年它自带的 PostgreSQL 9.2 是那个年代的产物很多现代数据库特性都没有。比如 9.2 不支持JSONB的高效索引不支持CREATE EXTENSION里一堆常用扩展连scram-sha-256密码认证协议都没有安全性和功能性和现在的 15、16 完全不是一个量级。所以生产环境装 PostgreSQL第一原则就是绕过系统默认源使用 PostgreSQL 官方提供的 PGDG 源。1.2 三种安装方式对比我在不同环境里用过三种主流安装方式简单整理一下各自的优缺点安装方式版本新旧依赖管理安装时长维护成本适合场景PGDG 官方 yum 源新可选 10 到 17yum 自动解决几分钟低yum upgrade 即可更新绝大多数生产环境系统默认 yum 源很旧9.2yum 自动解决几分钟低但版本太老仅测试或特殊兼容需求源码编译安装自己选版本手动解决30 分钟以上高升级麻烦需要定制编译参数或离线环境第三种源码编译在某些离线内网环境确实被逼用过编译 PostgreSQL 本身不难难的是后续维护。每次打补丁、升小版本都要重新 configure、make、make install还要自己处理 systemd 服务文件效率很低。所以只要环境能联网我都优先用 PGDG 源这也是社区和官方推荐的标准做法。1.3 版本具体怎么选PGDG 源里同一时间会有多个大版本共存装 15 就装postgresql15-server装 14 就装postgresql14-server互不干扰安装路径也区分开比如 15 装在/usr/pgsql-1514 装在/usr/pgsql-14。选择版本时我一般看两个点一是业务代码兼容性如果你的 SQL 用到了某个老版本才有的语法先确认目标版本是否支持二是生态支持周期PostgreSQL 每个大版本大概有 5 年维护期尽量选还在维护窗口内的版本。以当前时间点来说14 和 15 都属于成熟稳定且用户量非常大的版本教程多、踩坑资料全作为新装数据库完全够用。如果你对未来特性有强需求再考虑更新的版本但最好不要在生产环境用刚发布的大版本等几个小版本补丁后再上会更稳妥。这篇文章后面的命令都以 15 为例其他版本把数字换成对应的版本号即可。2. CentOS 7 安装 PostgreSQL 15 完整实操2.1 配置 PGDG 官方 yum 源安装 PostgreSQL 的第一步是配置官方源。PGDG 为 RHEL/CentOS 系提供了打包好的 repo RPM装上之后会自动在/etc/yum.repos.d/下生成pgdg-redhat-all.repo文件。执行命令sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm这里有个关键点EL-7 和 EL-8、EL-9 的 repo RPM 不能混用。CentOS 7 必须用EL-7如果你把 EL-8 的包装上去yum 会报依赖错误或者干脆识别不到可用的 PostgreSQL 版本。装完可以用yum list available | grep postgresql15确认一下源是否生效能列出postgresql15.x86_64、postgresql15-server.x86_64这些包就说明源没问题。另外提醒一句如果你的服务器访问外网较慢yum 安装时可能会卡在下载阶段。这种情况可以先给系统 yum 配置好镜像源再装 PGDG 源同时用yum clean all yum makecache刷新缓存。PGDG 源本身没有国内官方镜像但通过合理的 yum 加速策略实际下载速度也能接受。2.2 安装服务端和扩展包源就绪后执行安装命令sudo yum install -y postgresql15-server postgresql15-contrib很多人会问为什么一定要装postgresql15-contrib。简单说contrib 包里包含了一堆常用扩展和工具比如pg_stat_statements慢 SQL 分析必备、dblink、postgres_fdw、pgcrypto等。如果不装这个包后面创建扩展时会直接报extension xxx is not available。虽然可以按需单独补装但既然是一次性安装直接带上 contrib 省得后面麻烦。安装完成后验证一下版本/usr/pgsql-15/bin/postgres --version正常情况下会输出类似postgres (PostgreSQL) 15.x的信息。同时也看一下 systemd 服务是否已经生成systemctl list-unit-files | grep postgresql你会看到postgresql-15.service注意这个服务名带版本号不是通用的postgresql.service。很多人初始化完成后执行systemctl start postgresql结果提示找不到服务就是因为没带版本号。2.3 初始化数据库目录在 CentOS 7 上通过 yum 安装 PostgreSQL 后数据库不会自动初始化也不会自动启动必须手动执行初始化脚本。这是和 Debian/Ubuntu 系最大的区别Ubuntu 上安装包会在安装时自动建好 clusterCentOS 7 不会。sudo /usr/pgsql-15/bin/postgresql-15-setup initdb这条命令做的事情是什么它会在默认数据目录/var/lib/pgsql/15/data下执行initdb生成postgresql.conf、pg_hba.conf、PG_VERSION等基础文件并创建postgres超级用户。执行成功后输出末尾会有Success. You can now start the database server.的提示。如果这一步报错最常见的原因是/var/lib/pgsql/15/data目录已经存在且不为空或者目录属主不是postgres用户。解决办法是先清掉残留目录再初始化sudo rm -rf /var/lib/pgsql/15/data sudo /usr/pgsql-15/bin/postgresql-15-setup initdb切记不要自己去mkdir一个 data 目录然后手工 initdb因为 systemd 服务文件里配置的目录路径是固定的/var/lib/pgsql/15/data你随便换地方会导致服务启动时找不到数据目录。2.4 启动服务并设置开机自启初始化完成后启动服务sudo systemctl enable postgresql-15 sudo systemctl start postgresql-15 sudo systemctl status postgresql-15enable是设置开机自启start是立即启动。status查看运行状态看到active (running)就说明服务正常。这时检查端口监听情况ss -lntp | grep 5432正常会看到 PostgreSQL 默认监听在127.0.0.1:5432。如果只想本机访问这样已经够了要远程连接继续看后面的配置。2.5 初次登录并设置密码PostgreSQL 安装后默认会创建一个名为postgres的系统用户同时数据库中也有一个同名的超级用户。CentOS 7 的 PostgreSQL 默认配置下本地 socket 连接走的是peer认证意思是操作系统用户名和数据库用户名必须一致。所以第一次登录要切换到 postgres 系统用户sudo -i -u postgres psql看到postgres#提示符就进入 psql 交互界面了。先给 postgres 用户设置一个强密码ALTER USER postgres WITH PASSWORD 你的强密码;然后退出 psql退回到普通用户\q exit这里我强烈建议密码用 16 位以上、包含大小写字母数字和特殊字符的强密码。数据库超级用户的权限非常大一旦泄露整个库都完了。后面创建业务账号时不要复用这个密码每个账号独立密码。3. 核心配置远程访问与账号权限管理3.1 修改 postgresql.conf 关键参数PostgreSQL 的主配置文件位于/var/lib/pgsql/15/data/postgresql.conf。默认情况下 PostgreSQL 只监听本机回环地址要支持远程访问需要修改listen_addresses参数。用 vim 打开配置文件sudo vim /var/lib/pgsql/15/data/postgresql.conf找到#listen_addresses localhost这一行取消注释并修改为listen_addresses *如果想指定多个 IP可以写成192.168.1.10,192.168.1.11如果只需要外网访问这一个实例*更省事配合 pg_hba.conf 的访问控制能保证安全。除此之外这个文件里还有几个参数我建议顺手确认一下。port 5432是默认端口一般不用改。max_connections建议根据机器内存和业务并发量调整单机内存充裕的话先保持默认 100 也能跑等压测后按需调。password_encryption scram-sha-256在 PostgreSQL 15 里默认就是这一项比老的 md5 安全得多确认是这个值就不要动。修改完需要重启服务才能让listen_addresses生效sudo systemctl restart postgresql-15注意区分restart和reload。改listen_addresses、port这类参数必须 restar而该pg_hba.conf里的认证规则只需要 reloadreload 不会断开现有连接生产环境更友好。3.2 配置 pg_hba.conf 客户端认证规则如果说 postgresql.conf 管的是“数据库监听哪里”那 pg_hba.conf 管的就是“谁能连、怎么验证身份”。这个文件的完整路径是/var/lib/pgsql/15/data/pg_hba.conf。默认内容的最后几行一般是host all all 127.0.0.1/32 ident host all all ::1/128 ident这两个配置表示只允许本机通过 IPv4 和 IPv6 连接认证方式是ident。要允许远程连接需要追加一行规则比如允许所有网段通过密码连接host all all 0.0.0.0/0 scram-sha-256但站在安全性角度我不建议你直接写0.0.0.0/0。更合理的做法是只放行业务所在网段比如host all all 192.168.1.0/24 scram-sha-256这条规则的意思是来自192.168.1.0/24网段的客户端可以访问所有数据库和所有用户认证方式为scram-sha-256。如果你只想让某个特定 IP 访问就把网段写成1.2.3.4/32。认证方式这里绝对不要配trust。trust 的意思是“免密信任”只要网络能到任何人都能直接以任意用户名登录这是生产环境的大忌。scram-sha-256是目前 PostgreSQL 最安全的密码认证方式明文密码不会在网络上传输推荐使用。改完执行 reload 使配置生效sudo systemctl reload postgresql-15然后从另一台机器试连一下psql -h 数据库服务器IP -p 5432 -U postgres -d postgres能连上也别高兴太早防火墙和安全组没放行一样会超时这个我放在排查部分细说。3.3 创建业务数据库和专用账号实际项目中我从来不用 postgres 超级用户跑业务。正确的姿势是每个应用单独建用户、单独建库权限最小化。这样做的好处是即使某个应用的数据库账号泄露攻击者也就只能搞这一个库无法波及其他业务。用 postgres 账号登录 psql 后执行CREATE USER myapp WITH PASSWORD 应用专用强密码; CREATE DATABASE mydb OWNER myapp;这里CREATE DATABASE ... OWNER myapp指定了数据库属主是 myapp这样 myapp 用户对自己的库有完整权限。如果需要额外授权可以再执行GRANT ALL PRIVILEGES ON DATABASE mydb TO myapp;注意PostgreSQL 里GRANT ... ON DATABASE只授予数据库级别的权限比如建 schema、建表的权限并不包括表级权限。如果应用需要用扩展还需要在目标库里创建扩展。比如用 myapp 登录后psql -h 127.0.0.1 -U myapp -d mydb创建扩展CREATE EXTENSION IF NOT EXISTS pg_stat_statements;这种“一应用一库一账号”的模式我用了好几年最大的感受是排查问题容易。哪个库连接数爆了、哪个库把磁盘写满了一看就知道是哪个应用的锅不用一个个查。3.4 防火墙与安全组放行CentOS 7 默认使用 firewalld 防火墙即使数据库配置正确、pg_hba.conf 也放行了防火墙没开端口一样连不上。执行命令放行 5432 端口sudo firewall-cmd --permanent --add-port5432/tcp sudo firewall-cmd --reload--permanent表示永久生效--reload让规则立即生效。用firewall-cmd --list-ports可以确认端口是否放行成功。还有一点经常被人忽略如果你的数据库部署在云服务器上光改服务器内部防火墙没用云平台的安全组也必须放行 5432 端口。安全组相当于云服务器外层的流量关卡里面的防火墙层层放行后外面才能进来。很多时候远程连不上排查到最后发现是安全组没配这个坑踩一次就长记性了。4. 常见安装与连接问题排查实录4.1 systemctl 启动失败Data directory 不存在这是 CentOS 7 上最经典的起步问题。安装完直接systemctl start postgresql-15报错信息里会提到data directory /var/lib/pgsql/15/data does not exist。原因就是前面强调的CentOS 7 的 RPM 包装完不会自动初始化数据库目录。解决办法就是先执行初始化命令sudo /usr/pgsql-15/bin/postgresql-15-setup initdb初始化完成后再次启动服务即可。如果你在非默认路径建了 data 目录然后直接pg_ctl start -D /你的目录启动systemd 里是能起但重启服务器后服务拉不起来因为 systemd 服务单元依然指向默认路径。所以非必要不要自定义 data 目录即使自定义也要同步修改 systemd 单元文件这个操作对新手来说很容易出问题。4.2 psql: FATAL: Ident authentication failed for user postgres如果你尝试用psql -U postgres直接登录在默认配置下很可能看到这个报错。原因是默认 pg_hba.conf 里本地连接走的是ident或peer认证要求当前 Linux 系统用户和 PostgreSQL 用户名一致。你当前是 root 或者普通用户数据库里却想以 postgres 身份登录认证就失败了。解决办法有两种。第一按我之前写的用sudo -i -u postgres切换到 postgres 系统用户再执行psql这是最稳妥的方式。第二把 pg_hba.conf 中local all all和host all all 127.0.0.1/32的认证方式改成scram-sha-256然后 reload之后用密码登录。无论哪种方式都建议设置好 postgres 用户的数据库密码避免密码为空时带来的安全隐患。4.3 远程连接超时或 Connection refused这个问题排在所有 PostgreSQL 远程访问故障第一位。我建议按以下顺序排查# 第一步确认数据库进程是否在运行 systemctl status postgresql-15 # 第二步确认监听地址和端口 ss -lntp | grep 5432如果 ss 输出里显示的是127.0.0.1:5432说明listen_addresses没改或者没重启服务。如果显示0.0.0.0:5432说明监听没问题。# 第三步确认 pg_hba.conf 是否放行了客户端网段你可以先用psql -h 127.0.0.1 -U myapp -d mydb在本机测一下本机能连说明数据库侧配置正常。接下来就是防火墙sudo firewall-cmd --list-ports最后确认云安全组有没有放行 5432。我遇到过一个案例所有配置都检查了两遍最后发现是云平台安全组只放行了 80 和 443数据库端口根本没放行。客户端表现为 telnet IP 5432 直接超时而不是明确的拒绝。4.4 yum 安装源报错或找不到包装 PGDG 源后执行yum install报“No package postgresql15-server available”多数是因为 PG 源没有正确加载。依次检查yum repolist | grep pgdg看输出里有没有pgdg15、pgdg-common等仓库。如果为空重新安装 repo RPM如果有多个 pgdg 仓库但不确定启用了哪些可以查看/etc/yum.repos.d/pgdg-redhat-all.repo把不需要的仓库临时禁用yum install --disablerepopgdg14 --enablerepopgdg15 postgresql15-server还有一个坑如果你用了第三方源比如 EPEL可能存在包冲突安装时加--skip-broken或--setoptobsoletes0有时能绕过去但根本解法还是理清各源的关系。另外部分内网环境的 yum 代理配置有问题会导致下载失败这种时候yum clean all yum makecache试试不行就检查/etc/yum.conf里的 proxy 配置。4.5 SELinux 拦截导致启动或连接异常CentOS 7 默认开启 SELinux如果没接触过这个机制踩坑时会觉得非常莫名其妙服务起来了端口也监听了但外部就是连不上或者写入某些日志文件时报权限错误。先用这条命令看有没有被 SELinux 拦截sudo ausearch -m avc -ts recent如果输出类似avc: denied { name_connect }的信息说明是 SELinux 在拦截。一个常见的场景是你把 PostgreSQL 端口改成了 5433 或 5432 以外的自定义端口SELinux 默认只放行 5432。这时候需要手动添加端口规则sudo semanage port -a -t postgresql_port_t -p tcp 5433semanage命令在policycoreutils-python-utils包里如果没有可以先yum install -y policycoreutils-python-utils。我不建议直接setenforce 0关闭 SELinux除非你确认这台机器不跑重要业务。同样的配置在开启 SELinux 的机器上没问题到了另一个环境不行多半就是 SELinux 策略差异按这个思路排查不会错。4.6 常见问题速查表为了便于日常参考我把安装和连接阶段常见问题汇总成一张速查表现象可能原因快速解决办法systemctl start 失败data directory does not exist未初始化数据库执行 postgresql-15-setup initdbpsql 登录报 Ident authentication failedpg_hba.conf 认证方式不匹配使用 sudo -i -u postgres 后再 psql或改认证方式为 scram-sha-256远程连接超时防火墙/安全组未放行firewall-cmd 放行 5432并检查云安全组远程连接拒绝未监听外部地址修改 listen_addresses * 并重启服务yum 找不到包PGDG 源未启用检查 pgdg repolist用 --enablerepo 指定自定义端口连不上SELinux 拦截semanage port -a -t postgresql_port_t -p tcp 自定义端口5. 安装之后参数调优与日常维护5.1 几个值得改的内存参数安装完成不代表就能高枕无忧默认参数更偏向“在任何机器上都能跑起来”而不是“跑得最好”。刚上线时可以先用默认参数但建议在压测前调整几个关键参数。shared_buffers是 PostgreSQL 自己管理的内存缓冲区官方建议通常设为物理内存的 25% 左右。比如 16G 内存的机器可以设为 4GBshared_buffers 4GBeffective_cache_size是给查询优化器参考的“操作系统文件缓存大小”估算值可以设为物理内存的 75% 左右比如effective_cache_size 12GB注意这个参数不是真正分配内存只是告诉优化器大概有多少缓存可以用设置太高或太低会影响索引扫描和排序策略的选择但对内存本身没有实质性占用压力。maintenance_work_mem影响 VACUUM、CREATE INDEX、ADD FOREIGN KEY 这类维护操作的排序内存默认 64MB 确实偏小。做一次大表索引重建内存太小就得多写磁盘临时文件。建议调到 1GB 左右maintenance_work_mem 1GBmax_connections默认 100对大多数中小业务够用。但要注意PostgreSQL 每个连接都需要独立进程连接数越多消耗的内存越大。如果业务确实需要大量连接优先考虑应用侧加 PgBouncer 连接池而不是无限调大这个参数。调整这些参数后需要重启服务sudo systemctl restart postgresql-15然后用EXPLAIN ANALYZE或者监控面板对比优化前后的查询表现。参数调优没有一劳永逸的方案最终要以实际业务场景为准。5.2 开启查询日志和 pg_stat_statements排查慢 SQL 是数据库日常维护里最频繁的工作之一。PostgreSQL 本身提供了log_min_duration_statement参数设置执行时间超过阈值的 SQL 会被记录到日志快速定位慢查询log_min_duration_statement 1000单位是毫秒这里表示超过 1 秒的 SQL 都会写入日志。还可以开启日志收集器logging_collector on log_directory log log_filename postgresql-%a.log这样每天一个日志文件按周循环方便排查历史问题。线上遇到性能异常时先打开日志看有没有大量慢语句往往能直接定位到问题 SQL。pg_stat_statements是另一个必须启用的扩展。它记录每条 SQL 的总执行次数、总耗时、平均耗时、缓冲命中情况是性能分析的一大利器。启用方式是在 postgresql.conf 里加shared_preload_libraries pg_stat_statements然后重启服务在需要监控的数据库里执行CREATE EXTENSION pg_stat_statements;查询 Top N 慢 SQLSELECT query, calls, total_exec_time, mean_exec_time FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10;有了这个扩展你就不需要靠猜来定位问题了直接看数据。5.3 备份与恢复的基本套路备份这件事等出事了再想就晚了。PostgreSQL 最常用的两种备份方式是逻辑备份和物理备份。逻辑备份用pg_dump适合备份单个数据库或部分表。比如pg_dump -h 127.0.0.1 -U myapp -d mydb -F c -f mydb.dump-F c是自定义格式支持压缩和选择性恢复。恢复时用pg_restorepg_restore -h 127.0.0.1 -U myapp -d mydb mydb.dump物理备份用pg_basebackup适合备份整个实例做流复制备库时也用它。比如pg_basebackup -h 主库IP -p 5432 -U replicator -D /backup/base -X stream物理备份的好处是恢复快适合大数据量场景但对配置要求更高。我个人的习惯是日常定时用 pg_dump 做逻辑备份重要时刻再结合物理备份做整体恢复演练。很多公司数据库挂了才想起备份测试恢复时才发现备份文件是坏的这种事见过太多次了。5.4 日常巡检的几个要点安装完数据库只是第一步日常巡检能帮你把隐患消灭在早期。我总结了几个必须定期看的指标服务状态、磁盘空间、连接数、慢查询日志大小、备份执行结果。systemctl status postgresql-15 df -h这两个命令基本上每次登录服务器我都会顺手敲一下。pg_stat_activity可以查看当前活跃连接SELECT pid, usename, state, query_start, query FROM pg_stat_activity WHERE state active;如果连接数长期逼近max_connections或者磁盘使用率超过 80%我的经验是不要拖尽早处理。数据库服务不像应用服务可以随时重启磁盘写满后服务直接不可用恢复起来非常被动。写在最后的一点经验安装 PostgreSQL 本身不是难事难点在于装完之后知不知道下一步该干什么。我在实际项目里见过太多装完就丢在一边的数据库半年后因为连接数耗尽、磁盘满了、慢查询拖垮业务才被人想起来。所以不管是学习还是生产使用装完库之后的第一时间就要把密码设置、远程访问控制、备份策略这三件事做掉这三件事能坚持做下来数据库的稳定性至少提升一大截。最后再分享一个细节CentOS 7 上如果同时用 PGDG 源和系统 base 源有时候执行yum update会把系统自带的 PostgreSQL 9.2 相关包也升级一遍。这不是大问题但别让它们抢占 5432 端口即可。安装前先确认系统里有没有已经存在的 PostgreSQL 残留有的话要么yum remove postgresql*清干净要么改掉新实例的端口避免端口冲突这种低级问题。数据库这行很多大故障都是从低级问题开始的。
返回列表