代码之家  ›  专栏  ›  技术社区  ›  dar

如何优雅地杀死过时的服务器进程postgres

  •  3
  • dar  · 技术社区  · 15 年前

    在我们的实验室中,我们的postgres 8.3数据库偶尔会从pid文件中孤立出来,我们在尝试关闭数据库时会收到以下消息:

    Error: pid file is invalid, please manually kill the stale server process postgres

    当这种情况发生时,我们立即进行 pg_dump 所以我们可以稍后恢复数据库。但是,如果我们杀了-9个孤儿 postgres 进程,然后启动它,数据库仅从上次成功关闭的数据启动。但是如果你 psql 在杀死它之前,所有的数据都是可用的,所以为什么 垃圾场 作品

    有没有办法优雅地关闭孤立的postgres进程,这样我们就不必通过pg_转储和恢复?或者,是否有一种方法可以在终止孤立进程后恢复数据库?

    3 回复  |  直到 15 年前
        1
  •  4
  •   Milen A. Radev    15 年前

    documentation 您可以发送SIGTERM或SIGQUIT。SIGTERM是首选。无论哪种方式,都不要使用SIGKILL(正如你从个人经验中所知道的)。

    编辑: pgsql-admin 邮件列表。

        2
  •  3
  •   Magnus Hagander    15 年前

    从不 使用kill-9。

    但是要回答这个直接的问题,请对进程使用常规的kill(no-9)来关闭它。如果有多个进程正在运行,请确保杀死所有postgres进程。

    每当数据库关闭时,它将始终执行自动恢复。kill-9也会发生这种情况——提交的任何数据都应该在上面。这听起来像是有两个不同的数据目录安装在彼此的顶部,或者类似的东西——至少在以前,这是NFS的一个已知问题。

        3
  •  0
  •   Dan Benamy    12 年前

    #!/bin/bash
    
    DB="YOUR_DB"
    
    # Here's a snippet to watch how long each connection to the db has been open:
    #     watch -n 1 'ps -o pid,cmd,etime -C postgres | grep $DB'
    
    # This program kills any postgres workers/connections to the specified database
    # which have been running for 2 or 3 minutes. It actually kills workers which
    # have an elapsed time including "02:" or "03:". That'll be anything running
    # for at least 2 minutes and less than 4. It'll also cover anything that
    # managed to stay around until an hour and 2 or 3 minutes, etc.
    #
    # Run this once a minute via cron and it should catch any connection open
    # between 2 and 3 minutes. You can temporarily disable it if if you need to run
    # a long connection once in a while.
    #
    # The check for "03:" is in case there's a little lag starting the cron job and
    # the timing is really bad and it never sees a worker in the 1 minute window
    # when it's got "02:".
    old=$(ps -o pid,cmd,etime -C postgres | grep "$DB" | egrep '0[23]:')
    if [ -n "$old" ]; then
        echo "Killing:"
        echo "$old"
        echo "$old" | awk '{print $1}' | xargs -I {} kill {}
    fi