You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Golang Ping PostgreSQL?密码认证失败求助

Golang lib/pq连接PostgreSQL报密码认证失败,但命令行操作正常

问题详情

我尝试用Golang的lib/pq库连接PostgreSQL,执行db.Ping()时报错pq: password authentication failed for user "eos_user",但命令行工具(pg_isready、psql)都能正常操作数据库。

命令行正常操作示例

henry@vhost1:~/Eos$ pg_isready -h localhost -p 5432 -U eos_user -d eos_db
localhost:5432 - accepting connections
henry@vhost1:~/Eos$ sudo -u eos_user psql -d eos_db -c "SELECT * FROM logs;"
 id |         timestamp          | level |    message
----+----------------------------+-------+----------------
  1 | 2024-12-22 14:21:41.265223 | INFO  | Test log entry
  2 | 2024-12-22 14:24:09.661304 | INFO  | Test log entry
(2 rows)

henry@vhost1:~/Eos$ sudo -u eos_user psql -d eos_db -c "INSERT INTO logs (level, message) VALUES ('INFO', 'Test log entry');"
INSERT 0 1

Golang测试代码

package main

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/lib/pq"
)

func main() {
	host := "localhost"
	port := "5432"
	user := "eos_user"
	dbname := "eos_db"

	connStr := fmt.Sprintf("host=%s port=%s user=%s dbname=%s sslmode=disable", host, port, user, dbname)

	db, err := sql.Open("postgres", connStr)
	if err != nil {
		log.Fatalf("Failed to open database connection: %v", err)
	}
	defer db.Close()

	if err := db.Ping(); err != nil {
		log.Fatalf("Database is not ready: %v", err)
	}

	fmt.Println("Database is ready!")
}

代码执行报错

henry@vhost1:~/Eos$ sudo -u eos_user go run testDbPing.go
2024/12/22 17:05:09 Database is not ready: pq: password authentication failed for user "eos_user"
exit status 1

问题根源

命令行的psql未指定-h localhost时,默认使用Unix域套接字连接PostgreSQL,此时pg_hba.conf中对本地套接字的认证规则为peer(基于操作系统用户匹配),无需密码即可登录。

而Golang代码中指定了host=localhost,会触发TCP/IP连接,此时pg_hba.conf中对localhost的认证规则通常为md5或scram-sha-256(需要密码验证),但连接字符串未提供密码,因此触发认证失败。

解决方法

方法1:改用Unix域套接字连接

修改连接字符串,移除host和port参数,让lib/pq使用Unix域套接字连接(默认路径为/var/run/postgresql/.s.PGSQL.5432):

connStr := fmt.Sprintf("user=%s dbname=%s sslmode=disable", user, dbname)

若套接字路径非默认,可明确指定:

connStr := fmt.Sprintf("user=%s dbname=%s host=/var/run/postgresql sslmode=disable", user, dbname)

方法2:修改pg_hba.conf允许TCP连接使用peer认证

编辑PostgreSQL的pg_hba.conf文件(通常路径为/etc/postgresql/<版本号>/main/pg_hba.conf),找到IPv4本地连接规则:

# IPv4 local connections:
host    all             all             127.0.0.1/32            scram-sha-256

将认证方式改为peer:

# IPv4 local connections:
host    all             all             127.0.0.1/32            peer

修改后重启PostgreSQL服务:

sudo systemctl restart postgresql

方法3:添加密码到连接字符串

若需保留TCP连接,先给eos_user设置数据库密码,再在连接字符串中添加password参数:

connStr := fmt.Sprintf("host=%s port=%s user=%s dbname=%s password=你的数据库密码 sslmode=disable", host, port, user, dbname)

验证建议

优先尝试方法1,无需修改PostgreSQL配置,直接让Go代码与命令行使用相同的连接方式,最快解决问题。

内容的提问来源于stack exchange,提问作者chickenj0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 10:59:56