使用pqxx连接本地PostgreSQL数据库时出现broken_connection错误
解决pqxx/Shell连接PostgreSQL失败但JDBC/PGAdmin成功的问题
我之前帮好几个开发者解决过一模一样的问题——JDBC和PGAdmin能正常连PostgreSQL,但用pqxx库或者shell直接跑psql就报错,核心问题几乎都是PostgreSQL的连接认证规则在本地Unix套接字和TCP/IP连接上做了区分:
JDBC和PGAdmin默认会用TCP/IP连接本地数据库(哪怕你填的是localhost),而pqxx、未指定-h参数的shell psql会优先尝试Unix套接字连接,这两种连接方式对应的认证规则是分开配置的。
第一步:定位问题根源——检查pg_hba.conf配置
pg_hba.conf是PostgreSQL控制连接权限的核心配置文件,我们先找到它的位置:
通过PGAdmin或者JDBC连接上数据库后,执行SQL命令:
SHOW hba_file;会输出文件路径,比如
/var/lib/postgresql/14/main/pg_hba.conf打开这个文件,找到以下两类规则:
- 针对Unix套接字的
local规则(pqxx和默认psql用的就是这个):
这里的# "local" is for Unix domain socket connections only local all all peerpeer认证要求操作系统用户名和PostgreSQL用户名完全一致,如果你的shell用户不是postgres,或者运行pqxx程序的用户不是postgres,就会直接认证失败。 - 针对TCP/IP的
host规则(JDBC/PGAdmin用的是这个):
这里用的是host all all 127.0.0.1/32 md5md5密码认证,只要你输入的密码正确就能通过。
- 针对Unix套接字的
两种解决方法任选其一
方法一:强制pqxx/psql走TCP/IP连接(最简单)
直接修改连接参数,让它们和JDBC/PGAdmin用一样的连接方式:
- pqxx代码修改连接字符串,加上
host=127.0.0.1:#include <pqxx/connection.hxx> int main(){ pqxx::connection conn("user=postgres port=5432 dbname=pqxx-test password=postgres host=127.0.0.1"); return 0; } - shell的psql命令加上
-h参数:psql -h 127.0.0.1 pqxx-test
方法二:修改pg_hba.conf,让本地套接字用密码认证
如果你想保留Unix套接字连接的方式,可以修改认证规则:
- 把pg_hba.conf里的
local行的peer改成md5:local all all md5 - 重启PostgreSQL服务生效:
- Ubuntu/Debian系统:
sudo systemctl restart postgresql - CentOS/RHEL系统(以14版本为例):
sudo systemctl restart postgresql-14
- Ubuntu/Debian系统:
额外排查点(如果上面的方法没解决)
- 检查postgresql.conf里的
unix_socket_directories配置,确保它指向的目录(比如/var/run/postgresql/)存在,且运行pqxx/psql的用户有读写权限。 - 确认你的PostgreSQL服务确实在运行,没有意外停止。
内容的提问来源于stack exchange,提问作者Todde
相关产品推荐
相关产品推荐

