PostgreSQL 15 中 pg_dumpall 报角色 postgres 不存在怎么办?
结论
报错说明 pg_dumpall 正尝试以数据库角色 postgres 连接,但当前数据库集群中没有该角色。命令通过 docker exec --user postgres 使用容器内的操作系统用户 postgres 运行。未指定 -U 时,pg_dumpall 通常会让 libpq 使用当前操作系统用户名作为数据库用户名。先检查备份脚本使用的数据库连接身份,并确认集群中已有哪个角色可以执行完整备份。
即使集群中有约 150 个数据库,也不必逐个执行 GRANT CONNECT 或 ALTER DATABASE ... OWNER。这些命令不能通用地修复当前连接错误;更改数据库所有者还会影响权限和管理关系。
先检查集群中的角色
使用一个已知可连接的数据库管理员账号连接数据库,然后查看角色。例如:
psql -U <现有管理员角色> -d postgres -c '\du'
如果不清楚管理员角色是什么,先检查 Odoo 的连接配置、容器环境变量或部署配置,确认应用实际使用的数据库用户名。不要把密码直接写进命令行或脚本,按现有部署的凭据管理方式提供密码。
优先让备份使用现有管理员角色
pg_dumpall 默认使用当前系统用户名作为数据库用户名。如果现有管理员角色具备完整导出集群所需的权限,可以在备份命令中明确指定该角色:
pg_dumpall -U <现有管理员角色> --verbose 2>${LOGFILE} | gzip -c | openssl smime -encrypt \
-aes256 -binary -outform DEM \
-out ${BACKUPFILE} "${BACKUPKEY}"
此命令仍通过容器内的本地 PostgreSQL socket 连接。确认容器内的 .pgpass、环境或其他凭据配置能让该角色通过认证。修改后先单独测试连接,再运行备份脚本。
完整的 pg_dumpall 会导出集群范围的全局对象,并调用数据库导出工具处理集群中的数据库。执行完整集群备份的角色需要具备相应权限,常见做法是使用受控的超级用户账号。如果只需备份单个数据库,可以考虑使用对该数据库有读取权限的账号运行 pg_dump;这与导出整个集群不同。
是否需要重新创建 postgres 角色
如果系统确实要求保留这个备份身份,可以由现有管理员创建角色。创建前,先确认它在部署中的用途,以及如何安全管理其凭据。下面的语法会创建一个具有登录和超级用户权限的角色:
CREATE ROLE postgres WITH SUPERUSER LOGIN PASSWORD '从安全凭据管理系统提供的密码';
SUPERUSER 权限很高。只有确认该角色专用于受控备份、密码受到保护且符合运维策略时,才应授予此权限。不要只为消除报错就直接增加超级用户,也不要将示例密码原样用于生产环境。如果现有管理员角色已经能执行备份,通常不需要创建新角色。
这几条 SQL 是否适用
GRANT CONNECT ON DATABASE dbname TO postgres;
GRANT USAGE ON SCHEMA public TO postgres;
ALTER DATABASE dbname OWNER TO postgres;
这些命令无法替代缺失角色的创建,也不是修复 pg_dumpall 的标准流程:
GRANT CONNECT只授予连接指定数据库的权限,不会自动授予读取数据库中所有对象所需的权限。GRANT USAGE ON SCHEMA public只对指定数据库中的publicschema 生效,也不会覆盖其他 schema 或对象的权限。ALTER DATABASE ... OWNER会更改数据库所有者,不应仅为备份而批量执行。它既不是解决当前登录失败的必要条件,也可能改变现有权限和维护责任。
因此,不要把这些命令直接套用到 150 个数据库上。先确定备份所用的角色和目标,再根据实际权限需求处理。
关于 PostgreSQL 13 升级到 15
更换 PostgreSQL 镜像版本,不一定会在已有数据目录中自动创建 postgres 数据库角色。角色保存在数据库集群中,初始用户是否创建取决于容器初始化流程和数据目录状态。复用现有数据目录时,应检查集群中的实际角色和初始化配置,不要假设升级后的镜像会自动补上某个角色。
确认备份成功后,还应检查备份文件的退出状态、大小和恢复流程。原命令使用管道;如果 shell 未启用 pipefail,前序命令失败未必会让整条管道返回失败状态。可结合脚本现有的错误处理方式,确认备份失败时能被正确报告。
备注:内容仅供参考。
