DEBUG.WIKI
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
雨云;给项目一台云服务器
RackNerd;$21.99/年 · 1GB KVM

psql 连接时报与用户名同名的数据库不存在

裸 psql 默认连接与数据库用户名同名的库,该库不存在时会报 FATAL。明确数据库参数,核对 socket、角色与实际实例,避免为消除错误误建空库。

在 macOS 或 Linux 终端直接输入 psql,连接没有进入交互提示符,而是返回下面的错误。这里以本机用户名 dev 为例:

psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed:
FATAL: database "dev" does not exist

这条信息说明已经有服务器接收了连接请求,但该实例里没有请求指定的数据库。它不等于 PostgreSQL 没有安装,也不能证明连接到了你想用的实例。尤其是机器上同时有 Homebrew、容器或多个版本的 PostgreSQL 时,先确认连接目标,再决定是否需要建库。

本文处理的是省略数据库参数后,客户端选中了与用户名同名的数据库。PostgreSQL 14 和当前版本的 psql 都有这套默认规则;Homebrew 安装并不是触发条件。明确指定的业务库确实丢失、恢复未完成等情况,需要按实际数据库状态处理。

默认数据库名从哪里来

在没有命令参数、连接服务或环境变量覆盖时,psql 先用运行它的操作系统用户名作为数据库用户名,再用这个数据库用户名作为数据库名。以 dev 用户运行裸命令,就可能同时请求角色 dev 和数据库 dev。

数据库角色和数据库是两种对象。角色存在,不代表有一个同名数据库;psql -U app_user 也只指定登录角色,省略数据库名时仍可能尝试连接 app_user 数据库。

因此,不能把裸 psql 理解为固定连接本机的 postgres 库、使用 postgres 角色。Unix 系统省略主机时通常走本地 Unix socket,具体 socket 目录和默认端口还受构建及连接配置影响。

先确认当前使用的客户端和连接配置。下面只读取指定的变量,不输出密码变量:

id -un
command -v psql
psql --version
printenv PGDATABASE PGUSER PGHOST PGPORT PGSERVICE PGSERVICEFILE

psql --version 显示的是客户端版本。printenv 对未设置的变量不输出值,并可能返回非零退出码,这本身不表示 PostgreSQL 故障。如果设置了 PGSERVICE,还要在本机检查对应服务定义里的数据库、用户和主机;不要把包含凭据的配置全文贴到公开渠道。命令别名、脚本包装和连接字符串也可能明确指定数据库,不能仅凭错误中的名字与系统用户名相同就确定走了默认值。

先明确连接一个已存在的数据库

对于原来直接运行 psql 的本机环境,如果已知同一实例里有 postgres 库,且当前角色有连接权限,可以先只补数据库参数:

psql -X -d postgres

这样保持其余连接选择不变,便于判断失败是否来自默认数据库名。-X 跳过系统和用户的 psql 启动文件,减少自动执行的客户端配置对检查的影响;它不会清空连接环境变量,也不会绕过数据库权限。

如果能够进入交互界面,说明这组主机、端口和角色参数可以连接 postgres。这还不代表业务库已经存在或业务配置正确。也有实例删除了 postgres 库,或者限制了角色连接它,此时应由管理员提供一个允许连接的现有数据库,不能把该命令当成通用入口。

需要明确 socket 路径时,可以按实际环境写成下面这样。示例中 /tmp 和 5432 对应开头的报错,app_user 与 app_db 分别替换为真实角色和已有目标库:

psql -X -h /tmp -p 5432 -U app_user -d app_db

如果本来就通过 TCP 连接,应沿用实际主机、端口及既有 TLS 参数。不要为了消除报错,顺手把 socket 换成 localhost:连接方式改变后,匹配的认证规则也可能改变,反而增加一个新变量。

进入后核对数据库与连接目标

在 psql 提示符中执行:

\conninfo
\l
SELECT current_database(), session_user;

\conninfo 显示当前连接信息,\l 列出数据库,查询则确认当前数据库与会话登录角色。对照应用配置核实这些结果:库名拼写、实例地址和端口都应一致。查看列表不代表对每个库都有连接权限。

如果列表里有目标业务库,用明确的 -d 参数重新连接它,并再次确认上述信息。若列表里没有预期的库,先确认是不是连错实例;本机另一个 PostgreSQL 服务正常响应,也会让连接看起来“已经修好”。

如果错误变成 role ... does not exist、密码认证失败或权限拒绝,按新的报错检查角色与授权。此时继续修改数据库名,或放宽认证规则,并不能解决对应的问题。

把修正留在需要它的连接里

日常使用可以保留完整连接命令,或者只给这一次进程指定默认库:

PGDATABASE=app_db psql -X

这里的 app_db 仍须换成现有数据库;其余参数继续使用当前环境。这种写法不修改当前 shell 的长期环境,执行结束后不需要撤销全局设置。脚本中使用明确的 -d app_db 更便于审查,应用则应修改它实际使用的数据库连接配置。

不必仅为让裸 psql 不报错,就新建一个与系统用户名同名的空库。确实要创建个人开发库时,再确认目标实例、创建权限、所有者和用途,按正常建库流程操作。创建空库不会恢复原有业务数据,也不会替你完成表结构迁移。

本流程中的连接与查询无需修改数据库数据。若调整了脚本或应用配置,先保存原值;回退时恢复该配置并重新确认连接目标即可。不要通过重建集群、删除数据目录或重置数据库来修正一个默认库名选择错误。