【问题标题】:How to kill running queries on connection close如何在连接关闭时终止正在运行的查询
【发布时间】:2021-05-05 15:28:29
【问题描述】:

我们在后端使用https://github.com/go-gorm/gorm/ ORM,并使用脚本连接到我们的 PostgreSQL 数据库。

有时,当脚本正在运行时,我们通过在本地按 Ctrl + C 或在生产中终止 pod/进程来手动终止作业。我们在所有脚本中都有一个defer DB.Close(),我还添加了处理 SIGINT / SIGTERM 信号以在 kill 时执行 DB.Close()

问题是即使在关闭连接之后,任何已经运行的现有查询都不会被杀死并继续消耗数据库资源。有没有办法在直接从 gorm 或通过其他 hack 退出之前终止由该连接池启动的任何查询。

想过使用pg_backend_pid() 并使用pg_stat_activity 杀死查询,但是我们在运行新的pg_backend_pid() 时得到的pid 与运行的不一样。

版本jinzhu/gorm v1.9.2

【问题讨论】:

  • 这就是context.Context 的用途。你读过这个吗?
  • 参见文档的this section
  • 同时处理 SO 停止信号。例如,如本文所述here
  • 感谢@Flimzy @Matteo。 db.WithContextgorm 文档中提到的方法似乎不可用。我们目前在 v1 jinzhu/gorm v1.9.2。如果有任何我可以查看的示例,那将非常有帮助。同时也会阅读上下文。

标签: go go-gorm


【解决方案1】:

您可以 use BeginTx(ctx context.Context, opts *sql.TxOptions) 将上下文作为参数。

下面是一个小例子:


import (
    "context"
    "fmt"
    "os"
    "os/signal"

    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/postgres"
)

func main() {
    db, err := gorm.Open("postgres", "host=localhost port=5432 user=gorm dbname=gorm password=mypassword sslmode=disable")
    if err != nil {
        panic(err)
    }
    defer db.Close()
    ctx := context.Background()

    ctx, cancel := context.WithCancel(ctx)
    c := make(chan os.Signal, 1)
    signal.Notify(c, os.Interrupt)
    defer func() {
        signal.Stop(c)
        cancel()
    }()
    go func() {
        select {
        case <-c:
            cancel()
        case <-ctx.Done():
        }
    }()

    transaction, err := db.DB().BeginTx(ctx, nil)
    _, err = transaction.Exec("SELECT pg_sleep(100)")
    if err != nil {
        fmt.Println(err.Error())
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-12
    • 2022-01-11
    • 1970-01-01
    • 2021-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-12
    相关资源
    最近更新 更多