【问题标题】:Connection leak in lib/pq postgres driverlib/pq postgres 驱动程序中的连接泄漏
【发布时间】:2020-04-14 00:57:30
【问题描述】:

鉴于db 的类型为*sql.DB(使用lib/pq 驱动程序),以下代码会导致连接泄漏:

    rows, err := db.Query(
        "select 1 from things where id = $1",
        thing,
    )
    if err != nil {
        return nil, fmt.Errorf("can't select thing (%d): %w", thing, err)
    }

    found := false

    for rows.Next() {
        found = true
        break
    }

重复调用此代码会增加打开的连接数,直到耗尽:

select sum(numbackends) from pg_stat_database;
// 5
// 6
// 7
// ...
// 80

我该如何解决?

【问题讨论】:

    标签: sql postgresql go


    【解决方案1】:

    您编写的代码存在一些问题。避免连接泄漏问题的直接答案是关闭rows 迭代器as mentioned in the documentation。调用它的正常方式是在defer 语句中:

        rows, err := db.Query(
            "select 1 from things where id = $1",
            thing,
        )
        if err != nil {
            return nil, fmt.Errorf("can't select thing (%d): %w", thing, err)
        }
        defer rows.Close()
    
        found := false
    
        for rows.Next() {
            found = true
            break
        }
    

    其次,由于您只关心单个结果,因此根本没有理由获取多行结果集,这也将隐式解决连接泄漏问题。有关在 Postgres 中检查存在的最快方法的讨论,请参阅 this post。如果我们在这里调整:

        row, err := db.QueryRow(
            "select EXISTS(SELECT 1 from things where id = $1)",
            thing,
        )
        if err != nil {
            return nil, fmt.Errorf("can't select thing (%d): %w", thing, err)
        }
        var found bool
        if err := row.Scan(&found); err != nil {
            return nil, fmt.Errorf("Failed to scan result: %w", err)
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-06
      • 2012-11-25
      • 2013-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多