杀死-9 postgres 进程

杀死-9 postgres 进程

我们的数据库服务器上的 postgres SELECT 查询失控,开始消耗大量内存和交换,直到服务器内存耗尽。我通过 找到特定进程ps aux | grep postgres并运行kill -9 pid。这会终止进程,内存按预期释放。系统的其余部分和 postgres 查询似乎不受影响。此服务器在 SLES 9 SP4 上运行 postgres 9.1.3。

然而,我们的一位开发人员因为我使用 终止了 postgres 进程而责骂我kill -9,说这会破坏整个 postgres 服务。实际上,并没有。我以前做过几次,没有看到任何负面影响。

话虽如此,经过进一步阅读,看起来kill pid不使用标志是终止失控的 postgres 进程的首选方法,但根据 postgres 社区的其他用户的说法,听起来 postgres 多年来已经“变得更好了”,以至于kill -9单个查询进程/线程不再是死刑。

有人能告诉我如何正确终止失控的 Postgres 进程,以及kill -9现在使用 Postgres 会带来多大的灾难性(或良性)吗?谢谢你的见解。

答案1

voretaq7回答涵盖关键点,包括终止后端的正确方法但我想补充一点解释。

kill -9(即SIGKILL)永远、永远、永远不应该成为你的首选默认。当进程不响应其正常关闭请求并且SIGTERM( kill -15) 无效时,这应该是您的最后手段。对于 Pg 和几乎所有其他事物来说都是如此。

kill -9使被终止的进程根本没有机会进行任何清理。

对于 PostgreSQL 来说,Pg 认为被终止的支持kill -9是支持崩溃。它知道后端可能已经损坏了共享内存 - 因为你可能在将页面写入 shm 或修改页面的过程中中断了它 - 因此它终止并重新启动所有其他后端当它注意到后端突然消失并以非零错误代码退出时。

您会在日志中看到此报告。

如果看起来没有造成任何损害,那是因为 Pg 在崩溃后重新启动了一切,并且您的应用程序正在从丢失的连接中干净地恢复。这并不是一个好主意。如果没有其他问题,后端崩溃的测试不如 Pg 正常运行的部分那么好,而且更加复杂/多样,因此后端崩溃处理和恢复中潜伏错误的可能性更高。

顺便说一句,如果你是kill -9邮政局长,然后删除postmaster.pid并重新启动它,而没有确保每个postgres后端都消失了,可能会发生非常糟糕的事情。如果您意外地杀死了 postmaster 而不是后端,发现数据库已关闭,尝试重新启动它,在重新启动失败时删除了“过时的” .pid 文件,然后尝试再次重新启动它,则很容易发生这种情况。这是您应该避免使用kill -9Pg 并且不应删除的原因之一postmaster.pid

演示:

要确切了解后端发生的情况kill -9,请尝试以下简单步骤。打开两个终端,在每个终端中打开 psql,在每个终端中运行SELECT pg_backend_pid();。在另一个终端中kill -9运行其中一个 PID。现在SELECT pg_backend_pid();再次在两个 psql 会话中运行。注意它们如何两个都失去了联系?

第 1 节,我们已终止:

$ psql regress
psql (9.1.4)
Type "help" for help.

regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6357
(1 row)

[kill -9 of session one happens at this point]

regress=# select pg_backend_pid();
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6463
(1 row)

第 2 场,是附带损害:

$ psql regress
psql (9.1.4)
Type "help" for help.

regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6283
(1 row)

[kill -9 of session one happens at this point]

regress=# select pg_backend_pid();
WARNING:  terminating connection because of crash of another server process
DETAIL:  The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
HINT:  In a moment you should be able to reconnect to the database and repeat your command.
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6464
(1 row)

怎么看两个都会话中断了?这就是您没有kill -9后端的原因。

答案2

I found the particular process via ps aux | grep postgres and ran kill -9 pid.
不!糟糕!远离后端!

说真的 - 不要以那种方式杀死 Postgres 后端 - 可能会发生可怕的事情(即使自 7.x 时代以来已经进行了所有的稳定性增强),这可能会破坏你的整个数据库,而你的开发人员有权责骂你这样做。

事实上,在 Postgres 内部实现此目的的一种受人尊敬和认可的方法—— 甚至在Postgres 手册尽管那篇 SO 帖子对此进行了更好的解释......

SELECT pg_cancel_backend(pid)
向指定后端发送取消(SIGINT)信号,取消当前正在运行的查询。

select pg_terminate_backend(pid)
向指定的后端发送终止(SIGTERM)信号,以取消查询并中止后端(断开其连接)。

pg_stat_activity后端 ID 可以从表 (或ps)中获取

答案3

杀死 PostgreSQL 客户端进程应该没问题。杀死 PostgreSQL 守护进程可能会让你挨骂。

由于 SQL 守护进程也具有内部进程控制,因此首选方法是先尝试使用该通道。

停止在 PostgreSQL 中(长时间)运行的 SQL 查询...来自 StackOverflow。

相关内容