报 dial tcp 127.0.0.1:5432: connect: connection refused 是因 PostgreSQL 未运行、监听地址配置错误或网络隔离;需验证服务状态、调整 listen_addresses 和 pg_hba.conf,Docker 中改用 host.docker.internal,且必须调 db.Ping() 检测连通性。

用 database/sql 连 PostgreSQL 时为什么总是报 dial tcp 127.0.0.1:5432: connect: connection refused
这通常不是 Go 代码写错了,而是数据库根本没在本地跑起来,或者监听地址不对。PostgreSQL 默认只监听 localhost,且可能被防火墙或 Docker 网络隔离。
- 先手动验证:运行
psql -U your_user -d your_db,能连上才说明服务正常 - Docker 用户注意:Go 容器里写
127.0.0.1:5432是连自己,得换成宿主机 IP(如host.docker.internal:5432)或共用网络 - 检查 PostgreSQL 配置:
postgresql.conf中listen_addresses是否包含'localhost',pg_hba.conf是否允许对应用户和地址的连接
sql.Open 不会立即建连接,那怎么确认数据库真的通了
sql.Open 只是初始化连接池配置,不校验连通性。真要测通,得调 db.Ping() 或执行一条简单查询。
- 启动时建议加一次
db.Ping(),失败就 panic 或 log.Fatal,避免后续请求才暴露问题 - 别在每次 HTTP handler 里都
Ping(),它会阻塞并消耗连接池资源 - 如果用的是
pgx(非database/sql兼容驱动),要用conn.Ping(ctx),且需传入 context
用 Scan 读数据时为什么常遇到 sql: Scan error on column index 0: unsupported Scan, storing driver.Value type into type *string
这是空值(NULL)和 Go 类型不匹配的典型错误。Go 的 string 不能直接接收 SQL 的 NULL,必须用可空类型。
- 对可能为 NULL 的字段,用
sql.NullString、sql.NullInt64等,它们带Valid字段标识是否非空 - 更现代的做法是用
pgx驱动配合自定义 struct,用指针字段(如*string),NULL 自动映射为nil - 别用
interface{}接收再类型断言——容易 panic,且无法区分零值和 NULL
Web 服务重启后数据库连接泄漏,连接数越跑越高
根本原因是没正确关闭 *sql.DB。它虽是连接池,但进程退出前应显式调用 db.Close() 释放资源。
立即学习“go语言免费学习笔记(深入)”;
- 在 main 函数退出前、或 HTTP server 关闭回调中调用
db.Close() - 别在每个 handler 里
defer db.Close()——这会把整个池关掉,后续请求全失败 - 检查连接池参数:
db.SetMaxOpenConns(20)和db.SetMaxIdleConns(10)要根据 QPS 和 DB 负载调,盲目设太高反而压垮数据库










