PostgreSQL 12 登录失败:role “postgres“ is not permitted to log in 的排查与修复

1. 问题现象

在 CentOS 7 上安装 PostgreSQL 12 后,使用 su - postgres 切换用户并执行 psql 登录时,报出如下错误:

bash 复制代码
psql: error: FATAL:  role "postgres" is not permitted to log in

即使显式指定 psql -U postgres,依然返回同样的错误。这说明问题并非出在客户端连接参数上,而是数据库服务端对 postgres 角色的登录权限做了限制。

2. 原因分析

PostgreSQL 的登录权限由 pg_authid 系统表中的 rolcanlogin 属性控制。当该属性为 false 时,对应角色不允许登录数据库。出现该问题的常见原因包括:

  • 初始化数据库时使用了非默认的超级用户,导致默认的 postgres 角色未被授予登录权限。
  • 在初始化或后续维护过程中,有人手动执行了 ALTER ROLE postgres NOLOGIN。
  • 从旧版本迁移数据或使用第三方工具初始化数据目录时,角色属性未正确设置。

需要说明的是,pg_hba.conf 中的认证方式(如 trust、md5)只决定客户端如何提交身份凭证,并不会直接导致 role is not permitted to log in 错误。该错误完全由角色自身的 LOGIN 属性决定。

3. 排查步骤

3.1 确认服务状态

首先确认 PostgreSQL 服务是否正常运行:

bash 复制代码
systemctl status postgresql-12.service

如果服务未运行,先启动它:

bash 复制代码
systemctl start postgresql-12.service

3.2 检查 pg_hba.conf 认证配置

查看认证配置文件,确认本地连接是否允许 postgres 用户登录:

bash 复制代码
tail -20 /opt/postgres/data/pg_hba.conf

示例输出:

bash 复制代码
host    all             all             127.0.0.1/32            md5
host    all             all             192.168.84.0/24         md5
local   all             all                                     trust

从输出可以看到,本地 local 连接使用的是 trust 认证,理论上不需要密码即可登录。因此问题不在认证方式,而在于角色本身不允许登录。

3.3 确认角色登录属性

由于 postgres 角色无法正常登录,需要通过单用户模式(standalone backend)来检查和修改角色属性。单用户模式会绕过正常的权限检查,以超级用户身份直接操作数据目录。

4. 解决方案

4.1 停止 PostgreSQL 服务

在进入单用户模式前,必须先停止数据库服务,避免数据目录被占用:

bash 复制代码
systemctl stop postgresql-12.service

4.2 使用单用户模式修改角色属性

以 postgres 系统用户身份,使用 postgres --single 进入单用户模式:

bash 复制代码
su - postgres -c "postgres --single -D /opt/postgres/data"

进入后端交互界面后,执行以下 SQL 语句,为 postgres 角色授予登录权限:

sql 复制代码
ALTER ROLE postgres WITH LOGIN;

执行成功后,输入 Ctrl+D 退出单用户模式。

4.3 重启服务并验证

重新启动 PostgreSQL 服务:

bash 复制代码
systemctl start postgresql-12.service

再次切换用户并登录验证:

bash 复制代码
su - postgres
psql

此时应能正常进入 psql 交互界面,执行 \l 可以查看数据库列表。

5. 验证结果

修复完成后,执行 \l 可以看到如下数据库列表:

bash 复制代码
                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
 appdb     | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 enmo      | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | postgres=CTc/postgres+
           |          |          |             |             | =c/postgres
 test01    | test01   | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
(6 rows)

数据库列表正常显示,说明 postgres 角色已恢复登录权限,问题解决。

6. 总结

本文记录了一个 PostgreSQL 12 登录失败的典型案例。核心要点如下:

  • role "postgres" is not permitted to log in 错误由角色的 LOGIN 属性为 false 导致,与 pg_hba.conf 认证方式无关。
  • 当所有正常登录途径都被阻断时,可以使用 postgres --single 单用户模式绕过权限检查,直接修改系统表。
  • 进入单用户模式前必须先停止数据库服务,操作完成后及时重启服务并验证。
  • 日常运维中应避免随意修改超级用户的登录属性,以免造成服务不可用。
相关推荐
龙腾AI白云7 小时前
AI检索增强生成(RAG):解决大模型幻觉的核心落地技术
数据库·人工智能·机器学习·知识图谱
一 乐8 小时前
动漫书销售商城|基于springboot + vue动漫书销售商城(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
zzj_2626108 小时前
MySQL常用操作
数据库·mysql
其实防守也摸鱼8 小时前
Fastjson 反序列化漏洞(JNDI注入)
android·数据库·安全·oracle·自动化·fastjson·反序列化
haerapi8 小时前
把 PostgreSQL 复制巡检做成可审计闭环:确定性采集、阈值判定与受控模型归纳
数据库·postgresql
微学AI9 小时前
不让每一步都调用最贵模型:用蓝耘智能路由改造自主式研究 Agent
数据库·人工智能·蓝耘
yjb.gz9 小时前
Oracle19 RAC查看集群状态及磁盘空间情况(巡检)
数据库
钝挫力PROGRAMER10 小时前
开发踩坑记:MyBatis selectKey、空 SQL
数据库·sql·mybatis
JosieBook10 小时前
【数据库】MySQL 实战精通系列 · 第6篇:InnoDB 存储引擎、日志与崩溃恢复
数据库·mysql
杨云龙UP10 小时前
TDengine 3.4.2.8 Community 三节点三副本生产集群部署实战(DNode/MNode/taosAdapter/Explorer)
大数据·linux·运维·数据库·tdengine·时序库