【问题标题】:how do I gracefully kill stale server process postgres我如何优雅地杀死过时的服务器进程 postgres
【发布时间】:2012-09-10 19:19:42
【问题描述】:

有时在我们的实验室中,我们的 postgres 8.3 数据库会从 pid 文件中分离出来,并且在尝试关闭数据库时会收到此消息:

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

发生这种情况时,我们会立即执行pg_dump,以便稍后恢复数据库。但是,如果我们只是杀死 -9 孤儿 postgres 进程然后启动它,则数据库仅使用上次成功关闭的数据启动。但是如果你在杀死它之前psql 给它,数据都是可用的,这就是为什么pg_dump 有效。

有没有办法优雅地关闭孤立的 postgres 进程,这样我们就不必通过 pg_dump 和恢复?或者有没有办法在杀死孤立进程后让数据库恢复?

【问题讨论】:

    标签: postgresql


    【解决方案1】:

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

    编辑:另一方面,您遇到的情况不正常,可能表示配置错误或错误。请通过pgsql-admin 邮件列表寻求帮助。

    【讨论】:

      【解决方案2】:

      从不使用 kill -9。

      我强烈建议您尝试弄清楚这是如何发生的。错误消息究竟来自哪里?这不是 PostgreSQL 错误消息。您是否有机会混合不同的方式来启动/停止服务器(例如,有时是 initscripts,有时是 pg_ctl)?这可能会导致事情不同步。

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

      数据库在关闭时总是会进行自动恢复。这也应该发生在 kill -9 上——任何提交的数据都应该在那里。这几乎听起来就像您将两个不同的数据目录安装在彼此之上或类似的东西 - 这至少是 NFS 的一个已知问题。

      【讨论】:

        【解决方案3】:

        我使用如下脚本由 cron 每分钟运行一次。

        #!/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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-07-28
          • 2014-10-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多