pq:抱歉,已经有太多客户了
Posted
技术标签:
【中文标题】pq:抱歉,已经有太多客户了【英文标题】:pq: sorry, too many clients already 【发布时间】:2019-05-21 23:15:14 【问题描述】:当我多次调用GetMessages()
时,我收到pq: sorry, too many clients already
错误。
请查找更新后的代码:
main()
代码
func main()
dbConn, err := InitDB()
if err != nil
Log.Error("Connection Error: ", err.Error())
return
defer dbConn.Close()
go run()
var input string
fmt.Scanln(&input)
数据库连接代码为:
func InitDB()(*sql.DB, error)
connectionString := fmt.Sprintf("user=%v password='%v' dbname=%v sslmode=disable", USER, PASSWORD, DATABASE)
db, err = sql.Open(DRIVER, connectionString)
return db, err
run
goroutine:
func run()
for
messages, err := GetMessages()
if err != nil
Log.Error("Connection Error: ", err.Error())
return
log.Info(messages)
GetMessages()
功能码:
func GetMessages() (messages []string, err error)
rows, err := db.Query(`SELECT message1, message2, message3, message4, message5,
message6, message7, message8, message9, message10, message11, message12, message13,
message14, message15, message16, message17, message18, message19, message20, message21,
message22, message23, message24, message25, message26, message27, message28, message29,
message30, message31, message32, message33, message34, message35, message36, message37,
message38, message39, message40, message41, message42, message43, message44, message45,
message46, message47, message48 FROM table1 WHERE id=1`)
if err != nil
Log.Error("Query error", err)
return messages, err
var pointers []interface
defer rows.Close()
for rows.Next()
pointers = make([]interface, 48)
messages = make([]string, 48)
for i, _ := range pointers
pointers[i] = &messages[i]
err = rows.Scan(pointers...)
if err != nil
Log.Error("Failed to scan row", err)
return messages, err
return messages, nil
我检查了this 的答案,我使用了scan
,但它仍然无法正常工作
更新
问题出在另一个函数中。我在使用 db.Query
时没有关闭返回的 rows
对象,并且反复调用该函数。我已经更新了我的代码;使用db.Exec
而不是db.Query
,它现在正在工作。非常感谢@mkopriva this 的回答。 :)
【问题讨论】:
您的GetMessages
代码对我来说看起来不错。您在哪里以及执行了多少次连接代码?
...虽然与问题无关,但WHERE id=1
建议您选择单行,如果是这种情况,我建议您使用db.QueryRow
而不是db.Query
。 (play.golang.com/p/pMsuG2alB1v)
检查你的 postgres 服务器的 max_connection
设置是什么。 (click here if you don't know how) 还可以使用SELECT COUNT(*) from pg_stat_activity;
检查已经存在的连接数和/或尝试在执行您的 go 应用期间使用SELECT * FROM pg_stat_activity;
检查连接。
我想知道建立连接的完整功能是什么样的。因为你关闭了一个延迟连接,所以如果该函数返回你的连接将被关闭,但如果它没有返回,我想知道它是否可能在某个地方的循环中打开越来越多的连接
启动一次数据库连接。并使用指向所有函数的指针传递它。您正在创建许多连接,这就是您收到此警告的原因。
【参考方案1】:
尝试设置SetMaxOpenConns。默认值为 0(无限制)。这可能是导致问题的原因。如果你也有SetConnMaxLifetime 会有所帮助;否则,Postgres 将开始更长时间地保持连接,并且您会注意到内存使用量增加。
【讨论】:
【参考方案2】:我的 postgres / golang 项目也遇到了同样的问题。
最终,这个示例完美运行,没有“吃掉”任何数据库连接:
// example params
firstName := "Jeremy"
lastName := "Baker"
// setup statement
stmt, err := db.Prepare(
`INSERT INTO user (
firstname,
lastname) VALUES($1, $2)
RETURNING id`) // id is the primary key of table: user
if err != nil
return err
defer stmt.Close()
// execute statement
var userID string
err = stmt.QueryRow(
firstName,
lastName).Scan(&userID)
if err != nil
return err
【讨论】:
以上是关于pq:抱歉,已经有太多客户了的主要内容,如果未能解决你的问题,请参考以下文章
当我运行我的测试套件时,它们因 PSQLException 失败:致命:抱歉,已经有太多客户端了
Arval SQLException: FATAL: 抱歉,postgres 中已经有太多客户端